summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java23
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java9
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp34
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml1
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.pngbin0 -> 56309 bytes
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.pngbin0 -> 56309 bytes
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties1
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt94
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt34
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java46
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java17
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt43
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt64
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt137
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt30
22 files changed, 424 insertions, 186 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index 612b38762d2d..9ea2943bc6da 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -50,6 +50,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
import java.util.Map;
import java.util.concurrent.Executor;
@@ -393,19 +394,31 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
if (splitAttributes == null) {
return TaskFragmentAnimationParams.DEFAULT;
}
+ final TaskFragmentAnimationParams.Builder builder =
+ new TaskFragmentAnimationParams.Builder();
final int animationBackgroundColor = getAnimationBackgroundColor(splitAttributes);
- TaskFragmentAnimationParams.Builder builder = new TaskFragmentAnimationParams.Builder();
- if (animationBackgroundColor != DEFAULT_ANIMATION_BACKGROUND_COLOR) {
- builder.setAnimationBackgroundColor(animationBackgroundColor);
+ builder.setAnimationBackgroundColor(animationBackgroundColor);
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ final int openAnimationResId =
+ splitAttributes.getAnimationParams().getOpenAnimationResId();
+ builder.setOpenAnimationResId(openAnimationResId);
+ final int closeAnimationResId =
+ splitAttributes.getAnimationParams().getCloseAnimationResId();
+ builder.setCloseAnimationResId(closeAnimationResId);
+ final int changeAnimationResId =
+ splitAttributes.getAnimationParams().getChangeAnimationResId();
+ builder.setChangeAnimationResId(changeAnimationResId);
}
- // TODO(b/293658614): Allow setting custom open/close/changeAnimationResId.
return builder.build();
}
@ColorInt
private static int getAnimationBackgroundColor(@NonNull SplitAttributes splitAttributes) {
int animationBackgroundColor = DEFAULT_ANIMATION_BACKGROUND_COLOR;
- final AnimationBackground animationBackground = splitAttributes.getAnimationBackground();
+ AnimationBackground animationBackground = splitAttributes.getAnimationBackground();
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ animationBackground = splitAttributes.getAnimationParams().getAnimationBackground();
+ }
if (animationBackground instanceof AnimationBackground.ColorBackground colorBackground) {
animationBackgroundColor = colorBackground.getColor();
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
index 4267749dfa6b..c5aaddc4e0ed 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
@@ -29,6 +29,7 @@ import android.view.WindowManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.window.extensions.embedding.AnimationBackground;
+import androidx.window.extensions.embedding.AnimationParams;
import androidx.window.extensions.embedding.SplitAttributes;
import org.junit.Before;
@@ -112,5 +113,13 @@ public class WindowExtensionsTest {
.isEqualTo(new SplitAttributes.SplitType.RatioSplitType(0.5f));
assertThat(splitAttributes.getAnimationBackground())
.isEqualTo(AnimationBackground.ANIMATION_BACKGROUND_DEFAULT);
+ assertThat(splitAttributes.getAnimationParams().getAnimationBackground())
+ .isEqualTo(AnimationBackground.ANIMATION_BACKGROUND_DEFAULT);
+ assertThat(splitAttributes.getAnimationParams().getOpenAnimationResId())
+ .isEqualTo(AnimationParams.DEFAULT_ANIMATION_RESOURCES_ID);
+ assertThat(splitAttributes.getAnimationParams().getCloseAnimationResId())
+ .isEqualTo(AnimationParams.DEFAULT_ANIMATION_RESOURCES_ID);
+ assertThat(splitAttributes.getAnimationParams().getChangeAnimationResId())
+ .isEqualTo(AnimationParams.DEFAULT_ANIMATION_RESOURCES_ID);
}
}
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp b/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
index c6dbd9b25e7f..1871203c7600 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
@@ -22,6 +22,40 @@ package {
default_team: "trendy_team_multitasking_windowing",
}
+android_app {
+ name: "WMShellRobolectricScreenshotTestApp",
+ platform_apis: true,
+ certificate: "platform",
+ static_libs: [
+ "WindowManager-Shell",
+ "platform-screenshot-diff-core",
+ ],
+ asset_dirs: ["goldens/robolectric"],
+ manifest: "AndroidManifestRobolectric.xml",
+ use_resource_processor: true,
+}
+
+android_robolectric_test {
+ name: "WMShellRobolectricScreenshotTests",
+ instrumentation_for: "WMShellRobolectricScreenshotTestApp",
+ upstream: true,
+ java_resource_dirs: [
+ "robolectric/config",
+ ],
+ srcs: [
+ "src/**/*.kt",
+ ],
+ static_libs: [
+ "junit",
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "truth",
+ "platform-parametric-runner-lib",
+ ],
+ auto_gen_config: true,
+}
+
android_test {
name: "WMShellMultivalentScreenshotTestsOnDevice",
srcs: [
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml
index a7a3f1313a9b..b4bdaeaf0eac 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml
@@ -16,7 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.wm.shell.multivalentscreenshot">
<application android:debuggable="true" android:supportsRtl="true">
- <uses-library android:name="android.test.runner" />
<activity
android:name="platform.test.screenshot.ScreenshotActivity"
android:exported="true">
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.png
new file mode 100644
index 000000000000..723c6b8d9c93
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.png
new file mode 100644
index 000000000000..723c6b8d9c93
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties b/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties
index 7a0527ccaafb..d50d976c9e84 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties
@@ -1,2 +1,3 @@
sdk=NEWEST_SDK
+graphicsMode=NATIVE
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
index dfc9c82d85ff..8f7fdd6a7b84 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
@@ -37,15 +37,12 @@ enum class DesktopModeFlags(
// All desktop mode related flags will be added here
DESKTOP_WINDOWING_MODE(DesktopModeStatus::isDesktopModeFlagEnabled, true);
- private val TAG = "DesktopModeFlags"
-
- // Cache for toggle override, which is initialized once on its first access. It needs to be refreshed
- // only on reboots as overridden state takes effect on reboots.
+ // Local cache for toggle override, which is initialized once on its first access. It needs to be
+ // refreshed only on reboots as overridden state takes effect on reboots.
private var cachedToggleOverride: ToggleOverride? = null
/**
- * Determines state of flag based on the actual flag and desktop mode developer option
- * overrides.
+ * Determines state of flag based on the actual flag and desktop mode developer option overrides.
*
* Note, this method makes sure that a constant developer toggle overrides is read until reboot.
*/
@@ -63,34 +60,44 @@ enum class DesktopModeFlags(
}
private fun getToggleOverride(context: Context): ToggleOverride {
- val override = cachedToggleOverride ?: run {
- // Cache toggle override the first time we encounter context. Override does not change
- // with context, as context is just used to fetch a system property.
+ val override =
+ cachedToggleOverride
+ ?: run {
+ val override = getToggleOverrideFromSystem(context)
+ // Cache toggle override the first time we encounter context. Override does not change
+ // with context, as context is just used to fetch System Property and Settings.Global
+ cachedToggleOverride = override
+ Log.d(TAG, "Toggle override initialized to: $override")
+ override
+ }
- // TODO(b/348193756): Cache a persistent value for Settings.Global until reboot. Current
- // cache will change with process restart.
- val toggleOverride =
- Settings.Global.getInt(
- context.contentResolver,
- Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES,
- ToggleOverride.OVERRIDE_UNSET.setting)
+ return override
+ }
- val newOverride =
- settingToToggleOverrideMap[toggleOverride]
- ?: run {
- Log.w(TAG, "Unknown toggleOverride $toggleOverride")
- ToggleOverride.OVERRIDE_UNSET
- }
- cachedToggleOverride = newOverride
- Log.d(TAG, "Toggle override initialized to: $newOverride")
- newOverride
- }
+ private fun getToggleOverrideFromSystem(context: Context): ToggleOverride {
+ // A non-persistent System Property is used to store override to ensure it remains
+ // constant till reboot.
+ val overrideFromSystemProperties: ToggleOverride? =
+ System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, null).convertToToggleOverride()
+ return overrideFromSystemProperties
+ ?: run {
+ // Read Setting Global if System Property is not present (just after reboot)
+ // or not valid (user manually changed the value)
+ val overrideFromSettingsGlobal =
+ Settings.Global.getInt(
+ context.contentResolver,
+ Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES,
+ ToggleOverride.OVERRIDE_UNSET.setting)
+ .convertToToggleOverrideWithFallback(ToggleOverride.OVERRIDE_UNSET)
+ // Initialize System Property
+ System.setProperty(
+ SYSTEM_PROPERTY_OVERRIDE_KEY, overrideFromSettingsGlobal.setting.toString())
- return override
+ overrideFromSettingsGlobal
+ }
}
- // TODO(b/348193756): Share ToggleOverride enum with Settings
- // 'DesktopModePreferenceController'
+ // TODO(b/348193756): Share ToggleOverride enum with Settings 'DesktopModePreferenceController'
/**
* Override state of desktop mode developer option toggle.
*
@@ -107,4 +114,33 @@ enum class DesktopModeFlags(
}
private val settingToToggleOverrideMap = ToggleOverride.entries.associateBy { it.setting }
+
+ private fun String?.convertToToggleOverride(): ToggleOverride? {
+ val intValue = this?.toIntOrNull() ?: return null
+ return settingToToggleOverrideMap[intValue]
+ ?: run {
+ Log.w(TAG, "Unknown toggleOverride int $intValue")
+ null
+ }
+ }
+
+ private fun Int.convertToToggleOverrideWithFallback(
+ fallbackOverride: ToggleOverride
+ ): ToggleOverride {
+ return settingToToggleOverrideMap[this]
+ ?: run {
+ Log.w(TAG, "Unknown toggleOverride int $this")
+ fallbackOverride
+ }
+ }
+
+ private companion object {
+ const val TAG = "DesktopModeFlags"
+
+ /**
+ * Key for non-persistent System Property which is used to store desktop windowing developer
+ * option overrides.
+ */
+ const val SYSTEM_PROPERTY_OVERRIDE_KEY = "sys.wmshell.desktopmode.dev_toggle_override"
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index d270d2b4ccf1..5696a544152c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -266,6 +266,9 @@ class ActivityEmbeddingAnimationRunner {
final Animation animation =
animationProvider.get(info, change, openingWholeScreenBounds);
if (shouldUseJumpCutForAnimation(animation)) {
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ return new ArrayList<>();
+ }
continue;
}
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
@@ -291,6 +294,9 @@ class ActivityEmbeddingAnimationRunner {
final Animation animation =
animationProvider.get(info, change, closingWholeScreenBounds);
if (shouldUseJumpCutForAnimation(animation)) {
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ return new ArrayList<>();
+ }
continue;
}
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index f49b90d08a75..3046307702c2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -97,7 +97,7 @@ class ActivityEmbeddingAnimationSpec {
Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
if (customAnimation != null) {
return customAnimation;
}
@@ -131,7 +131,7 @@ class ActivityEmbeddingAnimationSpec {
Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
if (customAnimation != null) {
return customAnimation;
}
@@ -172,7 +172,7 @@ class ActivityEmbeddingAnimationSpec {
// TODO(b/293658614): Support more complicated animations that may need more than a noop
// animation as the start leash.
final Animation noopAnimation = createNoopAnimation(change);
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
if (customAnimation != null) {
return new Animation[]{noopAnimation, customAnimation};
}
@@ -227,7 +227,7 @@ class ActivityEmbeddingAnimationSpec {
Animation loadOpenAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
final boolean isEnter = TransitionUtil.isOpeningType(change.getMode());
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, change.getMode());
final Animation animation;
if (customAnimation != null) {
animation = customAnimation;
@@ -254,7 +254,7 @@ class ActivityEmbeddingAnimationSpec {
Animation loadCloseAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
final boolean isEnter = TransitionUtil.isOpeningType(change.getMode());
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, change.getMode());
final Animation animation;
if (customAnimation != null) {
animation = customAnimation;
@@ -287,14 +287,14 @@ class ActivityEmbeddingAnimationSpec {
@Nullable
private Animation loadCustomAnimation(@NonNull TransitionInfo info,
- @NonNull TransitionInfo.Change change) {
+ @NonNull TransitionInfo.Change change, @WindowManager.TransitionType int mode) {
final TransitionInfo.AnimationOptions options;
if (Flags.moveAnimationOptionsToChange()) {
options = change.getAnimationOptions();
} else {
options = info.getAnimationOptions();
}
- return loadCustomAnimationFromOptions(options, change.getMode());
+ return loadCustomAnimationFromOptions(options, mode);
}
@Nullable
@@ -319,8 +319,14 @@ class ActivityEmbeddingAnimationSpec {
return null;
}
- final Animation anim = mTransitionAnimation.loadAnimationRes(options.getPackageName(),
- resId);
+ final Animation anim;
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ // TODO(b/293658614): Consider allowing custom animations from non-default packages.
+ // Enforce limiting to animations from the default "android" package for now.
+ anim = mTransitionAnimation.loadDefaultAnimationRes(resId);
+ } else {
+ anim = mTransitionAnimation.loadAnimationRes(options.getPackageName(), resId);
+ }
if (anim != null) {
return anim;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt
index 6781d08c9904..d1b2347a4411 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt
@@ -19,6 +19,16 @@
package com.android.wm.shell.compatui
import android.app.TaskInfo
-fun isSingleTopActivityTranslucent(task: TaskInfo) =
- task.isTopActivityTransparent && task.numActivities == 1
+import android.content.Context
+import com.android.internal.R
+// TODO(b/347289970): Consider replacing with API
+fun isTopActivityExemptFromDesktopWindowing(context: Context, task: TaskInfo) =
+ isSystemUiTask(context, task) || (task.isTopActivityTransparent && task.numActivities == 1
+ && !task.isTopActivityStyleFloating)
+
+private fun isSystemUiTask(context: Context, task: TaskInfo): Boolean {
+ val sysUiPackageName: String =
+ context.resources.getString(R.string.config_systemUi)
+ return task.baseActivity?.packageName == sysUiPackageName
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index da1d6daff8c6..e792f7ad4263 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -24,7 +24,6 @@ import android.os.Handler;
import android.os.UserManager;
import android.view.Choreographer;
import android.view.IWindowManager;
-import android.view.SurfaceControl;
import android.view.WindowManager;
import com.android.internal.jank.InteractionJankMonitor;
@@ -404,8 +403,7 @@ public abstract class WMShellModule {
Optional<RecentTasksController> recentTasksController,
HomeTransitionObserver homeTransitionObserver) {
return new RecentsTransitionHandler(shellInit, transitions,
- recentTasksController.orElse(null), homeTransitionObserver,
- SurfaceControl.Transaction::new);
+ recentTasksController.orElse(null), homeTransitionObserver);
}
//
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 4868a2f2f905..e24791292085 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -66,7 +66,7 @@ import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
-import com.android.wm.shell.compatui.isSingleTopActivityTranslucent
+import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.DragToDesktopStateListener
import com.android.wm.shell.draganddrop.DragAndDropController
@@ -158,8 +158,6 @@ class DesktopTasksController(
visualIndicator = null
}
}
- private val sysUIPackageName = context.resources.getString(
- com.android.internal.R.string.config_systemUi)
private val transitionAreaHeight
get() =
@@ -219,11 +217,6 @@ class DesktopTasksController(
return visualIndicator
}
- // TODO(b/347289970): Consider replacing with API
- private fun isSystemUIApplication(taskInfo: RunningTaskInfo): Boolean {
- return taskInfo.baseActivity?.packageName == sysUIPackageName
- }
-
fun setOnTaskResizeAnimationListener(listener: OnTaskResizeAnimationListener) {
toggleResizeDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
enterDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
@@ -351,19 +344,12 @@ class DesktopTasksController(
wct: WindowContainerTransaction = WindowContainerTransaction(),
transitionSource: DesktopModeTransitionSource,
) {
- if (Flags.enableDesktopWindowingModalsPolicy() && isSingleTopActivityTranslucent(task)) {
- KtProtoLog.w(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: Cannot enter desktop, " +
- "translucent top activity found. This is likely a modal dialog."
- )
- return
- }
- if (isSystemUIApplication(task)) {
+ if (Flags.enableDesktopWindowingModalsPolicy()
+ && isTopActivityExemptFromDesktopWindowing(context, task)) {
KtProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: Cannot enter desktop, " +
- "systemUI top activity found."
+ "ineligible top activity found."
)
return
}
@@ -942,10 +928,8 @@ class DesktopTasksController(
when {
// Check if the closing task needs to be handled
TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task)
- // Check if the task has a top transparent activity
- shouldLaunchAsModal(task) -> handleIncompatibleTaskLaunch(task)
- // Check if the task has a top systemUI activity
- isSystemUIApplication(task) -> handleIncompatibleTaskLaunch(task)
+ // Check if the top task shouldn't be allowed to enter desktop mode
+ isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task)
// Check if fullscreen task should be updated
task.isFullscreen -> handleFullscreenTaskLaunch(task, transition)
// Check if freeform task should be updated
@@ -979,9 +963,9 @@ class DesktopTasksController(
.forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
}
- // TODO(b/347289970): Consider replacing with API
- private fun shouldLaunchAsModal(task: TaskInfo) =
- Flags.enableDesktopWindowingModalsPolicy() && isSingleTopActivityTranslucent(task)
+ private fun isIncompatibleTask(task: TaskInfo) =
+ Flags.enableDesktopWindowingModalsPolicy()
+ && isTopActivityExemptFromDesktopWindowing(context, task)
private fun shouldHandleTaskClosing(request: TransitionRequestInfo): Boolean {
return Flags.enableDesktopWindowingWallpaperActivity() &&
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index e46625debcc6..234b4d0f86db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -74,7 +74,6 @@ import com.android.wm.shell.transition.Transitions;
import java.util.ArrayList;
import java.util.function.Consumer;
-import java.util.function.Supplier;
/**
* Handles the Recents (overview) animation. Only one of these can run at a time. A recents
@@ -85,7 +84,6 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
private final Transitions mTransitions;
private final ShellExecutor mExecutor;
- private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
@Nullable
private final RecentTasksController mRecentTasksController;
private IApplicationThread mAnimApp = null;
@@ -103,13 +101,11 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
public RecentsTransitionHandler(ShellInit shellInit, Transitions transitions,
@Nullable RecentTasksController recentTasksController,
- HomeTransitionObserver homeTransitionObserver,
- Supplier<SurfaceControl.Transaction> transactionSupplier) {
+ HomeTransitionObserver homeTransitionObserver) {
mTransitions = transitions;
mExecutor = transitions.getMainExecutor();
mRecentTasksController = recentTasksController;
mHomeTransitionObserver = homeTransitionObserver;
- mTransactionSupplier = transactionSupplier;
if (!Transitions.ENABLE_SHELL_TRANSITIONS) return;
if (recentTasksController == null) return;
shellInit.addInitCallback(() -> {
@@ -1060,7 +1056,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
final Transitions.TransitionFinishCallback finishCB = mFinishCB;
mFinishCB = null;
- SurfaceControl.Transaction t = mFinishTransaction;
+ final SurfaceControl.Transaction t = mFinishTransaction;
final WindowContainerTransaction wct = new WindowContainerTransaction();
if (mKeyguardLocked && mRecentsTask != null) {
@@ -1110,16 +1106,6 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
}
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, " normal finish");
- if (toHome && !mOpeningTasks.isEmpty()) {
- // Attempting to start a task after swipe to home, don't show it,
- // move recents to top
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " attempting to start a task after swipe to home");
- t = mTransactionSupplier.get();
- wct.reorder(mRecentsTask, true /*onTop*/);
- mClosingTasks.addAll(mOpeningTasks);
- mOpeningTasks.clear();
- }
// The general case: committing to recents, going home, or switching tasks.
for (int i = 0; i < mOpeningTasks.size(); ++i) {
t.show(mOpeningTasks.get(i).mTaskSurface);
@@ -1188,10 +1174,6 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
mPipTransaction = null;
}
}
- if (t != mFinishTransaction) {
- // apply after merges because these changes are accounting for finishWCT changes.
- mTransitions.setAfterMergeFinishTransaction(mTransition, t);
- }
cleanUp();
finishCB.onTransitionFinished(wct.isEmpty() ? null : wct);
if (runnerFinishCb != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index b8abf8f2a3c0..21307a2edae0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -77,6 +77,7 @@ import androidx.annotation.BinderThread;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
+import com.android.window.flags.Flags;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -242,13 +243,6 @@ public class Transitions implements RemoteCallable<Transitions>,
/** Ordered list of transitions which have been merged into this one. */
private ArrayList<ActiveTransition> mMerged;
- /**
- * @deprecated DO NOT USE THIS unless absolutely necessary. It will be removed once
- * everything migrates off finishWCT.
- */
- @java.lang.Deprecated
- SurfaceControl.Transaction mAfterMergeFinishT;
-
ActiveTransition(IBinder token) {
mToken = token;
}
@@ -586,6 +580,14 @@ public class Transitions implements RemoteCallable<Transitions>,
final boolean isOpening = isOpeningType(transitType);
final boolean isClosing = isClosingType(transitType);
final int mode = change.getMode();
+ // Ensure wallpapers stay in the back
+ if (change.hasFlags(FLAG_IS_WALLPAPER) && Flags.ensureWallpaperInTransitions()) {
+ if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
+ return -zSplitLine + numChanges - i;
+ } else {
+ return -zSplitLine - i;
+ }
+ }
// Put all the OPEN/SHOW on top
if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
if (isOpening) {
@@ -1034,20 +1036,6 @@ public class Transitions implements RemoteCallable<Transitions>,
return null;
}
- /** @deprecated */
- @java.lang.Deprecated
- public void setAfterMergeFinishTransaction(IBinder transition,
- SurfaceControl.Transaction afterMergeFinishT) {
- final ActiveTransition at = mKnownTransitions.get(transition);
- if (at == null) return;
- if (at.mAfterMergeFinishT != null) {
- Log.e(TAG, "Setting after-merge-t >1 time on transition: " + at.mInfo.getDebugId());
- at.mAfterMergeFinishT.merge(afterMergeFinishT);
- return;
- }
- at.mAfterMergeFinishT = afterMergeFinishT;
- }
-
/** Aborts a transition. This will still queue it up to maintain order. */
private void onAbort(ActiveTransition transition) {
final Track track = mTracks.get(transition.getTrack());
@@ -1108,7 +1096,6 @@ public class Transitions implements RemoteCallable<Transitions>,
}
// Merge all associated transactions together
SurfaceControl.Transaction fullFinish = active.mFinishT;
- SurfaceControl.Transaction afterMergeFinish = active.mAfterMergeFinishT;
if (active.mMerged != null) {
for (int iM = 0; iM < active.mMerged.size(); ++iM) {
final ActiveTransition toMerge = active.mMerged.get(iM);
@@ -1128,21 +1115,6 @@ public class Transitions implements RemoteCallable<Transitions>,
fullFinish.merge(toMerge.mFinishT);
}
}
- if (toMerge.mAfterMergeFinishT != null) {
- if (afterMergeFinish == null) {
- afterMergeFinish = toMerge.mAfterMergeFinishT;
- } else {
- afterMergeFinish.merge(toMerge.mAfterMergeFinishT);
- }
- toMerge.mAfterMergeFinishT = null;
- }
- }
- }
- if (afterMergeFinish != null) {
- if (fullFinish == null) {
- fullFinish = afterMergeFinish;
- } else {
- fullFinish.merge(afterMergeFinish);
}
}
if (fullFinish != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index e3aa31f7e286..440fc4d314bb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -32,7 +32,7 @@ import static android.view.WindowInsets.Type.statusBars;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.compatui.AppCompatUtils.isSingleTopActivityTranslucent;
+import static com.android.wm.shell.compatui.AppCompatUtils.isTopActivityExemptFromDesktopWindowing;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
@@ -105,7 +105,6 @@ import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
import java.io.PrintWriter;
-import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
@@ -1034,12 +1033,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
&& taskInfo.isFocused) {
return false;
}
- // TODO(b/347289970): Consider replacing with API
if (Flags.enableDesktopWindowingModalsPolicy()
- && isSingleTopActivityTranslucent(taskInfo)) {
- return false;
- }
- if (isSystemUIApplication(taskInfo)) {
+ && isTopActivityExemptFromDesktopWindowing(mContext, taskInfo)) {
return false;
}
return DesktopModeStatus.canEnterDesktopMode(mContext)
@@ -1118,14 +1113,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
&& mSplitScreenController.isTaskInSplitScreen(taskId);
}
- // TODO(b/347289970): Consider replacing with API
- private boolean isSystemUIApplication(RunningTaskInfo taskInfo) {
- if (taskInfo.baseActivity != null) {
- return (Objects.equals(taskInfo.baseActivity.getPackageName(), mSysUIPackageName));
- }
- return false;
- }
-
private void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + "DesktopModeWindowDecorViewModel");
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index a0a61fe2cf72..d0e8215e662e 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -117,12 +117,10 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
/**
* Checks that all parts of the screen are covered at the start and end of the transition
- *
- * TODO b/197726599 Prevents all states from being checked
*/
@Presubmit
@Test
- fun entireScreenCoveredAtStartAndEnd() = flicker.entireScreenCovered(allStates = false)
+ fun entireScreenCoveredAtStartAndEnd() = flicker.entireScreenCovered()
/** Checks [pipApp] window remains visible and on top throughout the transition */
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
index 4cd2a366f5eb..ecaf970ae389 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
@@ -16,8 +16,10 @@
package com.android.wm.shell.compatui
+import android.content.ComponentName
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
+import com.android.internal.R
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
import org.junit.Assert.assertFalse
@@ -34,26 +36,55 @@ import org.junit.runner.RunWith
@RunWith(AndroidTestingRunner::class)
@SmallTest
class AppCompatUtilsTest : ShellTestCase() {
-
@Test
- fun testIsSingleTopActivityTranslucent() {
- assertTrue(isSingleTopActivityTranslucent(
+ fun testIsTopActivityExemptFromDesktopWindowing_topActivityTransparent() {
+ assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
createFreeformTask(/* displayId */ 0)
.apply {
isTopActivityTransparent = true
numActivities = 1
}))
- assertFalse(isSingleTopActivityTranslucent(
+ assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
createFreeformTask(/* displayId */ 0)
.apply {
isTopActivityTransparent = true
numActivities = 0
}))
- assertFalse(isSingleTopActivityTranslucent(
+ }
+
+ @Test
+ fun testIsTopActivityExemptFromDesktopWindowing_singleTopActivity() {
+ assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
+ createFreeformTask(/* displayId */ 0)
+ .apply {
+ isTopActivityTransparent = true
+ numActivities = 1
+ }))
+ assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
createFreeformTask(/* displayId */ 0)
.apply {
isTopActivityTransparent = false
numActivities = 1
}))
}
-} \ No newline at end of file
+
+ @Test
+ fun testIsTopActivityExemptFromDesktopWindowing__topActivityStyleFloating() {
+ assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
+ createFreeformTask(/* displayId */ 0)
+ .apply {
+ isTopActivityStyleFloating = true
+ }))
+ }
+
+ @Test
+ fun testIsTopActivityExemptFromDesktopWindowing_systemUiTask() {
+ val systemUIPackageName = context.resources.getString(R.string.config_systemUi)
+ val baseComponent = ComponentName(systemUIPackageName, /* class */ "")
+ assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
+ createFreeformTask(/* displayId */ 0)
+ .apply {
+ baseActivity = baseComponent
+ }))
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 8c7de5c24bb8..bd38d360a15b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -700,19 +700,37 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun moveToDesktop_topActivityTranslucent_doesNothing() {
- setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun moveToDesktop_topActivityTranslucentWithStyleFloating_taskIsMovedToDesktop() {
val task =
- setUpFullscreenTask().apply {
- isTopActivityTransparent = true
- numActivities = 1
- }
+ setUpFullscreenTask().apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = true
+ numActivities = 1
+ }
+
+ controller.moveToDesktop(task, transitionSource = UNKNOWN)
+
+ val wct = getLatestEnterDesktopWct()
+ assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun moveToDesktop_topActivityTranslucentWithoutStyleFloating_doesNothing() {
+ val task =
+ setUpFullscreenTask().apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = false
+ numActivities = 1
+ }
controller.moveToDesktop(task, transitionSource = UNKNOWN)
verifyEnterDesktopWCTNotExecuted()
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
fun moveToDesktop_systemUIActivity_doesNothing() {
val task = setUpFullscreenTask()
@@ -1374,20 +1392,40 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun handleRequest_shouldLaunchAsModal_returnSwitchToFullscreenWCT() {
- setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun handleRequest_topActivityTransparentWithStyleFloating_returnSwitchToFreeformWCT() {
+ val freeformTask = setUpFreeformTask()
+ markTaskVisible(freeformTask)
+
val task =
- setUpFreeformTask().apply {
- isTopActivityTransparent = true
- numActivities = 1
- }
+ setUpFullscreenTask().apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = true
+ numActivities = 1
+ }
val result = controller.handleRequest(Binder(), createTransition(task))
assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode)
- .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+ .isEqualTo(WINDOWING_MODE_FREEFORM)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun handleRequest_topActivityTransparentWithoutStyleFloating_returnSwitchToFullscreenWCT() {
+ val task =
+ setUpFreeformTask().apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = false
+ numActivities = 1
+ }
+
+ val result = controller.handleRequest(Binder(), createTransition(task))
+ assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
fun handleRequest_systemUIActivity_returnSwitchToFullscreenWCT() {
val task = setUpFreeformTask()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
index 115b218f2e82..17983b27f4e8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
@@ -82,7 +82,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_unsetOverride_featureFlagOn_returnsTrue() {
+ fun isEnabled_overrideUnset_featureFlagOn_returnsTrue() {
setOverride(OVERRIDE_UNSET.setting)
// For overridableFlag, for unset overrides, follow flag
@@ -92,7 +92,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_unsetOverride_featureFlagOff_returnsFalse() {
+ fun isEnabled_overrideUnset_featureFlagOff_returnsFalse() {
setOverride(OVERRIDE_UNSET.setting)
// For overridableFlag, for unset overrides, follow flag
@@ -101,7 +101,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_noOverride_featureFlagOn_returnsTrue() {
+ fun isEnabled_noOverride_featureFlagOn_returnsTrue() {
setOverride(null)
// For overridableFlag, in absence of overrides, follow flag
@@ -111,7 +111,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_noOverride_featureFlagOff_returnsFalse() {
+ fun isEnabled_noOverride_featureFlagOff_returnsFalse() {
setOverride(null)
// For overridableFlag, in absence of overrides, follow flag
@@ -120,7 +120,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_unrecognizableOverride_featureFlagOn_returnsTrue() {
+ fun isEnabled_unrecognizableOverride_featureFlagOn_returnsTrue() {
setOverride(-2)
// For overridableFlag, for recognizable overrides, follow flag
@@ -130,7 +130,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_unrecognizableOverride_featureFlagOff_returnsFalse() {
+ fun isEnabled_unrecognizableOverride_featureFlagOff_returnsFalse() {
setOverride(-2)
// For overridableFlag, for recognizable overrides, follow flag
@@ -139,7 +139,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_overrideOff_featureFlagOn_returnsFalse() {
+ fun isEnabled_overrideOff_featureFlagOn_returnsFalse() {
setOverride(OVERRIDE_OFF.setting)
// For overridableFlag, follow override if they exist
@@ -149,7 +149,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_overrideOn_featureFlagOff_returnsTrue() {
+ fun isEnabled_overrideOn_featureFlagOff_returnsTrue() {
setOverride(OVERRIDE_ON.setting)
// For overridableFlag, follow override if they exist
@@ -158,7 +158,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_overrideOffThenOn_featureFlagOn_returnsFalseAndFalse() {
+ fun isEnabled_overrideOffThenOn_featureFlagOn_returnsFalseAndFalse() {
setOverride(OVERRIDE_OFF.setting)
// For overridableFlag, follow override if they exist
@@ -173,7 +173,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_overrideOnThenOff_featureFlagOff_returnsTrueAndTrue() {
+ fun isEnabled_overrideOnThenOff_featureFlagOff_returnsTrueAndTrue() {
setOverride(OVERRIDE_ON.setting)
// For overridableFlag, follow override if they exist
@@ -187,7 +187,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_noOverride_featureFlagOnThenOff_returnsTrueAndFalse() {
+ fun isEnabled_noOverride_featureFlagOnThenOff_returnsTrueAndFalse() {
setOverride(null)
// For overridableFlag, in absence of overrides, follow flag
assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
@@ -206,6 +206,108 @@ class DesktopModeFlagsTest : ShellTestCase() {
}
}
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noSystemProperty_overrideOn_featureFlagOff_returnsTrueAndStoresPropertyOn() {
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ setOverride(OVERRIDE_ON.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ // Store System Property if not present
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_ON.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noSystemProperty_overrideUnset_featureFlagOn_returnsTrueAndStoresPropertyUnset() {
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ setOverride(OVERRIDE_UNSET.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ // Store System Property if not present
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_UNSET.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noSystemProperty_overrideUnset_featureFlagOff_returnsFalseAndStoresPropertyUnset() {
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ setOverride(OVERRIDE_UNSET.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ // Store System Property if not present
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_UNSET.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @Suppress("ktlint:standard:max-line-length")
+ fun isEnabled_systemPropertyNotInteger_overrideOff_featureFlagOn_returnsFalseAndStoresPropertyOff() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, "abc")
+ setOverride(OVERRIDE_OFF.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ // Store System Property if currently invalid
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_OFF.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @Suppress("ktlint:standard:max-line-length")
+ fun isEnabled_systemPropertyInvalidInteger_overrideOff_featureFlagOn_returnsFalseAndStoresPropertyOff() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, "-2")
+ setOverride(OVERRIDE_OFF.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ // Store System Property if currently invalid
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_OFF.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_systemPropertyOff_overrideOn_featureFlagOn_returnsFalseAndDoesNotUpdateProperty() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_OFF.setting.toString())
+ setOverride(OVERRIDE_ON.setting)
+
+ // Have a consistent override until reboot
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_OFF.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_systemPropertyOn_overrideOff_featureFlagOff_returnsTrueAndDoesNotUpdateProperty() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_ON.setting.toString())
+ setOverride(OVERRIDE_OFF.setting)
+
+ // Have a consistent override until reboot
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_ON.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @Suppress("ktlint:standard:max-line-length")
+ fun isEnabled_systemPropertyUnset_overrideOff_featureFlagOn_returnsTrueAndDoesNotUpdateProperty() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_UNSET.setting.toString())
+ setOverride(OVERRIDE_OFF.setting)
+
+ // Have a consistent override until reboot
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_UNSET.setting.toString())
+ }
+
private fun setOverride(setting: Int?) {
val contentResolver = mContext.contentResolver
val key = Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES
@@ -217,9 +319,16 @@ class DesktopModeFlagsTest : ShellTestCase() {
}
private fun resetCache() {
- val cacheToggleOverride =
+ val cachedToggleOverride =
DESKTOP_WINDOWING_MODE::class.java.getDeclaredField("cachedToggleOverride")
- cacheToggleOverride.isAccessible = true
- cacheToggleOverride.set(DESKTOP_WINDOWING_MODE, null)
+ cachedToggleOverride.isAccessible = true
+ cachedToggleOverride.set(DESKTOP_WINDOWING_MODE, null)
+
+ // Clear override cache stored in System property
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ }
+
+ private companion object {
+ const val SYSTEM_PROPERTY_OVERRIDE_KEY = "sys.wmshell.desktopmode.dev_toggle_override"
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index 8331d591fd59..409b87723e79 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -1191,8 +1191,7 @@ public class ShellTransitionTests extends ShellTestCase {
mMainHandler, mAnimExecutor, mock(HomeTransitionObserver.class));
final RecentsTransitionHandler recentsHandler =
new RecentsTransitionHandler(shellInit, transitions,
- mock(RecentTasksController.class), mock(HomeTransitionObserver.class),
- () -> mock(SurfaceControl.Transaction.class));
+ mock(RecentTasksController.class), mock(HomeTransitionObserver.class));
transitions.replaceDefaultHandlerForTest(mDefaultHandler);
shellInit.init();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 0ec671314cdf..0bf5a674aabb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -348,10 +348,35 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
}
@Test
- fun testDecorationIsNotCreatedForTopTranslucentActivities() {
- setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun testDecorationIsCreatedForTopTranslucentActivitiesWithStyleFloating() {
+ val mockitoSession: StaticMockitoSession = mockitoSession()
+ .strictness(Strictness.LENIENT)
+ .spyStatic(DesktopModeStatus::class.java)
+ .startMocking()
+ try {
+ val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true).apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = true
+ numActivities = 1
+ }
+ doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ setUpMockDecorationsForTasks(task)
+
+ onTaskOpening(task)
+ verify(mockDesktopModeWindowDecorFactory)
+ .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ } finally {
+ mockitoSession.finishMocking()
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun testDecorationIsNotCreatedForTopTranslucentActivitiesWithoutStyleFloating() {
val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true).apply {
isTopActivityTransparent = true
+ isTopActivityStyleFloating = false
numActivities = 1
}
onTaskOpening(task)
@@ -361,6 +386,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
fun testDecorationIsNotCreatedForSystemUIActivities() {
val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)