Merge "Determine whether to support activities in multi window (5/n)" into sc-dev

This commit is contained in:
Chris Li
2021-05-12 22:37:41 +00:00
committed by Android (Google) Code Review
23 changed files with 300 additions and 197 deletions

View File

@@ -18,7 +18,6 @@ package com.android.wm.shell.flicker.apppairs
import android.os.SystemClock
import android.platform.test.annotations.Presubmit
import android.provider.Settings
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -27,6 +26,8 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.wm.shell.flicker.appPairsDividerIsInvisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
import org.junit.After
import org.junit.Before
import org.junit.FixMethodOrder
@@ -49,7 +50,6 @@ import org.junit.runners.Parameterized
class AppPairsTestCannotPairNonResizeableApps(
testSpec: FlickerTestParameter
) : AppPairsTransition(testSpec) {
var prevSupportNonResizableInMultiWindow = 0
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = {
@@ -64,21 +64,15 @@ class AppPairsTestCannotPairNonResizeableApps(
}
@Before
fun setup() {
prevSupportNonResizableInMultiWindow = Settings.Global.getInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)
if (prevSupportNonResizableInMultiWindow == 1) {
// Not support non-resizable in multi window
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 0)
}
override fun setup() {
super.setup()
setSupportsNonResizableMultiWindow(instrumentation, -1)
}
@After
fun teardown() {
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
prevSupportNonResizableInMultiWindow)
override fun teardown() {
super.teardown()
resetMultiWindowConfig(instrumentation)
}
@FlakyTest

View File

@@ -18,7 +18,6 @@ package com.android.wm.shell.flicker.apppairs
import android.os.SystemClock
import android.platform.test.annotations.Presubmit
import android.provider.Settings
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -27,6 +26,8 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.wm.shell.flicker.appPairsDividerIsVisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
import org.junit.After
import org.junit.Before
import org.junit.FixMethodOrder
@@ -49,7 +50,6 @@ import org.junit.runners.Parameterized
class AppPairsTestSupportPairNonResizeableApps(
testSpec: FlickerTestParameter
) : AppPairsTransition(testSpec) {
var prevSupportNonResizableInMultiWindow = 0
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = {
@@ -64,21 +64,15 @@ class AppPairsTestSupportPairNonResizeableApps(
}
@Before
fun setup() {
prevSupportNonResizableInMultiWindow = Settings.Global.getInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)
if (prevSupportNonResizableInMultiWindow == 0) {
// Support non-resizable in multi window
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 1)
}
override fun setup() {
super.setup()
setSupportsNonResizableMultiWindow(instrumentation, 1)
}
@After
fun teardown() {
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
prevSupportNonResizableInMultiWindow)
override fun teardown() {
super.teardown()
resetMultiWindowConfig(instrumentation)
}
@FlakyTest

View File

@@ -20,11 +20,9 @@ import android.app.Instrumentation
import android.content.Context
import android.platform.test.annotations.Presubmit
import android.system.helpers.ActivityHelper
import android.util.Log
import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.compatibility.common.util.SystemUtil
import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
@@ -41,10 +39,14 @@ import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import com.android.wm.shell.flicker.helpers.BaseAppHelper
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.getDevEnableNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setDevEnableNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import com.android.wm.shell.flicker.testapp.Components
import org.junit.After
import org.junit.Before
import org.junit.Test
import java.io.IOException
abstract class AppPairsTransition(protected val testSpec: FlickerTestParameter) {
protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
@@ -62,6 +64,21 @@ abstract class AppPairsTransition(protected val testSpec: FlickerTestParameter)
protected var primaryTaskId = ""
protected var secondaryTaskId = ""
protected var nonResizeableTaskId = ""
private var prevDevEnableNonResizableMultiWindow = 0
@Before
open fun setup() {
prevDevEnableNonResizableMultiWindow = getDevEnableNonResizableMultiWindow(context)
if (prevDevEnableNonResizableMultiWindow != 0) {
// Turn off the development option
setDevEnableNonResizableMultiWindow(context, 0)
}
}
@After
open fun teardown() {
setDevEnableNonResizableMultiWindow(context, prevDevEnableNonResizableMultiWindow)
}
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
@@ -117,11 +134,7 @@ abstract class AppPairsTransition(protected val testSpec: FlickerTestParameter)
}
internal fun executeShellCommand(cmd: String) {
try {
SystemUtil.runShellCommand(instrumentation, cmd)
} catch (e: IOException) {
Log.d("AppPairsTest", "executeShellCommand error! $e")
}
BaseAppHelper.executeShellCommand(instrumentation, cmd)
}
internal fun composePairsCommand(

View File

@@ -21,11 +21,14 @@ import android.content.ComponentName
import android.content.pm.PackageManager.FEATURE_LEANBACK
import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY
import android.support.test.launcherhelper.LauncherStrategyFactory
import android.util.Log
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiObject2
import androidx.test.uiautomator.Until
import com.android.compatibility.common.util.SystemUtil
import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.traces.parser.toWindowName
import java.io.IOException
abstract class BaseAppHelper(
instrumentation: Instrumentation,
@@ -56,5 +59,13 @@ abstract class BaseAppHelper(
companion object {
private const val APP_CLOSE_WAIT_TIME_MS = 3_000L
fun executeShellCommand(instrumentation: Instrumentation, cmd: String) {
try {
SystemUtil.runShellCommand(instrumentation, cmd)
} catch (e: IOException) {
Log.e("BaseAppHelper", "executeShellCommand error! $e")
}
}
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
import android.content.ComponentName
import android.content.Context
import android.provider.Settings
class MultiWindowHelper(
instrumentation: Instrumentation,
activityLabel: String,
componentsInfo: ComponentName
) : BaseAppHelper(instrumentation, activityLabel, componentsInfo) {
companion object {
fun getDevEnableNonResizableMultiWindow(context: Context): Int =
Settings.Global.getInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)
fun setDevEnableNonResizableMultiWindow(context: Context, configValue: Int) =
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, configValue)
fun setSupportsNonResizableMultiWindow(instrumentation: Instrumentation, configValue: Int) =
executeShellCommand(
instrumentation,
createConfigSupportsNonResizableMultiWindowCommand(configValue))
fun resetMultiWindowConfig(instrumentation: Instrumentation) =
executeShellCommand(instrumentation, resetMultiWindowConfigCommand)
private fun createConfigSupportsNonResizableMultiWindowCommand(configValue: Int): String =
"wm set-multi-window-config --supportsNonResizable $configValue"
private const val resetMultiWindowConfigCommand: String = "wm reset-multi-window-config"
}
}

View File

@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.legacysplitscreen
import android.platform.test.annotations.Presubmit
import android.provider.Settings
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -27,6 +26,8 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.canSplitScreen
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import org.junit.After
import org.junit.Assert
@@ -51,7 +52,6 @@ import org.junit.runners.Parameterized
class EnterSplitScreenNotSupportNonResizable(
testSpec: FlickerTestParameter
) : LegacySplitScreenTransition(testSpec) {
var prevSupportNonResizableInMultiWindow = 0
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = { configuration ->
@@ -76,21 +76,15 @@ class EnterSplitScreenNotSupportNonResizable(
splitScreenApp.defaultWindowName)
@Before
fun setup() {
prevSupportNonResizableInMultiWindow = Settings.Global.getInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)
if (prevSupportNonResizableInMultiWindow == 1) {
// Not support non-resizable in multi window
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 0)
}
override fun setup() {
super.setup()
setSupportsNonResizableMultiWindow(instrumentation, -1)
}
@After
fun teardown() {
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
prevSupportNonResizableInMultiWindow)
override fun teardown() {
super.teardown()
resetMultiWindowConfig(instrumentation)
}
@Presubmit

View File

@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.legacysplitscreen
import android.platform.test.annotations.Presubmit
import android.provider.Settings
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -27,6 +26,8 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.launchSplitScreen
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.dockedStackDividerIsVisible
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import org.junit.After
import org.junit.Before
@@ -50,7 +51,6 @@ import org.junit.runners.Parameterized
class EnterSplitScreenSupportNonResizable(
testSpec: FlickerTestParameter
) : LegacySplitScreenTransition(testSpec) {
var prevSupportNonResizableInMultiWindow = 0
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = { configuration ->
@@ -73,21 +73,15 @@ class EnterSplitScreenSupportNonResizable(
splitScreenApp.defaultWindowName)
@Before
fun setup() {
prevSupportNonResizableInMultiWindow = Settings.Global.getInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)
if (prevSupportNonResizableInMultiWindow != 1) {
// Support non-resizable in multi window
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 1)
}
override fun setup() {
super.setup()
setSupportsNonResizableMultiWindow(instrumentation, 1)
}
@After
fun teardown() {
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
prevSupportNonResizableInMultiWindow)
override fun teardown() {
super.teardown()
resetMultiWindowConfig(instrumentation)
}
@Presubmit

View File

@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.legacysplitscreen
import android.platform.test.annotations.Presubmit
import android.provider.Settings
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -32,6 +31,8 @@ import com.android.server.wm.flicker.layerBecomesVisible
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER
import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import org.junit.After
import org.junit.Before
@@ -53,7 +54,6 @@ import org.junit.runners.Parameterized
class LegacySplitScreenFromIntentNotSupportNonResizable(
testSpec: FlickerTestParameter
) : LegacySplitScreenTransition(testSpec) {
var prevSupportNonResizableInMultiWindow = 0
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = { configuration ->
@@ -77,21 +77,15 @@ class LegacySplitScreenFromIntentNotSupportNonResizable(
WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME)
@Before
fun setup() {
prevSupportNonResizableInMultiWindow = Settings.Global.getInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)
if (prevSupportNonResizableInMultiWindow == 1) {
// Not support non-resizable in multi window
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 0)
}
override fun setup() {
super.setup()
setSupportsNonResizableMultiWindow(instrumentation, -1)
}
@After
fun teardown() {
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
prevSupportNonResizableInMultiWindow)
override fun teardown() {
super.teardown()
resetMultiWindowConfig(instrumentation)
}
@Presubmit

View File

@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.legacysplitscreen
import android.platform.test.annotations.Presubmit
import android.provider.Settings
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -30,6 +29,8 @@ import com.android.server.wm.flicker.layerBecomesVisible
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER
import com.android.wm.shell.flicker.dockedStackDividerIsVisible
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import org.junit.After
import org.junit.Before
@@ -51,7 +52,6 @@ import org.junit.runners.Parameterized
class LegacySplitScreenFromIntentSupportNonResizable(
testSpec: FlickerTestParameter
) : LegacySplitScreenTransition(testSpec) {
var prevSupportNonResizableInMultiWindow = 0
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = { configuration ->
@@ -75,21 +75,15 @@ class LegacySplitScreenFromIntentSupportNonResizable(
WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME)
@Before
fun setup() {
prevSupportNonResizableInMultiWindow = Settings.Global.getInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)
if (prevSupportNonResizableInMultiWindow == 0) {
// Support non-resizable in multi window
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 1)
}
override fun setup() {
super.setup()
setSupportsNonResizableMultiWindow(instrumentation, 1)
}
@After
fun teardown() {
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
prevSupportNonResizableInMultiWindow)
override fun teardown() {
super.teardown()
resetMultiWindowConfig(instrumentation)
}
@Presubmit

View File

@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.legacysplitscreen
import android.platform.test.annotations.Presubmit
import android.provider.Settings
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -33,6 +32,8 @@ import com.android.server.wm.flicker.layerBecomesVisible
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER
import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import org.junit.After
import org.junit.Before
@@ -54,7 +55,6 @@ import org.junit.runners.Parameterized
class LegacySplitScreenFromRecentNotSupportNonResizable(
testSpec: FlickerTestParameter
) : LegacySplitScreenTransition(testSpec) {
var prevSupportNonResizableInMultiWindow = 0
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = { configuration ->
@@ -78,21 +78,15 @@ class LegacySplitScreenFromRecentNotSupportNonResizable(
WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME)
@Before
fun setup() {
prevSupportNonResizableInMultiWindow = Settings.Global.getInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)
if (prevSupportNonResizableInMultiWindow == 1) {
// Not support non-resizable in multi window
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 0)
}
override fun setup() {
super.setup()
setSupportsNonResizableMultiWindow(instrumentation, -1)
}
@After
fun teardown() {
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
prevSupportNonResizableInMultiWindow)
override fun teardown() {
super.teardown()
resetMultiWindowConfig(instrumentation)
}
@Presubmit

View File

@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.legacysplitscreen
import android.platform.test.annotations.Presubmit
import android.provider.Settings
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -31,6 +30,8 @@ import com.android.server.wm.flicker.layerBecomesVisible
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER
import com.android.wm.shell.flicker.dockedStackDividerIsVisible
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import org.junit.After
import org.junit.Before
@@ -52,7 +53,6 @@ import org.junit.runners.Parameterized
class LegacySplitScreenFromRecentSupportNonResizable(
testSpec: FlickerTestParameter
) : LegacySplitScreenTransition(testSpec) {
var prevSupportNonResizableInMultiWindow = 0
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = { configuration ->
@@ -76,21 +76,15 @@ class LegacySplitScreenFromRecentSupportNonResizable(
WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME)
@Before
fun setup() {
prevSupportNonResizableInMultiWindow = Settings.Global.getInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)
if (prevSupportNonResizableInMultiWindow == 0) {
// Support non-resizable in multi window
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 1)
}
override fun setup() {
super.setup()
setSupportsNonResizableMultiWindow(instrumentation, 1)
}
@After
fun teardown() {
Settings.Global.putInt(context.contentResolver,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
prevSupportNonResizableInMultiWindow)
override fun teardown() {
super.teardown()
resetMultiWindowConfig(instrumentation)
}
@Presubmit

View File

@@ -32,7 +32,11 @@ import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.repetitions
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.getDevEnableNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setDevEnableNonResizableMultiWindow
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import org.junit.After
import org.junit.Before
import org.junit.Test
abstract class LegacySplitScreenTransition(protected val testSpec: FlickerTestParameter) {
@@ -44,6 +48,21 @@ abstract class LegacySplitScreenTransition(protected val testSpec: FlickerTestPa
protected val nonResizeableApp = SplitScreenHelper.getNonResizeable(instrumentation)
protected val LAUNCHER_PACKAGE_NAME = LauncherStrategyFactory.getInstance(instrumentation)
.launcherStrategy.supportedLauncherPackage
private var prevDevEnableNonResizableMultiWindow = 0
@Before
open fun setup() {
prevDevEnableNonResizableMultiWindow = getDevEnableNonResizableMultiWindow(context)
if (prevDevEnableNonResizableMultiWindow != 0) {
// Turn off the development option
setDevEnableNonResizableMultiWindow(context, 0)
}
}
@After
open fun teardown() {
setDevEnableNonResizableMultiWindow(context, prevDevEnableNonResizableMultiWindow)
}
/**
* List of windows that are ignored when verifying that visible elements appear on 2

View File

@@ -2483,39 +2483,52 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
/**
* @return whether this activity supports split-screen multi-window and can be put in the docked
* root task.
* @return whether this activity supports split-screen multi-window and can be put in
* split-screen.
*/
@Override
public boolean supportsSplitScreenWindowingMode() {
// An activity can not be docked even if it is considered resizeable because it only
// supports picture-in-picture mode but has a non-resizeable resizeMode
return supportsSplitScreenWindowingModeInDisplayArea(getDisplayArea());
}
/**
* @return whether this activity supports split-screen multi-window and can be put in
* split-screen if it is in the given {@link TaskDisplayArea}.
*/
boolean supportsSplitScreenWindowingModeInDisplayArea(@Nullable TaskDisplayArea tda) {
return super.supportsSplitScreenWindowingMode()
&& mAtmService.mSupportsSplitScreenMultiWindow && supportsMultiWindow();
&& mAtmService.mSupportsSplitScreenMultiWindow
&& supportsMultiWindowInDisplayArea(tda);
}
boolean supportsFreeform() {
return supportsFreeformInDisplayArea(getDisplayArea());
}
/**
* @return whether this activity supports freeform multi-window and can be put in the freeform
* root task.
* windowing mode if it is in the given {@link TaskDisplayArea}.
*/
boolean supportsFreeform() {
return mAtmService.mSupportsFreeformWindowManagement && supportsMultiWindow();
boolean supportsFreeformInDisplayArea(@Nullable TaskDisplayArea tda) {
return mAtmService.mSupportsFreeformWindowManagement
&& supportsMultiWindowInDisplayArea(tda);
}
boolean supportsMultiWindow() {
return supportsMultiWindowInDisplayArea(getDisplayArea());
}
/**
* @return whether this activity supports multi-window.
* @return whether this activity supports multi-window if it is in the given
* {@link TaskDisplayArea}.
*/
boolean supportsMultiWindow() {
return mAtmService.mSupportsMultiWindow && !isActivityTypeHome()
&& (isResizeable() || mAtmService.mDevEnableNonResizableMultiWindow);
}
// TODO(b/176061101) replace supportsMultiWindow() after fixing tests.
boolean supportsMultiWindow2() {
boolean supportsMultiWindowInDisplayArea(@Nullable TaskDisplayArea tda) {
if (isActivityTypeHome()) {
return false;
}
if (!mAtmService.mSupportsMultiWindow) {
return false;
}
final TaskDisplayArea tda = getDisplayArea();
if (tda == null) {
return false;
}

View File

@@ -1684,7 +1684,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// Leave the task in its current root task or a fullscreen root task if it isn't
// resizeable and the preferred root task is in multi-window mode.
if (inMultiWindowMode && !task.supportsMultiWindow()) {
if (inMultiWindowMode
&& !task.supportsMultiWindowInDisplayArea(rootTask.getDisplayArea())) {
Slog.w(TAG, "Can not move unresizeable task=" + task + " to multi-window root task="
+ rootTask + " Moving to a fullscreen root task instead.");
if (prevRootTask != null) {

View File

@@ -3046,7 +3046,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// There is a 1-to-1 relationship between root task and task when not in
// primary split-windowing mode.
if (task.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
&& r.supportsSplitScreenWindowingMode()
&& r.supportsSplitScreenWindowingModeInDisplayArea(task.getDisplayArea())
&& (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
|| windowingMode == WINDOWING_MODE_UNDEFINED)) {
return true;

View File

@@ -1977,32 +1977,46 @@ class Task extends WindowContainer<WindowContainer> {
@Override
public boolean supportsSplitScreenWindowingMode() {
final Task topTask = getTopMostTask();
return super.supportsSplitScreenWindowingMode()
&& (topTask == null || topTask.supportsSplitScreenWindowingModeInner());
return supportsSplitScreenWindowingModeInDisplayArea(getDisplayArea());
}
private boolean supportsSplitScreenWindowingModeInner() {
boolean supportsSplitScreenWindowingModeInDisplayArea(@Nullable TaskDisplayArea tda) {
final Task topTask = getTopMostTask();
return super.supportsSplitScreenWindowingMode()
&& (topTask == null || topTask.supportsSplitScreenWindowingModeInner(tda));
}
private boolean supportsSplitScreenWindowingModeInner(@Nullable TaskDisplayArea tda) {
return super.supportsSplitScreenWindowingMode()
&& mAtmService.mSupportsSplitScreenMultiWindow
&& supportsMultiWindow();
&& supportsMultiWindowInDisplayArea(tda);
}
boolean supportsFreeform() {
return mAtmService.mSupportsFreeformWindowManagement && supportsMultiWindow();
return supportsFreeformInDisplayArea(getDisplayArea());
}
/**
* @return whether this task supports freeform multi-window if it is in the given
* {@link TaskDisplayArea}.
*/
boolean supportsFreeformInDisplayArea(@Nullable TaskDisplayArea tda) {
return mAtmService.mSupportsFreeformWindowManagement
&& supportsMultiWindowInDisplayArea(tda);
}
boolean supportsMultiWindow() {
return mAtmService.mSupportsMultiWindow
&& (isResizeable() || mAtmService.mDevEnableNonResizableMultiWindow);
return supportsMultiWindowInDisplayArea(getDisplayArea());
}
// TODO(b/176061101) replace supportsMultiWindow() after fixing tests.
boolean supportsMultiWindow2() {
/**
* @return whether this task supports multi-window if it is in the given
* {@link TaskDisplayArea}.
*/
boolean supportsMultiWindowInDisplayArea(@Nullable TaskDisplayArea tda) {
if (!mAtmService.mSupportsMultiWindow) {
return false;
}
final TaskDisplayArea tda = getDisplayArea();
if (tda == null) {
return false;
}

View File

@@ -1614,18 +1614,18 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
boolean supportsPip = mAtmService.mSupportsPictureInPicture;
if (supportsMultiWindow) {
if (task != null) {
supportsSplitScreen = task.supportsSplitScreenWindowingMode();
supportsFreeform = task.supportsFreeform();
supportsMultiWindow = task.supportsMultiWindow()
supportsSplitScreen = task.supportsSplitScreenWindowingModeInDisplayArea(this);
supportsFreeform = task.supportsFreeformInDisplayArea(this);
supportsMultiWindow = task.supportsMultiWindowInDisplayArea(this)
// When the activity needs to be moved to PIP while the Task is not in PIP,
// it can be moved to a new created PIP Task, so WINDOWING_MODE_PINNED is
// always valid for Task as long as the device supports it.
|| (windowingMode == WINDOWING_MODE_PINNED && supportsPip);
} else if (r != null) {
supportsSplitScreen = r.supportsSplitScreenWindowingMode();
supportsFreeform = r.supportsFreeform();
supportsSplitScreen = r.supportsSplitScreenWindowingModeInDisplayArea(this);
supportsFreeform = r.supportsFreeformInDisplayArea(this);
supportsPip = r.supportsPictureInPicture();
supportsMultiWindow = r.supportsMultiWindow();
supportsMultiWindow = r.supportsMultiWindowInDisplayArea(this);
}
}
@@ -2078,14 +2078,15 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
task.finishAllActivitiesImmediately();
} else {
// Reparent task to corresponding launch root or display area.
final WindowContainer launchRoot = task.supportsSplitScreenWindowingMode()
? toDisplayArea.getLaunchRootTask(
task.getWindowingMode(),
task.getActivityType(),
null /* options */,
null /* sourceTask */,
0 /* launchFlags */)
: null;
final WindowContainer launchRoot =
task.supportsSplitScreenWindowingModeInDisplayArea(toDisplayArea)
? toDisplayArea.getLaunchRootTask(
task.getWindowingMode(),
task.getActivityType(),
null /* options */,
null /* sourceTask */,
0 /* launchFlags */)
: null;
task.reparent(launchRoot == null ? toDisplayArea : launchRoot, POSITION_TOP);
// Set the windowing mode to undefined by default to let the root task inherited the
@@ -2101,7 +2102,8 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
if (lastReparentedRootTask != null) {
if (toDisplayArea.isSplitScreenModeActivated()
&& !lastReparentedRootTask.supportsSplitScreenWindowingMode()) {
&& !lastReparentedRootTask.supportsSplitScreenWindowingModeInDisplayArea(
toDisplayArea)) {
// Dismiss split screen if the last reparented root task doesn't support split mode.
mAtmService.getTaskChangeNotificationController()
.notifyActivityDismissingDockedRootTask();

View File

@@ -612,7 +612,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
private boolean shouldLaunchUnresizableAppInFreeform(ActivityRecord activity,
TaskDisplayArea displayArea) {
if (!activity.supportsFreeform() || activity.isResizeable()) {
if (!activity.supportsFreeformInDisplayArea(displayArea) || activity.isResizeable()) {
return false;
}

View File

@@ -569,14 +569,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (newParent.asTaskDisplayArea() != null) {
// For now, reparenting to displayarea is different from other reparents...
as.reparent(newParent.asTaskDisplayArea(), hop.getToTop());
} else {
} else if (newParent.asTask() != null) {
if (newParent.inMultiWindowMode() && task.isLeafTask()) {
if (newParent.inPinnedWindowingMode()) {
Slog.w(TAG, "Can't support moving a task to another PIP window..."
+ " newParent=" + newParent + " task=" + task);
return 0;
}
if (!task.supportsMultiWindow()) {
if (!task.supportsMultiWindowInDisplayArea(
newParent.asTask().getDisplayArea())) {
Slog.w(TAG, "Can't support task that doesn't support multi-window"
+ " mode in multi-window mode... newParent=" + newParent
+ " task=" + task);
@@ -586,6 +587,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
task.reparent((Task) newParent,
hop.getToTop() ? POSITION_TOP : POSITION_BOTTOM,
false /*moveParents*/, "sanitizeAndApplyHierarchyOp");
} else {
throw new RuntimeException("Can only reparent task to another task or"
+ " taskDisplayArea, but not " + newParent);
}
} else {
final Task rootTask = (Task) (
@@ -641,6 +645,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
}
final boolean newParentInMultiWindow = newParent.inMultiWindowMode();
final TaskDisplayArea newParentTda = newParent.asTask() != null
? newParent.asTask().getDisplayArea()
: newParent.asTaskDisplayArea();
final WindowContainer finalCurrentParent = currentParent;
Slog.i(TAG, "reparentChildrenTasksHierarchyOp"
+ " currentParent=" + currentParent + " newParent=" + newParent + " hop=" + hop);
@@ -656,7 +663,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
// are reparenting from.
return;
}
if (newParentInMultiWindow && !task.supportsMultiWindow()) {
if (newParentInMultiWindow && !task.supportsMultiWindowInDisplayArea(newParentTda)) {
Slog.e(TAG, "reparentChildrenTasksHierarchyOp non-resizeable task to multi window,"
+ " task=" + task);
return;

View File

@@ -2034,20 +2034,29 @@ public class ActivityRecordTests extends WindowTestsBase {
.setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
.build();
// Non-resizable
// Not allow non-resizable
mAtm.mForceResizableActivities = false;
mAtm.mSupportsNonResizableMultiWindow = -1;
mAtm.mDevEnableNonResizableMultiWindow = false;
assertFalse(activity.supportsSplitScreenWindowingMode());
// Force resizable
mAtm.mForceResizableActivities = true;
mAtm.mSupportsNonResizableMultiWindow = -1;
mAtm.mDevEnableNonResizableMultiWindow = false;
assertTrue(activity.supportsSplitScreenWindowingMode());
// Allow non-resizable
// Use development option to allow non-resizable
mAtm.mForceResizableActivities = false;
mAtm.mSupportsNonResizableMultiWindow = -1;
mAtm.mDevEnableNonResizableMultiWindow = true;
assertTrue(activity.supportsSplitScreenWindowingMode());
// Always allow non-resizable
mAtm.mForceResizableActivities = false;
mAtm.mSupportsNonResizableMultiWindow = 1;
mAtm.mDevEnableNonResizableMultiWindow = false;
assertTrue(activity.supportsSplitScreenWindowingMode());
}
@Test
@@ -2058,20 +2067,29 @@ public class ActivityRecordTests extends WindowTestsBase {
.setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
.build();
// Non-resizable
// Not allow non-resizable
mAtm.mForceResizableActivities = false;
mAtm.mSupportsNonResizableMultiWindow = -1;
mAtm.mDevEnableNonResizableMultiWindow = false;
assertFalse(activity.supportsFreeform());
// Force resizable
mAtm.mForceResizableActivities = true;
mAtm.mSupportsNonResizableMultiWindow = -1;
mAtm.mDevEnableNonResizableMultiWindow = false;
assertTrue(activity.supportsFreeform());
// Allow non-resizable
// Use development option to allow non-resizable
mAtm.mForceResizableActivities = false;
mAtm.mSupportsNonResizableMultiWindow = -1;
mAtm.mDevEnableNonResizableMultiWindow = true;
assertTrue(activity.supportsFreeform());
// Always allow non-resizable
mAtm.mForceResizableActivities = false;
mAtm.mSupportsNonResizableMultiWindow = 1;
mAtm.mDevEnableNonResizableMultiWindow = false;
assertTrue(activity.supportsFreeform());
}
@Test

View File

@@ -320,8 +320,8 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
.build();
final Task task = activity.getTask();
assertTrue(activity.supportsMultiWindow2());
assertTrue(task.supportsMultiWindow2());
assertTrue(activity.supportsMultiWindow());
assertTrue(task.supportsMultiWindow());
}
@Test
@@ -336,14 +336,14 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
// Device config as not support.
mAtm.mSupportsNonResizableMultiWindow = -1;
assertFalse(activity.supportsMultiWindow2());
assertFalse(task.supportsMultiWindow2());
assertFalse(activity.supportsMultiWindow());
assertFalse(task.supportsMultiWindow());
// Device config as always support.
mAtm.mSupportsNonResizableMultiWindow = 1;
assertTrue(activity.supportsMultiWindow2());
assertTrue(task.supportsMultiWindow2());
assertTrue(activity.supportsMultiWindow());
assertTrue(task.supportsMultiWindow());
// The default config is relying on the screen size.
mAtm.mSupportsNonResizableMultiWindow = 0;
@@ -351,14 +351,14 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
// Supports on large screen.
tda.getConfiguration().smallestScreenWidthDp = mAtm.mLargeScreenSmallestScreenWidthDp;
assertTrue(activity.supportsMultiWindow2());
assertTrue(task.supportsMultiWindow2());
assertTrue(activity.supportsMultiWindow());
assertTrue(task.supportsMultiWindow());
// Not supports on small screen.
tda.getConfiguration().smallestScreenWidthDp = mAtm.mLargeScreenSmallestScreenWidthDp - 1;
assertFalse(activity.supportsMultiWindow2());
assertFalse(task.supportsMultiWindow2());
assertFalse(activity.supportsMultiWindow());
assertFalse(task.supportsMultiWindow());
}
@Test
@@ -381,14 +381,14 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
// Ignore the activity min width/height for determine multi window eligibility.
mAtm.mRespectsActivityMinWidthHeightMultiWindow = -1;
assertTrue(activity.supportsMultiWindow2());
assertTrue(task.supportsMultiWindow2());
assertTrue(activity.supportsMultiWindow());
assertTrue(task.supportsMultiWindow());
// Always check the activity min width/height.
mAtm.mRespectsActivityMinWidthHeightMultiWindow = 1;
assertFalse(activity.supportsMultiWindow2());
assertFalse(task.supportsMultiWindow2());
assertFalse(activity.supportsMultiWindow());
assertFalse(task.supportsMultiWindow());
// The default config is relying on the screen size.
mAtm.mRespectsActivityMinWidthHeightMultiWindow = 0;
@@ -396,14 +396,14 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
// Ignore on large screen.
tda.getConfiguration().smallestScreenWidthDp = mAtm.mLargeScreenSmallestScreenWidthDp;
assertTrue(activity.supportsMultiWindow2());
assertTrue(task.supportsMultiWindow2());
assertTrue(activity.supportsMultiWindow());
assertTrue(task.supportsMultiWindow());
// Check on small screen.
tda.getConfiguration().smallestScreenWidthDp = mAtm.mLargeScreenSmallestScreenWidthDp - 1;
assertFalse(activity.supportsMultiWindow2());
assertFalse(task.supportsMultiWindow2());
assertFalse(activity.supportsMultiWindow());
assertFalse(task.supportsMultiWindow());
}
@Test
@@ -429,14 +429,14 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
// Always check the activity min width/height.
mAtm.mSupportsNonResizableMultiWindow = 1;
assertTrue(activity.supportsMultiWindow2());
assertTrue(task.supportsMultiWindow2());
assertTrue(activity.supportsMultiWindow());
assertTrue(task.supportsMultiWindow());
// The default config is relying on the screen size. Check for small screen
mAtm.mSupportsNonResizableMultiWindow = 0;
assertTrue(activity.supportsMultiWindow2());
assertTrue(task.supportsMultiWindow2());
assertTrue(activity.supportsMultiWindow());
assertTrue(task.supportsMultiWindow());
}
}

View File

@@ -488,6 +488,7 @@ public class SystemServicesTestRule implements TestRule {
mLargeScreenSmallestScreenWidthDp = 600;
mSupportsNonResizableMultiWindow = 0;
mRespectsActivityMinWidthHeightMultiWindow = 0;
mForceResizableActivities = false;
doReturn(mock(IPackageManager.class)).when(this).getPackageManager();
// allow background activity starts by default

View File

@@ -1193,13 +1193,13 @@ public class WindowOrganizerTests extends WindowTestsBase {
splitPrimaryRootTask.mRemoteToken.toWindowContainerToken(), true /* onTop */);
// Can't reparent non-resizable to split screen
mAtm.mDevEnableNonResizableMultiWindow = false;
mAtm.mSupportsNonResizableMultiWindow = -1;
mAtm.mWindowOrganizerController.applyTransaction(wct);
assertEquals(rootTask, activity.getRootTask());
// Allow reparent non-resizable to split screen
mAtm.mDevEnableNonResizableMultiWindow = true;
mAtm.mSupportsNonResizableMultiWindow = 1;
mAtm.mWindowOrganizerController.applyTransaction(wct);
assertEquals(splitPrimaryRootTask, activity.getRootTask());