summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/AcceptOnceConsumer.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java)2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/BaseDataProducer.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java)4
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java5
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/ExtensionHelper.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java)2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java4
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java142
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java7
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java6
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java4
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/ExtensionHelperTest.java (renamed from libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/util/ExtensionHelperTest.java)2
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java24
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java3
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java98
-rw-r--r--libs/WindowManager/Shell/res/layout/compat_ui_layout.xml32
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rCA/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rXC/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-es/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-eu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-gu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-iw/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-or/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rBR/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pt/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-uk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml14
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/ImeListener.kt70
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java50
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java77
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt449
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskPosition.kt151
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt271
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt88
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java61
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java36
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java82
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/ImeListenerTest.kt152
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java104
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java112
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java170
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt323
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt17
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt341
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt106
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java21
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt82
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java10
-rw-r--r--libs/hwui/Android.bp3
-rw-r--r--libs/hwui/Properties.cpp4
-rw-r--r--libs/hwui/Properties.h2
-rw-r--r--libs/hwui/Readback.cpp11
-rw-r--r--libs/hwui/tests/macrobench/AndroidTest.xml28
-rw-r--r--libs/hwui/tests/macrobench/how_to_run.txt4
-rw-r--r--libs/hwui/tests/microbench/AndroidTest.xml (renamed from libs/hwui/AndroidTest.xml)13
-rwxr-xr-xlibs/hwui/tests/microbench/how_to_run.txt4
-rw-r--r--libs/hwui/tests/unit/AndroidTest.xml27
-rwxr-xr-xlibs/hwui/tests/unit/how_to_run.txt8
-rw-r--r--libs/hwui/tests/unit/main.cpp15
163 files changed, 2055 insertions, 1662 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/AcceptOnceConsumer.java
index 63828ab2e62b..c2f827a22fc2 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/AcceptOnceConsumer.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.window.util;
+package androidx.window.common;
import android.annotation.NonNull;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/BaseDataProducer.java
index cd26efd4fdb6..e7099dc3a281 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/BaseDataProducer.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.window.util;
+package androidx.window.common;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
@@ -125,4 +125,4 @@ public abstract class BaseDataProducer<T> implements
mCallbacksToRemove.add(callback);
}
}
-} \ No newline at end of file
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
index e37dea4dfd69..b95bca16ef5b 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
@@ -16,7 +16,7 @@
package androidx.window.common;
-import static androidx.window.util.ExtensionHelper.isZero;
+import static androidx.window.common.ExtensionHelper.isZero;
import android.annotation.IntDef;
import android.annotation.Nullable;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index 98935e95deaf..b2bc3de1e7f5 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -31,9 +31,6 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
-import androidx.window.util.AcceptOnceConsumer;
-import androidx.window.util.BaseDataProducer;
-
import com.android.internal.R;
import java.util.ArrayList;
@@ -44,7 +41,7 @@ import java.util.Optional;
import java.util.function.Consumer;
/**
- * An implementation of {@link androidx.window.util.BaseDataProducer} that returns
+ * An implementation of {@link BaseDataProducer} that returns
* the device's posture by mapping the state returned from {@link DeviceStateManager} to
* values provided in the resources' config at {@link R.array#config_device_state_postures}.
*/
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/common/ExtensionHelper.java
index a08db7939eca..f466d603bda3 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/ExtensionHelper.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.window.util;
+package androidx.window.common;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
index 88264f383153..6d758f1fb3c1 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
@@ -26,15 +26,13 @@ import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
-import androidx.window.util.BaseDataProducer;
-
import com.android.internal.R;
import java.util.Optional;
import java.util.function.Consumer;
/**
- * Implementation of {@link androidx.window.util.BaseDataProducer} that produces a
+ * Implementation of {@link BaseDataProducer} that produces a
* {@link String} that can be parsed to a {@link CommonFoldingFeature}.
* {@link RawFoldingFeatureProducer} searches for the value in two places. The first check is in
* settings where the {@link String} property is saved with the key
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 8e1fde066277..409cde30cf8c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -119,7 +119,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// TODO(b/243518738): Move to WM Extensions if we have requirement of overlay without
// association. It's not set in WM Extensions nor Wm Jetpack library currently.
- private static final String KEY_OVERLAY_ASSOCIATE_WITH_LAUNCHING_ACTIVITY =
+ @VisibleForTesting
+ static final String KEY_OVERLAY_ASSOCIATE_WITH_LAUNCHING_ACTIVITY =
"androidx.window.extensions.embedding.shouldAssociateWithLaunchingActivity";
@VisibleForTesting
@@ -2742,89 +2743,70 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
final int taskId = getTaskId(launchActivity);
- if (!overlayContainers.isEmpty()) {
- for (final TaskFragmentContainer overlayContainer : overlayContainers) {
- final boolean isTopNonFinishingOverlay = overlayContainer.equals(
- overlayContainer.getTaskContainer().getTopNonFinishingTaskFragmentContainer(
- true /* includePin */, true /* includeOverlay */));
- if (taskId != overlayContainer.getTaskId()) {
- // If there's an overlay container with same tag in a different task,
- // dismiss the overlay container since the tag must be unique per process.
- if (overlayTag.equals(overlayContainer.getOverlayTag())) {
- Log.w(TAG, "The overlay container with tag:"
- + overlayContainer.getOverlayTag() + " is dismissed because"
- + " there's an existing overlay container with the same tag but"
- + " different task ID:" + overlayContainer.getTaskId() + ". "
- + "The new associated activity is " + launchActivity);
- mPresenter.cleanupContainer(wct, overlayContainer,
- false /* shouldFinishDependant */);
- }
- continue;
- }
- if (!overlayTag.equals(overlayContainer.getOverlayTag())) {
- // If there's an overlay container with different tag on top in the same
- // task, dismiss the existing overlay container.
- if (isTopNonFinishingOverlay) {
- mPresenter.cleanupContainer(wct, overlayContainer,
- false /* shouldFinishDependant */);
- }
- continue;
- }
- // The overlay container has the same tag and task ID with the new launching
- // overlay container.
- if (!isTopNonFinishingOverlay) {
- // Dismiss the invisible overlay container regardless of activity
- // association if it collides the tag of new launched overlay container .
- Log.w(TAG, "The invisible overlay container with tag:"
- + overlayContainer.getOverlayTag() + " is dismissed because"
- + " there's a launching overlay container with the same tag."
- + " The new associated activity is " + launchActivity);
- mPresenter.cleanupContainer(wct, overlayContainer,
- false /* shouldFinishDependant */);
- continue;
- }
- // Requesting an always-on-top overlay.
- if (!associateLaunchingActivity) {
- if (overlayContainer.isOverlayWithActivityAssociation()) {
- // Dismiss the overlay container since it has associated with an activity.
- Log.w(TAG, "The overlay container with tag:"
- + overlayContainer.getOverlayTag() + " is dismissed because"
- + " there's an existing overlay container with the same tag but"
- + " different associated launching activity. The overlay container"
- + " doesn't associate with any activity.");
- mPresenter.cleanupContainer(wct, overlayContainer,
- false /* shouldFinishDependant */);
- continue;
- } else {
- // The existing overlay container doesn't associate an activity as well.
- // Just update the overlay and return.
- // Note that going to this condition means the tag, task ID matches a
- // visible always-on-top overlay, and won't dismiss any overlay any more.
- mPresenter.applyActivityStackAttributes(wct, overlayContainer, attrs,
- getMinDimensions(intent));
- return overlayContainer;
- }
- }
- if (launchActivity.getActivityToken()
- != overlayContainer.getAssociatedActivityToken()) {
- Log.w(TAG, "The overlay container with tag:"
- + overlayContainer.getOverlayTag() + " is dismissed because"
- + " there's an existing overlay container with the same tag but"
- + " different associated launching activity. The new associated"
- + " activity is " + launchActivity);
- // The associated activity must be the same, or it will be dismissed.
- mPresenter.cleanupContainer(wct, overlayContainer,
- false /* shouldFinishDependant */);
- continue;
- }
- // Reaching here means the launching activity launch an overlay container with the
- // same task ID, tag, while there's a previously launching visible overlay
- // container. We'll regard it as updating the existing overlay container.
+ // Overlay container policy:
+ // 1. Overlay tag must be unique per process.
+ // a. For associated overlay, if a new launched overlay container has the same tag as
+ // an existing one, the existing overlay will be dismissed regardless of its task
+ // and window hierarchy.
+ // b. For always-on-top overlay, if there's an overlay container has the same tag in the
+ // launched task, the overlay container will be re-used, which means the
+ // ActivityStackAttributes will be applied and the launched activity will be positioned
+ // on top of the overlay container.
+ // 2. There must be at most one overlay that partially occludes a visible activity per task.
+ // a. For associated overlay, only the top visible overlay container in the launched task
+ // will be dismissed.
+ // b. Always-on-top overlay is always visible. If there's an overlay with different tags
+ // in the same task, the overlay will be dismissed in case an activity above
+ // the overlay is dismissed and the overlay is shown unexpectedly.
+ for (final TaskFragmentContainer overlayContainer : overlayContainers) {
+ final boolean isTopNonFinishingOverlay = overlayContainer.isTopNonFinishingChild();
+ final boolean areInSameTask = taskId == overlayContainer.getTaskId();
+ final boolean haveSameTag = overlayTag.equals(overlayContainer.getOverlayTag());
+ if (!associateLaunchingActivity && overlayContainer.isAlwaysOnTopOverlay()
+ && haveSameTag && areInSameTask) {
+ // Just launch the activity and update the existing always-on-top overlay
+ // if the requested overlay is an always-on-top overlay with the same tag
+ // as the existing one.
mPresenter.applyActivityStackAttributes(wct, overlayContainer, attrs,
getMinDimensions(intent));
return overlayContainer;
-
}
+ if (haveSameTag) {
+ // For other tag match, we should clean up the existing overlay since the overlay
+ // tag must be unique per process.
+ Log.w(TAG, "The overlay container with tag:"
+ + overlayContainer.getOverlayTag() + " is dismissed with "
+ + " the launching activity=" + launchActivity
+ + " because there's an existing overlay container with the same tag.");
+ mPresenter.cleanupContainer(wct, overlayContainer,
+ false /* shouldFinishDependant */);
+ }
+ if (!areInSameTask) {
+ // Early return here because we won't clean-up or update overlay from different
+ // tasks except tag collision.
+ continue;
+ }
+ if (associateLaunchingActivity) {
+ // For associated overlay, we only dismiss the overlay if it's the top non-finishing
+ // child of its parent container.
+ if (isTopNonFinishingOverlay) {
+ Log.w(TAG, "The on-top overlay container with tag:"
+ + overlayContainer.getOverlayTag() + " is dismissed with "
+ + " the launching activity=" + launchActivity
+ + "because we only allow one overlay on top.");
+ mPresenter.cleanupContainer(wct, overlayContainer,
+ false /* shouldFinishDependant */);
+ }
+ continue;
+ }
+ // Otherwise, we should clean up the overlay in the task because we only allow one
+ // overlay when an always-on-top overlay is launched.
+ Log.w(TAG, "The overlay container with tag:"
+ + overlayContainer.getOverlayTag() + " is dismissed with "
+ + " the launching activity=" + launchActivity
+ + "because an always-on-top overlay is launched.");
+ mPresenter.cleanupContainer(wct, overlayContainer,
+ false /* shouldFinishDependant */);
}
// Launch the overlay container to the task with taskId.
return createEmptyContainer(wct, intent, taskId, attrs, launchActivity, overlayTag,
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 7173b0c95230..d0e2c998e961 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -340,6 +340,13 @@ class TaskFragmentContainer {
return mInfo != null && mInfo.isVisible();
}
+ /**
+ * See {@link TaskFragmentInfo#isTopNonFinishingChild()}
+ */
+ boolean isTopNonFinishingChild() {
+ return mInfo != null && mInfo.isTopNonFinishingChild();
+ }
+
/** Whether the TaskFragment is in an intermediate state waiting for the server update.*/
boolean isInIntermediateState() {
if (mInfo == null) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index 84984a9f8c7b..a3ef68a15196 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -21,9 +21,9 @@ import static android.view.Display.INVALID_DISPLAY;
import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
-import static androidx.window.util.ExtensionHelper.isZero;
-import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
-import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
+import static androidx.window.common.ExtensionHelper.isZero;
+import static androidx.window.common.ExtensionHelper.rotateRectToDisplayRotation;
+import static androidx.window.common.ExtensionHelper.transformToWindowSpaceRect;
import android.app.Activity;
import android.app.ActivityThread;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index 339908a3a9a4..b63fd0802e5f 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -25,11 +25,11 @@ import android.os.Bundle;
import android.os.IBinder;
import androidx.annotation.NonNull;
+import androidx.window.common.BaseDataProducer;
import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.common.RawFoldingFeatureProducer;
-import androidx.window.util.BaseDataProducer;
import java.util.ArrayList;
import java.util.List;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
index bb6ab47b144d..4fd03e4bdc0b 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
@@ -17,8 +17,8 @@ package androidx.window.sidecar;
import static android.view.Display.DEFAULT_DISPLAY;
-import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
-import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
+import static androidx.window.common.ExtensionHelper.rotateRectToDisplayRotation;
+import static androidx.window.common.ExtensionHelper.transformToWindowSpaceRect;
import android.annotation.NonNull;
import android.app.Activity;
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/util/ExtensionHelperTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/ExtensionHelperTest.java
index 3278cdf1c337..b6e951961a69 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/util/ExtensionHelperTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/ExtensionHelperTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.window.util;
+package androidx.window.common;
import static org.junit.Assert.assertEquals;
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
index d649c6d57137..7dc78fdd601f 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
@@ -163,12 +163,14 @@ public class EmbeddingTestUtils {
}
/** Creates a mock TaskFragmentInfo for the given TaskFragment. */
+ @NonNull
static TaskFragmentInfo createMockTaskFragmentInfo(@NonNull TaskFragmentContainer container,
@NonNull Activity activity) {
return createMockTaskFragmentInfo(container, activity, true /* isVisible */);
}
/** Creates a mock TaskFragmentInfo for the given TaskFragment. */
+ @NonNull
static TaskFragmentInfo createMockTaskFragmentInfo(@NonNull TaskFragmentContainer container,
@NonNull Activity activity, boolean isVisible) {
return new TaskFragmentInfo(container.getTaskFragmentToken(),
@@ -182,7 +184,27 @@ public class EmbeddingTestUtils {
false /* isTaskClearedForReuse */,
false /* isTaskFragmentClearedForPip */,
false /* isClearedForReorderActivityToFront */,
- new Point());
+ new Point(),
+ false /* isTopChild */);
+ }
+
+ /** Creates a mock TaskFragmentInfo for the given TaskFragment. */
+ @NonNull
+ static TaskFragmentInfo createMockTaskFragmentInfo(@NonNull TaskFragmentContainer container,
+ @NonNull Activity activity, boolean isVisible, boolean isOnTop) {
+ return new TaskFragmentInfo(container.getTaskFragmentToken(),
+ mock(WindowContainerToken.class),
+ new Configuration(),
+ 1,
+ isVisible,
+ Collections.singletonList(activity.getActivityToken()),
+ new ArrayList<>(),
+ new Point(),
+ false /* isTaskClearedForReuse */,
+ false /* isTaskFragmentClearedForPip */,
+ false /* isClearedForReorderActivityToFront */,
+ new Point(),
+ isOnTop);
}
static ActivityInfo createActivityInfoWithMinDimensions() {
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
index ad41b18dcbc6..8911d18b9b97 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
@@ -114,6 +114,7 @@ public class JetpackTaskFragmentOrganizerTest {
mock(WindowContainerToken.class), new Configuration(), 0 /* runningActivityCount */,
false /* isVisible */, new ArrayList<>(), new ArrayList<>(), new Point(),
false /* isTaskClearedForReuse */, false /* isTaskFragmentClearedForPip */,
- false /* isClearedForReorderActivityToFront */, new Point());
+ false /* isClearedForReorderActivityToFront */, new Point(),
+ false /* isTopChild */);
}
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 1c4c8870b26f..475475b05272 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -30,6 +30,7 @@ import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSpli
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitPlaceholderRuleBuilder;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTfContainer;
+import static androidx.window.extensions.embedding.SplitController.KEY_OVERLAY_ASSOCIATE_WITH_LAUNCHING_ACTIVITY;
import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_BOTTOM;
import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_LEFT;
import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_RIGHT;
@@ -94,6 +95,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -267,7 +269,7 @@ public class OverlayPresentationTest {
}
@Test
- public void testCreateOrUpdateOverlay_visibleOverlaySameTagInTask_dismissOverlay() {
+ public void testCreateOrUpdateOverlay_topOverlayInTask_dismissOverlay() {
createExistingOverlayContainers();
final TaskFragmentContainer overlayContainer =
@@ -295,26 +297,6 @@ public class OverlayPresentationTest {
}
@Test
- public void testCreateOrUpdateOverlay_sameTagTaskAndActivity_updateOverlay() {
- createExistingOverlayContainers();
-
- final Rect bounds = new Rect(0, 0, 100, 100);
- mSplitController.setActivityStackAttributesCalculator(params ->
- new ActivityStackAttributes.Builder().setRelativeBounds(bounds).build());
- final TaskFragmentContainer overlayContainer = createOrUpdateOverlayTaskFragmentIfNeeded(
- mOverlayContainer1.getOverlayTag());
-
- assertWithMessage("overlayContainer1 must be updated since the new overlay container"
- + " is launched with the same tag and task")
- .that(mSplitController.getAllNonFinishingOverlayContainers())
- .containsExactly(mOverlayContainer1, mOverlayContainer2);
-
- assertThat(overlayContainer).isEqualTo(mOverlayContainer1);
- verify(mSplitPresenter).resizeTaskFragment(eq(mTransaction),
- eq(mOverlayContainer1.getTaskFragmentToken()), eq(bounds));
- }
-
- @Test
public void testCreateOrUpdateOverlay_sameTagAndTaskButNotActivity_dismissOverlay() {
createExistingOverlayContainers();
@@ -362,6 +344,43 @@ public class OverlayPresentationTest {
}
@Test
+ public void testCreateOrUpdateAlwaysOnTopOverlay_dismissMultipleOverlaysInTask() {
+ createExistingOverlayContainers();
+ // Create another overlay in task.
+ final TaskFragmentContainer overlayContainer3 =
+ createTestOverlayContainer(TASK_ID, "test3");
+ assertThat(mSplitController.getAllNonFinishingOverlayContainers())
+ .containsExactly(mOverlayContainer1, mOverlayContainer2, overlayContainer3);
+
+ final TaskFragmentContainer overlayContainer =
+ createOrUpdateAlwaysOnTopOverlay("test4");
+
+ assertWithMessage("overlayContainer1 and overlayContainer3 must be dismissed")
+ .that(mSplitController.getAllNonFinishingOverlayContainers())
+ .containsExactly(mOverlayContainer2, overlayContainer);
+ }
+
+ @Test
+ public void testCreateOrUpdateAlwaysOnTopOverlay_updateOverlay() {
+ createExistingOverlayContainers();
+ // Create another overlay in task.
+ final TaskFragmentContainer alwaysOnTopOverlay = createTestOverlayContainer(TASK_ID,
+ "test3", true /* isVisible */, false /* associateLaunchingActivity */);
+ final ActivityStackAttributes attrs = new ActivityStackAttributes.Builder()
+ .setRelativeBounds(new Rect(0, 0, 100, 100)).build();
+ mSplitController.setActivityStackAttributesCalculator(params -> attrs);
+
+ Mockito.clearInvocations(mSplitPresenter);
+ final TaskFragmentContainer overlayContainer =
+ createOrUpdateAlwaysOnTopOverlay(alwaysOnTopOverlay.getOverlayTag());
+
+ assertWithMessage("overlayContainer1 and overlayContainer3 must be dismissed")
+ .that(mSplitController.getAllNonFinishingOverlayContainers())
+ .containsExactly(mOverlayContainer2, alwaysOnTopOverlay);
+ assertThat(overlayContainer).isEqualTo(alwaysOnTopOverlay);
+ }
+
+ @Test
public void testCreateOrUpdateOverlay_launchFromSplit_returnNull() {
final Activity primaryActivity = createMockActivity();
final Activity secondaryActivity = createMockActivity();
@@ -381,13 +400,13 @@ public class OverlayPresentationTest {
}
private void createExistingOverlayContainers() {
- createExistingOverlayContainers(true /* visible */);
+ createExistingOverlayContainers(true /* isOnTop */);
}
- private void createExistingOverlayContainers(boolean visible) {
- mOverlayContainer1 = createTestOverlayContainer(TASK_ID, "test1", visible,
+ private void createExistingOverlayContainers(boolean isOnTop) {
+ mOverlayContainer1 = createTestOverlayContainer(TASK_ID, "test1", isOnTop,
true /* associatedLaunchingActivity */, mActivity);
- mOverlayContainer2 = createTestOverlayContainer(TASK_ID + 1, "test2", visible);
+ mOverlayContainer2 = createTestOverlayContainer(TASK_ID + 1, "test2", isOnTop);
List<TaskFragmentContainer> overlayContainers = mSplitController
.getAllNonFinishingOverlayContainers();
assertThat(overlayContainers).containsExactly(mOverlayContainer1, mOverlayContainer2);
@@ -966,6 +985,16 @@ public class OverlayPresentationTest {
launchOptions, mIntent, activity);
}
+ @Nullable
+ private TaskFragmentContainer createOrUpdateAlwaysOnTopOverlay(
+ @NonNull String tag) {
+ final Bundle launchOptions = new Bundle();
+ launchOptions.putBoolean(KEY_OVERLAY_ASSOCIATE_WITH_LAUNCHING_ACTIVITY, false);
+ launchOptions.putString(KEY_OVERLAY_TAG, tag);
+ return mSplitController.createOrUpdateOverlayTaskFragmentIfNeeded(mTransaction,
+ launchOptions, mIntent, createMockActivity());
+ }
+
/** Creates a mock TaskFragment that has been registered and appeared in the organizer. */
@NonNull
private TaskFragmentContainer createMockTaskFragmentContainer(@NonNull Activity activity) {
@@ -975,10 +1004,10 @@ public class OverlayPresentationTest {
/** Creates a mock TaskFragment that has been registered and appeared in the organizer. */
@NonNull
private TaskFragmentContainer createMockTaskFragmentContainer(
- @NonNull Activity activity, boolean isVisible) {
+ @NonNull Activity activity, boolean isOnTop) {
final TaskFragmentContainer container = createTfContainer(mSplitController,
activity.getTaskId(), activity);
- setupTaskFragmentInfo(container, activity, isVisible);
+ setupTaskFragmentInfo(container, activity, isOnTop);
return container;
}
@@ -990,8 +1019,8 @@ public class OverlayPresentationTest {
@NonNull
private TaskFragmentContainer createTestOverlayContainer(int taskId, @NonNull String tag,
- boolean isVisible) {
- return createTestOverlayContainer(taskId, tag, isVisible,
+ boolean isOnTop) {
+ return createTestOverlayContainer(taskId, tag, isOnTop,
true /* associateLaunchingActivity */);
}
@@ -1002,11 +1031,9 @@ public class OverlayPresentationTest {
null /* launchingActivity */);
}
- // TODO(b/243518738): add more test coverage on overlay container without activity association
- // once we have use cases.
@NonNull
private TaskFragmentContainer createTestOverlayContainer(int taskId, @NonNull String tag,
- boolean isVisible, boolean associateLaunchingActivity,
+ boolean isOnTop, boolean associateLaunchingActivity,
@Nullable Activity launchingActivity) {
final Activity activity = launchingActivity != null
? launchingActivity : createMockActivity();
@@ -1017,14 +1044,15 @@ public class OverlayPresentationTest {
.setLaunchOptions(Bundle.EMPTY)
.setAssociatedActivity(associateLaunchingActivity ? activity : null)
.build();
- setupTaskFragmentInfo(overlayContainer, createMockActivity(), isVisible);
+ setupTaskFragmentInfo(overlayContainer, createMockActivity(), isOnTop);
return overlayContainer;
}
private void setupTaskFragmentInfo(@NonNull TaskFragmentContainer container,
@NonNull Activity activity,
- boolean isVisible) {
- final TaskFragmentInfo info = createMockTaskFragmentInfo(container, activity, isVisible);
+ boolean isOnTop) {
+ final TaskFragmentInfo info = createMockTaskFragmentInfo(container, activity, isOnTop,
+ isOnTop);
container.setInfo(mTransaction, info);
mSplitPresenter.mFragmentInfos.put(container.getTaskFragmentToken(), info);
}
diff --git a/libs/WindowManager/Shell/res/layout/compat_ui_layout.xml b/libs/WindowManager/Shell/res/layout/compat_ui_layout.xml
index 257fe1544bbb..62782a784db9 100644
--- a/libs/WindowManager/Shell/res/layout/compat_ui_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/compat_ui_layout.xml
@@ -21,38 +21,6 @@
android:orientation="vertical"
android:gravity="bottom|end">
- <include android:id="@+id/camera_compat_hint"
- android:visibility="gone"
- android:layout_width="@dimen/camera_compat_hint_width"
- android:layout_height="wrap_content"
- layout="@layout/compat_mode_hint"/>
-
- <LinearLayout
- android:id="@+id/camera_compat_control"
- android:visibility="gone"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:clipToPadding="false"
- android:layout_marginEnd="@dimen/compat_button_margin"
- android:layout_marginBottom="@dimen/compat_button_margin"
- android:orientation="vertical">
-
- <ImageButton
- android:id="@+id/camera_compat_treatment_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@android:color/transparent"/>
-
- <ImageButton
- android:id="@+id/camera_compat_dismiss_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/camera_compat_dismiss_ripple"
- android:background="@android:color/transparent"
- android:contentDescription="@string/camera_compat_dismiss_button_description"/>
-
- </LinearLayout>
-
<include android:id="@+id/size_compat_hint"
android:visibility="gone"
android:layout_width="@dimen/compat_hint_width"
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index e476db050f01..e58ff6aa331e 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Maak klein"</string>
<string name="close_button_text" msgid="2913281996024033299">"Maak toe"</string>
<string name="back_button_text" msgid="1469718707134137085">"Terug"</string>
- <string name="handle_text" msgid="1766582106752184456">"Handvatsel"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Apphandvatsel"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikoon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Volskerm"</string>
<string name="desktop_text" msgid="1077633567027630454">"Rekenaarmodus"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 33fea2bcdde5..3208ea9bea61 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"አሳንስ"</string>
<string name="close_button_text" msgid="2913281996024033299">"ዝጋ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ተመለስ"</string>
- <string name="handle_text" msgid="1766582106752184456">"መያዣ"</string>
+ <string name="handle_text" msgid="4419667835599523257">"የመተግበሪያ መያዣ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"የመተግበሪያ አዶ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ሙሉ ማያ"</string>
<string name="desktop_text" msgid="1077633567027630454">"የዴስክቶፕ ሁነታ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index b014c3ba7d77..18db50ecdadd 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"تصغير"</string>
<string name="close_button_text" msgid="2913281996024033299">"إغلاق"</string>
<string name="back_button_text" msgid="1469718707134137085">"رجوع"</string>
- <string name="handle_text" msgid="1766582106752184456">"مقبض"</string>
+ <string name="handle_text" msgid="4419667835599523257">"مقبض التطبيق"</string>
<string name="app_icon_text" msgid="2823268023931811747">"رمز التطبيق"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ملء الشاشة"</string>
<string name="desktop_text" msgid="1077633567027630454">"وضع سطح المكتب"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index b94ab2e73e9c..195177230419 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"মিনিমাইজ কৰক"</string>
<string name="close_button_text" msgid="2913281996024033299">"বন্ধ কৰক"</string>
<string name="back_button_text" msgid="1469718707134137085">"উভতি যাওক"</string>
- <string name="handle_text" msgid="1766582106752184456">"হেণ্ডেল"</string>
+ <string name="handle_text" msgid="4419667835599523257">"এপৰ হেণ্ডেল"</string>
<string name="app_icon_text" msgid="2823268023931811747">"এপৰ চিহ্ন"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"সম্পূৰ্ণ স্ক্ৰীন"</string>
<string name="desktop_text" msgid="1077633567027630454">"ডেস্কটপ ম’ড"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 9ec44a1e6325..32e0dd698571 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Kiçildin"</string>
<string name="close_button_text" msgid="2913281996024033299">"Bağlayın"</string>
<string name="back_button_text" msgid="1469718707134137085">"Geriyə"</string>
- <string name="handle_text" msgid="1766582106752184456">"Hər kəsə açıq istifadəçi adı"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Tətbiq ləqəbi"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Tətbiq ikonası"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
<string name="desktop_text" msgid="1077633567027630454">"Masaüstü Rejimi"</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index af695e73161d..1656e02b476a 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Umanjite"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zatvorite"</string>
<string name="back_button_text" msgid="1469718707134137085">"Nazad"</string>
- <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Preko celog ekrana"</string>
<string name="desktop_text" msgid="1077633567027630454">"Režim za računare"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index dbbc07fe2407..26f3d3ce85e3 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Згарнуць"</string>
<string name="close_button_text" msgid="2913281996024033299">"Закрыць"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
- <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Маркер праграмы"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок праграмы"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"На ўвесь экран"</string>
<string name="desktop_text" msgid="1077633567027630454">"Рэжым працоўнага стала"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 8dc791501b1b..7c4f25efb7e3 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Намаляване"</string>
<string name="close_button_text" msgid="2913281996024033299">"Затваряне"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
- <string name="handle_text" msgid="1766582106752184456">"Манипулатор"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Манипулатор за приложението"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона на приложението"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Цял екран"</string>
<string name="desktop_text" msgid="1077633567027630454">"Режим за настолни компютри"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 61294ada298e..4286162c0c87 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"ছোট করুন"</string>
<string name="close_button_text" msgid="2913281996024033299">"বন্ধ করুন"</string>
<string name="back_button_text" msgid="1469718707134137085">"ফিরে যান"</string>
- <string name="handle_text" msgid="1766582106752184456">"হাতল"</string>
+ <string name="handle_text" msgid="4419667835599523257">"অ্যাপের হ্যান্ডেল"</string>
<string name="app_icon_text" msgid="2823268023931811747">"অ্যাপ আইকন"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ফুলস্ক্রিন"</string>
<string name="desktop_text" msgid="1077633567027630454">"ডেস্কটপ মোড"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 676b226ec8c1..11f5e480f7db 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimiziranje"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zatvaranje"</string>
<string name="back_button_text" msgid="1469718707134137085">"Nazad"</string>
- <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Ručica aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Cijeli ekran"</string>
<string name="desktop_text" msgid="1077633567027630454">"Način rada radne površine"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index ce9f54798120..e1fc7d38a527 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimitza"</string>
<string name="close_button_text" msgid="2913281996024033299">"Tanca"</string>
<string name="back_button_text" msgid="1469718707134137085">"Enrere"</string>
- <string name="handle_text" msgid="1766582106752184456">"Ansa"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Identificador de l\'aplicació"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona de l\'aplicació"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
<string name="desktop_text" msgid="1077633567027630454">"Mode d\'escriptori"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index 6b9d85f37f00..e4282105455e 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimalizovat"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zavřít"</string>
<string name="back_button_text" msgid="1469718707134137085">"Zpět"</string>
- <string name="handle_text" msgid="1766582106752184456">"Úchyt"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Popisovač aplikace"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikace"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
<string name="desktop_text" msgid="1077633567027630454">"Režim počítače"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index de7d91943a4d..36c03304a670 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string>
<string name="close_button_text" msgid="2913281996024033299">"Luk"</string>
<string name="back_button_text" msgid="1469718707134137085">"Tilbage"</string>
- <string name="handle_text" msgid="1766582106752184456">"Håndtag"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Apphåndtag"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fuld skærm"</string>
<string name="desktop_text" msgid="1077633567027630454">"Computertilstand"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index e4fd3118293f..0ad112cf87a7 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimieren"</string>
<string name="close_button_text" msgid="2913281996024033299">"Schließen"</string>
<string name="back_button_text" msgid="1469718707134137085">"Zurück"</string>
- <string name="handle_text" msgid="1766582106752184456">"Ziehpunkt"</string>
+ <string name="handle_text" msgid="4419667835599523257">"App-Ziehpunkt"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App-Symbol"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Vollbild"</string>
<string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 964166e16034..1e2fec19c639 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Ελαχιστοποίηση"</string>
<string name="close_button_text" msgid="2913281996024033299">"Κλείσιμο"</string>
<string name="back_button_text" msgid="1469718707134137085">"Πίσω"</string>
- <string name="handle_text" msgid="1766582106752184456">"Λαβή"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Λαβή εφαρμογής"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Εικονίδιο εφαρμογής"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Πλήρης οθόνη"</string>
<string name="desktop_text" msgid="1077633567027630454">"Λειτουργία επιφάνειας εργασίας"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index c17b9f7ad8dc..71701c9a18a1 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string>
<string name="close_button_text" msgid="2913281996024033299">"Close"</string>
<string name="back_button_text" msgid="1469718707134137085">"Back"</string>
- <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+ <string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
<string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index bd8a63690ba3..5ab4af3d1557 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimize"</string>
<string name="close_button_text" msgid="2913281996024033299">"Close"</string>
<string name="back_button_text" msgid="1469718707134137085">"Back"</string>
- <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+ <string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App Icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string>
<string name="desktop_text" msgid="1077633567027630454">"Desktop Mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index c17b9f7ad8dc..71701c9a18a1 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string>
<string name="close_button_text" msgid="2913281996024033299">"Close"</string>
<string name="back_button_text" msgid="1469718707134137085">"Back"</string>
- <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+ <string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
<string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index c17b9f7ad8dc..71701c9a18a1 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string>
<string name="close_button_text" msgid="2913281996024033299">"Close"</string>
<string name="back_button_text" msgid="1469718707134137085">"Back"</string>
- <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+ <string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
<string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index 35030808f4fd..42d5f068927b 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‎Minimize‎‏‎‎‏‎"</string>
<string name="close_button_text" msgid="2913281996024033299">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎Close‎‏‎‎‏‎"</string>
<string name="back_button_text" msgid="1469718707134137085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎‏‎Back‎‏‎‎‏‎"</string>
- <string name="handle_text" msgid="1766582106752184456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎Handle‎‏‎‎‏‎"</string>
+ <string name="handle_text" msgid="4419667835599523257">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‏‎App handle‎‏‎‎‏‎"</string>
<string name="app_icon_text" msgid="2823268023931811747">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‏‏‎App Icon‎‏‎‎‏‎"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎Fullscreen‎‏‎‎‏‎"</string>
<string name="desktop_text" msgid="1077633567027630454">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎Desktop Mode‎‏‎‎‏‎"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 049649f0c748..1e3091295460 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
<string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
- <string name="handle_text" msgid="1766582106752184456">"Controlador"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Controlador de la app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícono de la app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
<string name="desktop_text" msgid="1077633567027630454">"Modo de escritorio"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 77413186228d..312e2977b4c3 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
<string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
- <string name="handle_text" msgid="1766582106752184456">"Controlador"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Controlador de la aplicación"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icono de la aplicación"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
<string name="desktop_text" msgid="1077633567027630454">"Modo Escritorio"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 29fc150fd229..5e4ef81c7795 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimeeri"</string>
<string name="close_button_text" msgid="2913281996024033299">"Sule"</string>
<string name="back_button_text" msgid="1469718707134137085">"Tagasi"</string>
- <string name="handle_text" msgid="1766582106752184456">"Käepide"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Rakenduse element"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Rakenduse ikoon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Täisekraan"</string>
<string name="desktop_text" msgid="1077633567027630454">"Lauaarvuti režiim"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 580f6e1cd875..40d67a2a9a9d 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizatu"</string>
<string name="close_button_text" msgid="2913281996024033299">"Itxi"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atzera"</string>
- <string name="handle_text" msgid="1766582106752184456">"Kontu-izena"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Aplikazioaren kontrol-puntua"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aplikazioaren ikonoa"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantaila osoa"</string>
<string name="desktop_text" msgid="1077633567027630454">"Ordenagailuetarako modua"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 766e78734fbc..55da319031e3 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"کوچک کردن"</string>
<string name="close_button_text" msgid="2913281996024033299">"بستن"</string>
<string name="back_button_text" msgid="1469718707134137085">"برگشتن"</string>
- <string name="handle_text" msgid="1766582106752184456">"دستگیره"</string>
+ <string name="handle_text" msgid="4419667835599523257">"دستگیره برنامه"</string>
<string name="app_icon_text" msgid="2823268023931811747">"نماد برنامه"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"تمام‌صفحه"</string>
<string name="desktop_text" msgid="1077633567027630454">"حالت رایانه"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 96c7b7504724..c2610ff182f2 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Pienennä"</string>
<string name="close_button_text" msgid="2913281996024033299">"Sulje"</string>
<string name="back_button_text" msgid="1469718707134137085">"Takaisin"</string>
- <string name="handle_text" msgid="1766582106752184456">"Kahva"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Sovelluksen tunnus"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Sovelluskuvake"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Koko näyttö"</string>
<string name="desktop_text" msgid="1077633567027630454">"Työpöytätila"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index e54e59d279fd..7a59b62812b9 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string>
<string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
<string name="back_button_text" msgid="1469718707134137085">"Retour"</string>
- <string name="handle_text" msgid="1766582106752184456">"Identifiant"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'appli"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
<string name="desktop_text" msgid="1077633567027630454">"Mode Bureau"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index d150ad7e89f5..0cf944fca1e6 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string>
<string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
<string name="back_button_text" msgid="1469718707134137085">"Retour"</string>
- <string name="handle_text" msgid="1766582106752184456">"Poignée"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icône d\'application"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
<string name="desktop_text" msgid="1077633567027630454">"Mode ordinateur"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 6429fb31acd7..0f2a6010c860 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
<string name="close_button_text" msgid="2913281996024033299">"Pechar"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
- <string name="handle_text" msgid="1766582106752184456">"Controlador"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Controlador da aplicación"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona de aplicación"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
<string name="desktop_text" msgid="1077633567027630454">"Modo de escritorio"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index f8bdfaeccc15..6151da03797c 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"નાનું કરો"</string>
<string name="close_button_text" msgid="2913281996024033299">"બંધ કરો"</string>
<string name="back_button_text" msgid="1469718707134137085">"પાછળ"</string>
- <string name="handle_text" msgid="1766582106752184456">"હૅન્ડલ"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ઍપનું હૅન્ડલ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ઍપનું આઇકન"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"પૂર્ણસ્ક્રીન"</string>
<string name="desktop_text" msgid="1077633567027630454">"ડેસ્કટૉપ મોડ"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index d7c380387509..04e76bc5bed3 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"विंडो छोटी करें"</string>
<string name="close_button_text" msgid="2913281996024033299">"बंद करें"</string>
<string name="back_button_text" msgid="1469718707134137085">"वापस जाएं"</string>
- <string name="handle_text" msgid="1766582106752184456">"हैंडल"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ऐप्लिकेशन का हैंडल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ऐप्लिकेशन आइकॉन"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"फ़ुलस्क्रीन"</string>
<string name="desktop_text" msgid="1077633567027630454">"डेस्कटॉप मोड"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 000b0e63bf8e..aa2ee17a157f 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimiziraj"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zatvori"</string>
<string name="back_button_text" msgid="1469718707134137085">"Natrag"</string>
- <string name="handle_text" msgid="1766582106752184456">"Pokazivač"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Pokazivač aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Puni zaslon"</string>
<string name="desktop_text" msgid="1077633567027630454">"Stolni način rada"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index b1268cc849ab..8ffeeed1b1f3 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Kis méret"</string>
<string name="close_button_text" msgid="2913281996024033299">"Bezárás"</string>
<string name="back_button_text" msgid="1469718707134137085">"Vissza"</string>
- <string name="handle_text" msgid="1766582106752184456">"Fogópont"</string>
+ <string name="handle_text" msgid="4419667835599523257">"App fogópontja"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Alkalmazásikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Teljes képernyő"</string>
<string name="desktop_text" msgid="1077633567027630454">"Asztali üzemmód"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 1d2d2ff76912..b3fccfaa93f1 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Ծալել"</string>
<string name="close_button_text" msgid="2913281996024033299">"Փակել"</string>
<string name="back_button_text" msgid="1469718707134137085">"Հետ"</string>
- <string name="handle_text" msgid="1766582106752184456">"Նշիչ"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Հավելվածի կեղծանուն"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Հավելվածի պատկերակ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Լիաէկրան"</string>
<string name="desktop_text" msgid="1077633567027630454">"Համակարգչի ռեժիմ"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 17e91050584d..38b24f92b76d 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimalkan"</string>
<string name="close_button_text" msgid="2913281996024033299">"Tutup"</string>
<string name="back_button_text" msgid="1469718707134137085">"Kembali"</string>
- <string name="handle_text" msgid="1766582106752184456">"Tuas"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Penanganan aplikasi"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikon Aplikasi"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Layar Penuh"</string>
<string name="desktop_text" msgid="1077633567027630454">"Mode Desktop"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index b955ef89759f..5b1f4d2205f7 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minnka"</string>
<string name="close_button_text" msgid="2913281996024033299">"Loka"</string>
<string name="back_button_text" msgid="1469718707134137085">"Til baka"</string>
- <string name="handle_text" msgid="1766582106752184456">"Handfang"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Handfang forrits"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Tákn forrits"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Allur skjárinn"</string>
<string name="desktop_text" msgid="1077633567027630454">"Skjáborðsstilling"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index d33e770f8199..adc9569b0afe 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Riduci a icona"</string>
<string name="close_button_text" msgid="2913281996024033299">"Chiudi"</string>
<string name="back_button_text" msgid="1469718707134137085">"Indietro"</string>
- <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Punto di manipolazione app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona dell\'app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Schermo intero"</string>
<string name="desktop_text" msgid="1077633567027630454">"Modalità desktop"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 6ebbc81046bf..9bae1c970b97 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"מזעור"</string>
<string name="close_button_text" msgid="2913281996024033299">"סגירה"</string>
<string name="back_button_text" msgid="1469718707134137085">"חזרה"</string>
- <string name="handle_text" msgid="1766582106752184456">"נקודת אחיזה"</string>
+ <string name="handle_text" msgid="4419667835599523257">"נקודת אחיזה לאפליקציה"</string>
<string name="app_icon_text" msgid="2823268023931811747">"סמל האפליקציה"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"מסך מלא"</string>
<string name="desktop_text" msgid="1077633567027630454">"ממשק המחשב"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 55fd8b16f2a2..fff794eda59b 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"最小化"</string>
<string name="close_button_text" msgid="2913281996024033299">"閉じる"</string>
<string name="back_button_text" msgid="1469718707134137085">"戻る"</string>
- <string name="handle_text" msgid="1766582106752184456">"ハンドル"</string>
+ <string name="handle_text" msgid="4419667835599523257">"アプリハンドル"</string>
<string name="app_icon_text" msgid="2823268023931811747">"アプリのアイコン"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全画面表示"</string>
<string name="desktop_text" msgid="1077633567027630454">"デスクトップ モード"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 235420812937..a73c4f0f9cff 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"ჩაკეცვა"</string>
<string name="close_button_text" msgid="2913281996024033299">"დახურვა"</string>
<string name="back_button_text" msgid="1469718707134137085">"უკან"</string>
- <string name="handle_text" msgid="1766582106752184456">"იდენტიფიკატორი"</string>
+ <string name="handle_text" msgid="4419667835599523257">"აპის იდენტიფიკატორი"</string>
<string name="app_icon_text" msgid="2823268023931811747">"აპის ხატულა"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"სრულ ეკრანზე"</string>
<string name="desktop_text" msgid="1077633567027630454">"დესკტოპის რეჟიმი"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 3e9b85ecd3a3..5a7197e08942 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Кішірейту"</string>
<string name="close_button_text" msgid="2913281996024033299">"Жабу"</string>
<string name="back_button_text" msgid="1469718707134137085">"Артқа"</string>
- <string name="handle_text" msgid="1766582106752184456">"Идентификатор"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Қолданба идентификаторы"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Қолданба белгішесі"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Толық экран"</string>
<string name="desktop_text" msgid="1077633567027630454">"Компьютер режимі"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 69c0e1eabc05..4db7aeaae457 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"បង្រួម"</string>
<string name="close_button_text" msgid="2913281996024033299">"បិទ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ថយក្រោយ"</string>
- <string name="handle_text" msgid="1766582106752184456">"ឈ្មោះអ្នកប្រើប្រាស់"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ឈ្មោះអ្នកប្រើប្រាស់កម្មវិធី"</string>
<string name="app_icon_text" msgid="2823268023931811747">"រូប​កម្មវិធី"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"អេក្រង់​ពេញ"</string>
<string name="desktop_text" msgid="1077633567027630454">"មុខងារកុំព្យូទ័រ"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 88a29df525e9..5615afcf55f8 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"ಕುಗ್ಗಿಸಿ"</string>
<string name="close_button_text" msgid="2913281996024033299">"ಮುಚ್ಚಿರಿ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ಹಿಂದಕ್ಕೆ"</string>
- <string name="handle_text" msgid="1766582106752184456">"ಹ್ಯಾಂಡಲ್"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ಆ್ಯಪ್ ಹ್ಯಾಂಡಲ್"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ಆ್ಯಪ್ ಐಕಾನ್"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ಫುಲ್‌ಸ್ಕ್ರೀನ್"</string>
<string name="desktop_text" msgid="1077633567027630454">"ಡೆಸ್ಕ್‌ಟಾಪ್ ಮೋಡ್"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 0f27080d65cd..33b980d40a6c 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"최소화"</string>
<string name="close_button_text" msgid="2913281996024033299">"닫기"</string>
<string name="back_button_text" msgid="1469718707134137085">"뒤로"</string>
- <string name="handle_text" msgid="1766582106752184456">"핸들"</string>
+ <string name="handle_text" msgid="4419667835599523257">"앱 핸들"</string>
<string name="app_icon_text" msgid="2823268023931811747">"앱 아이콘"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"전체 화면"</string>
<string name="desktop_text" msgid="1077633567027630454">"데스크톱 모드"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 289d930ecedd..bf3ca5255a80 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Кичирейтүү"</string>
<string name="close_button_text" msgid="2913281996024033299">"Жабуу"</string>
<string name="back_button_text" msgid="1469718707134137085">"Артка"</string>
- <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Колдонмонун маркери"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Колдонмонун сүрөтчөсү"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Толук экран"</string>
<string name="desktop_text" msgid="1077633567027630454">"Компьютер режими"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 0b84d2c45957..ac6fa0085785 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"ຫຍໍ້ລົງ"</string>
<string name="close_button_text" msgid="2913281996024033299">"ປິດ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ກັບຄືນ"</string>
- <string name="handle_text" msgid="1766582106752184456">"ມືບັງຄັບ"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ຊື່ຜູ້ໃຊ້ແອັບ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ໄອຄອນແອັບ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ເຕັມຈໍ"</string>
<string name="desktop_text" msgid="1077633567027630454">"ໂໝດເດັສທັອບ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 21dbb68c8c04..97b53d343dd8 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Sumažinti"</string>
<string name="close_button_text" msgid="2913281996024033299">"Uždaryti"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atgal"</string>
- <string name="handle_text" msgid="1766582106752184456">"Rankenėlė"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Programos kreipinys"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Programos piktograma"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Visas ekranas"</string>
<string name="desktop_text" msgid="1077633567027630454">"Stalinio kompiuterio režimas"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index f988c14605c4..3a7e90a9da21 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizēt"</string>
<string name="close_button_text" msgid="2913281996024033299">"Aizvērt"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atpakaļ"</string>
- <string name="handle_text" msgid="1766582106752184456">"Turis"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Lietotnes turis"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Lietotnes ikona"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pilnekrāna režīms"</string>
<string name="desktop_text" msgid="1077633567027630454">"Darbvirsmas režīms"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index ce34b9749e80..f7867cecdfae 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Минимизирај"</string>
<string name="close_button_text" msgid="2913281996024033299">"Затвори"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
- <string name="handle_text" msgid="1766582106752184456">"Прекар"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Прекар на апликацијата"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона на апликацијата"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Цел екран"</string>
<string name="desktop_text" msgid="1077633567027630454">"Режим за компјутер"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 2efd983b3342..68ff07474778 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"ചെറുതാക്കുക"</string>
<string name="close_button_text" msgid="2913281996024033299">"അടയ്ക്കുക"</string>
<string name="back_button_text" msgid="1469718707134137085">"മടങ്ങുക"</string>
- <string name="handle_text" msgid="1766582106752184456">"ഹാൻഡിൽ"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ആപ്പ് ഹാൻഡിൽ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ആപ്പ് ഐക്കൺ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"പൂർണ്ണസ്ക്രീൻ"</string>
<string name="desktop_text" msgid="1077633567027630454">"ഡെസ്‌ക്ടോപ്പ് മോഡ്"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index de58ed89864e..27b38bc283f9 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Багасгах"</string>
<string name="close_button_text" msgid="2913281996024033299">"Хаах"</string>
<string name="back_button_text" msgid="1469718707134137085">"Буцах"</string>
- <string name="handle_text" msgid="1766582106752184456">"Бариул"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Аппын бариул"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aппын дүрс тэмдэг"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Бүтэн дэлгэц"</string>
<string name="desktop_text" msgid="1077633567027630454">"Дэлгэцийн горим"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index ef71e864a809..f57f06375be9 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"लहान करा"</string>
<string name="close_button_text" msgid="2913281996024033299">"बंद करा"</string>
<string name="back_button_text" msgid="1469718707134137085">"मागे जा"</string>
- <string name="handle_text" msgid="1766582106752184456">"हँडल"</string>
+ <string name="handle_text" msgid="4419667835599523257">"अ‍ॅपचे हँडल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"अ‍ॅप आयकन"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"फुलस्‍क्रीन"</string>
<string name="desktop_text" msgid="1077633567027630454">"डेस्कटॉप मोड"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index a9a97d8112c6..9c3b8716c7e6 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimumkan"</string>
<string name="close_button_text" msgid="2913281996024033299">"Tutup"</string>
<string name="back_button_text" msgid="1469718707134137085">"Kembali"</string>
- <string name="handle_text" msgid="1766582106752184456">"Pemegang"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Pengendalian apl"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikon Apl"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Skrin penuh"</string>
<string name="desktop_text" msgid="1077633567027630454">"Mod Desktop"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 2f313cfe7e26..2685c56a246c 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"ချုံ့ရန်"</string>
<string name="close_button_text" msgid="2913281996024033299">"ပိတ်ရန်"</string>
<string name="back_button_text" msgid="1469718707134137085">"နောက်သို့"</string>
- <string name="handle_text" msgid="1766582106752184456">"သုံးသူအမည်"</string>
+ <string name="handle_text" msgid="4419667835599523257">"အက်ပ်သုံးသူအမည်"</string>
<string name="app_icon_text" msgid="2823268023931811747">"အက်ပ်သင်္ကေတ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ဖန်သားပြင်အပြည့်"</string>
<string name="desktop_text" msgid="1077633567027630454">"ဒက်စ်တော့မုဒ်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 11a807b73054..36c0b8b9febd 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string>
<string name="close_button_text" msgid="2913281996024033299">"Lukk"</string>
<string name="back_button_text" msgid="1469718707134137085">"Tilbake"</string>
- <string name="handle_text" msgid="1766582106752184456">"Håndtak"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Apphåndtak"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fullskjerm"</string>
<string name="desktop_text" msgid="1077633567027630454">"Skrivebordmodus"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 7cc4a437905b..4e96f5f5a0fb 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"मिनिमाइज गर्नुहोस्"</string>
<string name="close_button_text" msgid="2913281996024033299">"बन्द गर्नुहोस्"</string>
<string name="back_button_text" msgid="1469718707134137085">"पछाडि"</string>
- <string name="handle_text" msgid="1766582106752184456">"ह्यान्डल"</string>
+ <string name="handle_text" msgid="4419667835599523257">"एपको ह्यान्डल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"एपको आइकन"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"फुल स्क्रिन"</string>
<string name="desktop_text" msgid="1077633567027630454">"डेस्कटप मोड"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 7480add2ab0a..5ae084a7021a 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimaliseren"</string>
<string name="close_button_text" msgid="2913281996024033299">"Sluiten"</string>
<string name="back_button_text" msgid="1469718707134137085">"Terug"</string>
- <string name="handle_text" msgid="1766582106752184456">"Gebruikersnaam"</string>
+ <string name="handle_text" msgid="4419667835599523257">"App-handgreep"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App-icoon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Volledig scherm"</string>
<string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index b3b5e7cd6955..536c6fe18f94 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"ଛୋଟ କରନ୍ତୁ"</string>
<string name="close_button_text" msgid="2913281996024033299">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ପଛକୁ ଫେରନ୍ତୁ"</string>
- <string name="handle_text" msgid="1766582106752184456">"ହେଣ୍ଡେଲ"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ଆପର ହେଣ୍ଡେଲ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ଆପ ଆଇକନ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ପୂର୍ଣ୍ଣସ୍କ୍ରିନ"</string>
<string name="desktop_text" msgid="1077633567027630454">"ଡେସ୍କଟପ ମୋଡ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 4a08f6762673..bdef224e99b4 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"ਛੋਟਾ ਕਰੋ"</string>
<string name="close_button_text" msgid="2913281996024033299">"ਬੰਦ ਕਰੋ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ਪਿੱਛੇ"</string>
- <string name="handle_text" msgid="1766582106752184456">"ਹੈਂਡਲ"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ਐਪ ਹੈਂਡਲ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ਐਪ ਪ੍ਰਤੀਕ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ਪੂਰੀ-ਸਕ੍ਰੀਨ"</string>
<string name="desktop_text" msgid="1077633567027630454">"ਡੈਸਕਟਾਪ ਮੋਡ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 1c268bd34d55..41c4bb08a29a 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimalizuj"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zamknij"</string>
<string name="back_button_text" msgid="1469718707134137085">"Wstecz"</string>
- <string name="handle_text" msgid="1766582106752184456">"Uchwyt"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Uchwyt aplikacji"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacji"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pełny ekran"</string>
<string name="desktop_text" msgid="1077633567027630454">"Tryb pulpitu"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 82566fedf890..83d34c04cbfd 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
<string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
<string name="back_button_text" msgid="1469718707134137085">"Voltar"</string>
- <string name="handle_text" msgid="1766582106752184456">"Alça"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Identificador do app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string>
<string name="desktop_text" msgid="1077633567027630454">"Modo área de trabalho"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index b2e89182ace4..425ad052aeca 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
<string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
<string name="back_button_text" msgid="1469718707134137085">"Anterior"</string>
- <string name="handle_text" msgid="1766582106752184456">"Indicador"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Indicador da app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone da app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ecrã inteiro"</string>
<string name="desktop_text" msgid="1077633567027630454">"Modo de ambiente de trabalho"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 82566fedf890..83d34c04cbfd 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
<string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
<string name="back_button_text" msgid="1469718707134137085">"Voltar"</string>
- <string name="handle_text" msgid="1766582106752184456">"Alça"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Identificador do app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string>
<string name="desktop_text" msgid="1077633567027630454">"Modo área de trabalho"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 503f68c99c38..ea1a6b7f1422 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizează"</string>
<string name="close_button_text" msgid="2913281996024033299">"Închide"</string>
<string name="back_button_text" msgid="1469718707134137085">"Înapoi"</string>
- <string name="handle_text" msgid="1766582106752184456">"Ghidaj"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Handle de aplicație"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Pictograma aplicației"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ecran complet"</string>
<string name="desktop_text" msgid="1077633567027630454">"Modul desktop"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index b2a60302bd1a..d0292beb27bf 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Свернуть"</string>
<string name="close_button_text" msgid="2913281996024033299">"Закрыть"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
- <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Обозначение приложения"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок приложения"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Полноэкранный режим"</string>
<string name="desktop_text" msgid="1077633567027630454">"Режим компьютера"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 8589f42dd125..7994222d4913 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"කුඩා කරන්න"</string>
<string name="close_button_text" msgid="2913281996024033299">"වසන්න"</string>
<string name="back_button_text" msgid="1469718707134137085">"ආපසු"</string>
- <string name="handle_text" msgid="1766582106752184456">"හැඬලය"</string>
+ <string name="handle_text" msgid="4419667835599523257">"යෙදුම් හසුරුව"</string>
<string name="app_icon_text" msgid="2823268023931811747">"යෙදුම් නිරූපකය"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"පූර්ණ තිරය"</string>
<string name="desktop_text" msgid="1077633567027630454">"ඩෙස්ක්ටොප් ප්‍රකාරය"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 895974462576..896a85b477da 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimalizovať"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zavrieť"</string>
<string name="back_button_text" msgid="1469718707134137085">"Späť"</string>
- <string name="handle_text" msgid="1766582106752184456">"Rukoväť"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Rukoväť aplikácie"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikácie"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
<string name="desktop_text" msgid="1077633567027630454">"Režim počítača"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 5848f9261d9b..3418c483508d 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimiraj"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zapri"</string>
<string name="back_button_text" msgid="1469718707134137085">"Nazaj"</string>
- <string name="handle_text" msgid="1766582106752184456">"Ročica"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Celozaslonsko"</string>
<string name="desktop_text" msgid="1077633567027630454">"Namizni način"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 406389465aa0..306fcaa5191c 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimizo"</string>
<string name="close_button_text" msgid="2913281996024033299">"Mbyll"</string>
<string name="back_button_text" msgid="1469718707134137085">"Pas"</string>
- <string name="handle_text" msgid="1766582106752184456">"Emërtimi"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Emërtimi i aplikacionit"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona e aplikacionit"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ekrani i plotë"</string>
<string name="desktop_text" msgid="1077633567027630454">"Modaliteti i desktopit"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 8402eef99c38..8fd824ec0d1c 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Умањите"</string>
<string name="close_button_text" msgid="2913281996024033299">"Затворите"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
- <string name="handle_text" msgid="1766582106752184456">"Идентификатор"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Идентификатор апликације"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона апликације"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Преко целог екрана"</string>
<string name="desktop_text" msgid="1077633567027630454">"Режим за рачунаре"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 77c7d09fdb24..b6375c69f0dc 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Minimera"</string>
<string name="close_button_text" msgid="2913281996024033299">"Stäng"</string>
<string name="back_button_text" msgid="1469718707134137085">"Tillbaka"</string>
- <string name="handle_text" msgid="1766582106752184456">"Handtag"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Apphandtag"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Helskärm"</string>
<string name="desktop_text" msgid="1077633567027630454">"Datorläge"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index d367c80c7197..2eadf34f5197 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Punguza"</string>
<string name="close_button_text" msgid="2913281996024033299">"Funga"</string>
<string name="back_button_text" msgid="1469718707134137085">"Rudi nyuma"</string>
- <string name="handle_text" msgid="1766582106752184456">"Ncha"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Utambulisho wa programu"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aikoni ya Programu"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Skrini nzima"</string>
<string name="desktop_text" msgid="1077633567027630454">"Hali ya Kompyuta ya mezani"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 697f9519688f..36f69ce02515 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"சிறிதாக்கும்"</string>
<string name="close_button_text" msgid="2913281996024033299">"மூடும்"</string>
<string name="back_button_text" msgid="1469718707134137085">"பின்செல்லும்"</string>
- <string name="handle_text" msgid="1766582106752184456">"ஹேண்டில்"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ஆப்ஸ் ஹேண்டில்"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ஆப்ஸ் ஐகான்"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"முழுத்திரை"</string>
<string name="desktop_text" msgid="1077633567027630454">"டெஸ்க்டாப் பயன்முறை"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index ef094fcc8e64..2446ae8f58e6 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"కుదించండి"</string>
<string name="close_button_text" msgid="2913281996024033299">"మూసివేయండి"</string>
<string name="back_button_text" msgid="1469718707134137085">"వెనుకకు"</string>
- <string name="handle_text" msgid="1766582106752184456">"హ్యాండిల్"</string>
+ <string name="handle_text" msgid="4419667835599523257">"యాప్ హ్యాండిల్"</string>
<string name="app_icon_text" msgid="2823268023931811747">"యాప్ చిహ్నం"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ఫుల్-స్క్రీన్"</string>
<string name="desktop_text" msgid="1077633567027630454">"డెస్క్‌టాప్ మోడ్"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 762a81a0305a..10cf216064a2 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"ย่อ"</string>
<string name="close_button_text" msgid="2913281996024033299">"ปิด"</string>
<string name="back_button_text" msgid="1469718707134137085">"กลับ"</string>
- <string name="handle_text" msgid="1766582106752184456">"แฮนเดิล"</string>
+ <string name="handle_text" msgid="4419667835599523257">"แฮนเดิลแอป"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ไอคอนแอป"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"เต็มหน้าจอ"</string>
<string name="desktop_text" msgid="1077633567027630454">"โหมดเดสก์ท็อป"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 418f500aac80..497ac56b408d 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"I-minimize"</string>
<string name="close_button_text" msgid="2913281996024033299">"Isara"</string>
<string name="back_button_text" msgid="1469718707134137085">"Bumalik"</string>
- <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Handle ng app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icon ng App"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string>
<string name="desktop_text" msgid="1077633567027630454">"Desktop Mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 1a9724079e65..05eb1ba79f2a 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Küçült"</string>
<string name="close_button_text" msgid="2913281996024033299">"Kapat"</string>
<string name="back_button_text" msgid="1469718707134137085">"Geri"</string>
- <string name="handle_text" msgid="1766582106752184456">"Herkese açık kullanıcı adı"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Uygulama tanıtıcısı"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Uygulama Simgesi"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
<string name="desktop_text" msgid="1077633567027630454">"Masaüstü Modu"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index a5fcae5775a0..5c3cfaad4b28 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Згорнути"</string>
<string name="close_button_text" msgid="2913281996024033299">"Закрити"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
- <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Дескриптор додатка"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок додатка"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"На весь екран"</string>
<string name="desktop_text" msgid="1077633567027630454">"Режим комп’ютера"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 2cf9f325892d..98c433b1159f 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"چھوٹا کریں"</string>
<string name="close_button_text" msgid="2913281996024033299">"بند کریں"</string>
<string name="back_button_text" msgid="1469718707134137085">"پیچھے"</string>
- <string name="handle_text" msgid="1766582106752184456">"ہینڈل"</string>
+ <string name="handle_text" msgid="4419667835599523257">"ایپ ہینڈل"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ایپ کا آئیکن"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"مکمل اسکرین"</string>
<string name="desktop_text" msgid="1077633567027630454">"ڈیسک ٹاپ موڈ"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index f8cd43f9d6fa..3ec676d2942d 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Kichraytirish"</string>
<string name="close_button_text" msgid="2913281996024033299">"Yopish"</string>
<string name="back_button_text" msgid="1469718707134137085">"Orqaga"</string>
- <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Ilova identifikatori"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ilova belgisi"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Butun ekran"</string>
<string name="desktop_text" msgid="1077633567027630454">"Desktop rejimi"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 86e2b3349716..125d703a464e 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Thu nhỏ"</string>
<string name="close_button_text" msgid="2913281996024033299">"Đóng"</string>
<string name="back_button_text" msgid="1469718707134137085">"Quay lại"</string>
- <string name="handle_text" msgid="1766582106752184456">"Xử lý"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Ô điều khiển ứng dụng"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Biểu tượng ứng dụng"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Toàn màn hình"</string>
<string name="desktop_text" msgid="1077633567027630454">"Chế độ máy tính"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index a56553b786c3..6ccc38b624e9 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"最小化"</string>
<string name="close_button_text" msgid="2913281996024033299">"关闭"</string>
<string name="back_button_text" msgid="1469718707134137085">"返回"</string>
- <string name="handle_text" msgid="1766582106752184456">"处理"</string>
+ <string name="handle_text" msgid="4419667835599523257">"应用手柄"</string>
<string name="app_icon_text" msgid="2823268023931811747">"应用图标"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全屏"</string>
<string name="desktop_text" msgid="1077633567027630454">"桌面模式"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 78c97e4944c9..2787c1e86b0c 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"最小化"</string>
<string name="close_button_text" msgid="2913281996024033299">"關閉"</string>
<string name="back_button_text" msgid="1469718707134137085">"返去"</string>
- <string name="handle_text" msgid="1766582106752184456">"控點"</string>
+ <string name="handle_text" msgid="4419667835599523257">"應用程式控點"</string>
<string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
<string name="desktop_text" msgid="1077633567027630454">"桌面模式"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 307dc9db9381..72050fb3edc6 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"最小化"</string>
<string name="close_button_text" msgid="2913281996024033299">"關閉"</string>
<string name="back_button_text" msgid="1469718707134137085">"返回"</string>
- <string name="handle_text" msgid="1766582106752184456">"控點"</string>
+ <string name="handle_text" msgid="4419667835599523257">"應用程式控制代碼"</string>
<string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
<string name="desktop_text" msgid="1077633567027630454">"電腦模式"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index ba3df301df54..ac62a7bd67b2 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -107,7 +107,7 @@
<string name="minimize_button_text" msgid="271592547935841753">"Nciphisa"</string>
<string name="close_button_text" msgid="2913281996024033299">"Vala"</string>
<string name="back_button_text" msgid="1469718707134137085">"Emuva"</string>
- <string name="handle_text" msgid="1766582106752184456">"Isibambo"</string>
+ <string name="handle_text" msgid="4419667835599523257">"Inkomba ye-App"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Isithonjana Se-app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Isikrini esigcwele"</string>
<string name="desktop_text" msgid="1077633567027630454">"Imodi Yedeskithophu"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 269a58693a24..1eb24580a582 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -296,9 +296,6 @@
<!-- The width of the compat hint. -->
<dimen name="compat_hint_width">188dp</dimen>
- <!-- The width of the camera compat hint. -->
- <dimen name="camera_compat_hint_width">143dp</dimen>
-
<!-- The corner radius of the letterbox education dialog. -->
<dimen name="letterbox_education_dialog_corner_radius">28dp</dimen>
@@ -554,15 +551,10 @@
enable_windowing_edge_drag_resize is disabled. -->
<dimen name="freeform_resize_corner">44dp</dimen>
- <!-- The width of the area at the sides of the screen where a freeform task will transition to
- split select if dragged until the touch input is within the range. -->
- <dimen name="desktop_mode_transition_area_width">32dp</dimen>
-
- <!-- The width of the area where a desktop task will transition to fullscreen. -->
- <dimen name="desktop_mode_fullscreen_from_desktop_width">80dp</dimen>
+ <!-- The thickness in dp for all desktop drag transition regions. -->
+ <dimen name="desktop_mode_transition_region_thickness">44dp</dimen>
- <!-- The height of the area where a desktop task will transition to fullscreen. -->
- <dimen name="desktop_mode_fullscreen_from_desktop_height">40dp</dimen>
+ <item type="dimen" format="float" name="desktop_mode_fullscreen_region_scale">0.4</item>
<!-- The height on the screen where drag to the left or right edge will result in a
desktop task snapping to split size. The empty space between this and the top is to allow
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 b1c9a775913a..13049694d3fb 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
@@ -35,6 +35,7 @@ enum class DesktopModeFlags(
) {
// All desktop mode related flags will be added here
DESKTOP_WINDOWING_MODE(Flags::enableDesktopWindowingMode, true),
+ CASCADING_WINDOWS(Flags::enableCascadingWindows, true),
WALLPAPER_ACTIVITY(Flags::enableDesktopWindowingWallpaperActivity, true),
MODALS_POLICY(Flags::enableDesktopWindowingModalsPolicy, true),
THEMED_APP_HEADERS(Flags::enableThemedAppHeaders, true),
@@ -42,7 +43,8 @@ enum class DesktopModeFlags(
APP_HEADER_WITH_TASK_DENSITY(Flags::enableAppHeaderWithTaskDensity, true),
TASK_STACK_OBSERVER_IN_SHELL(Flags::enableTaskStackObserverInShell, true),
SIZE_CONSTRAINTS(Flags::enableDesktopWindowingSizeConstraints, true),
- DYNAMIC_INITIAL_BOUNDS(Flags::enableWindowingDynamicInitialBounds, true);
+ DYNAMIC_INITIAL_BOUNDS(Flags::enableWindowingDynamicInitialBounds, true),
+ ENABLE_DESKTOP_WINDOWING_TASK_LIMIT(Flags::enableDesktopWindowingTaskLimit, true);
/**
* Determines state of flag based on the actual flag and desktop mode developer option overrides.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index f014e559d4b4..452d12a242c0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -24,7 +24,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static com.android.wm.shell.compatui.impl.CompatUIEventsKt.CAMERA_CONTROL_STATE_UPDATE;
import static com.android.wm.shell.compatui.impl.CompatUIEventsKt.SIZE_COMPAT_RESTART_BUTTON_APPEARED;
import static com.android.wm.shell.compatui.impl.CompatUIEventsKt.SIZE_COMPAT_RESTART_BUTTON_CLICKED;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
@@ -61,7 +60,6 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.compatui.api.CompatUIHandler;
import com.android.wm.shell.compatui.api.CompatUIInfo;
-import com.android.wm.shell.compatui.impl.CompatUIEvents.CameraControlStateUpdated;
import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonAppeared;
import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonClicked;
import com.android.wm.shell.recents.RecentTasksController;
@@ -265,9 +263,6 @@ public class ShellTaskOrganizer extends TaskOrganizer {
case SIZE_COMPAT_RESTART_BUTTON_CLICKED:
onSizeCompatRestartButtonClicked(compatUIEvent.asType());
break;
- case CAMERA_CONTROL_STATE_UPDATE:
- onCameraControlStateUpdated(compatUIEvent.asType());
- break;
default:
}
@@ -690,6 +685,15 @@ public class ShellTaskOrganizer extends TaskOrganizer {
return result;
}
+ /** Return list of {@link RunningTaskInfo}s on all the displays. */
+ public ArrayList<RunningTaskInfo> getRunningTasks() {
+ ArrayList<RunningTaskInfo> result = new ArrayList<>();
+ for (int i = 0; i < mTasks.size(); i++) {
+ result.add(mTasks.valueAt(i).getTaskInfo());
+ }
+ return result;
+ }
+
/** Gets running task by taskId. Returns {@code null} if no such task observed. */
@Nullable
public RunningTaskInfo getRunningTaskInfo(int taskId) {
@@ -808,21 +812,6 @@ public class ShellTaskOrganizer extends TaskOrganizer {
restartTaskTopActivityProcessIfVisible(info.getTaskInfo().token);
}
- @VisibleForTesting
- void onCameraControlStateUpdated(@NonNull CameraControlStateUpdated compatUIEvent) {
- final int taskId = compatUIEvent.getTaskId();
- final int state = compatUIEvent.getState();
- final TaskAppearedInfo info;
- synchronized (mLock) {
- info = mTasks.get(taskId);
- }
- if (info == null) {
- return;
- }
- updateCameraCompatControlState(info.getTaskInfo().token, state);
- }
-
-
private void logSizeCompatRestartButtonEventReported(@NonNull TaskAppearedInfo info,
int event) {
ActivityInfo topActivityInfo = info.getTaskInfo().topActivityInfo;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 972dce51e02b..24c568c23bf2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -169,6 +169,8 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
R.layout.bubble_overflow_container, null /* root */);
mOverflowView.initialize(expandedViewManager, positioner);
addView(mOverflowView);
+ // Don't show handle for overflow
+ mHandleView.setVisibility(View.GONE);
} else {
mTaskView = bubbleTaskView.getTaskView();
mBubbleTaskViewHelper = new BubbleTaskViewHelper(mContext, expandedViewManager,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index 4fbb5744b64b..d7d19f7b8bbd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -315,7 +315,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
}
}
if (!mImeShowing) {
- removeImeSurface();
+ removeImeSurface(mDisplayId);
}
}
} else if (!android.view.inputmethod.Flags.refactorInsetsController()
@@ -617,7 +617,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
|| hasLeash) {
t.hide(mImeSourceControl.getLeash());
}
- removeImeSurface();
+ removeImeSurface(mDisplayId);
ImeTracker.forLogging().onHidden(mStatsToken);
} else if (mAnimationDirection == DIRECTION_SHOW && !mCancelled) {
ImeTracker.forLogging().onShown(mStatsToken);
@@ -671,10 +671,10 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
}
}
- void removeImeSurface() {
+ void removeImeSurface(int displayId) {
// Remove the IME surface to make the insets invisible for
// non-client controlled insets.
- InputMethodManagerGlobal.removeImeSurface(
+ InputMethodManagerGlobal.removeImeSurface(displayId,
e -> Slog.e(TAG, "Failed to remove IME surface.", e));
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ImeListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ImeListener.kt
new file mode 100644
index 000000000000..a34d7bed497b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ImeListener.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 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.common
+
+import android.graphics.Rect
+import android.view.InsetsSource
+import android.view.InsetsState
+import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener
+
+abstract class ImeListener(
+ private val mDisplayController: DisplayController,
+ private val mDisplayId: Int
+) : OnInsetsChangedListener {
+ // The last insets state
+ private val mInsetsState = InsetsState()
+ private val mTmpBounds = Rect()
+
+ override fun insetsChanged(insetsState: InsetsState) {
+ if (mInsetsState == insetsState) {
+ return
+ }
+
+ // Get the stable bounds that account for display cutout and system bars to calculate the
+ // relative IME height
+ val layout = mDisplayController.getDisplayLayout(mDisplayId)
+ if (layout == null) {
+ return
+ }
+ layout.getStableBounds(mTmpBounds)
+
+ val wasVisible = getImeVisibilityAndHeight(mInsetsState).first
+ val oldHeight = getImeVisibilityAndHeight(mInsetsState).second
+
+ val isVisible = getImeVisibilityAndHeight(insetsState).first
+ val newHeight = getImeVisibilityAndHeight(insetsState).second
+
+ mInsetsState.set(insetsState, true)
+ if (wasVisible != isVisible || oldHeight != newHeight) {
+ onImeVisibilityChanged(isVisible, newHeight)
+ }
+ }
+
+ private fun getImeVisibilityAndHeight(
+ insetsState: InsetsState): Pair<Boolean, Int> {
+ val source = insetsState.peekSource(InsetsSource.ID_IME)
+ val frame = if (source != null && source.isVisible) source.frame else null
+ val height = if (frame != null) mTmpBounds.bottom - frame.top else 0
+ val visible = source?.isVisible ?: false
+ return Pair(visible, height)
+ }
+
+ /**
+ * To be overridden by implementations to handle IME changes.
+ */
+ protected abstract fun onImeVisibilityChanged(imeVisible: Boolean, imeHeight: Int)
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index 5097ed8866c9..19a109e9a28c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -31,6 +31,7 @@ import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -201,7 +202,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
/** Showing resizing hint. */
public void onResizing(ActivityManager.RunningTaskInfo resizingTask, Rect newBounds,
Rect sideBounds, SurfaceControl.Transaction t, int offsetX, int offsetY,
- boolean immediately, float[] veilColor) {
+ boolean immediately) {
if (mResizingIconView == null) {
return;
}
@@ -234,7 +235,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
if (mBackgroundLeash == null) {
mBackgroundLeash = SurfaceUtils.makeColorLayer(mHostLeash,
RESIZING_BACKGROUND_SURFACE_NAME, mSurfaceSession);
- t.setColor(mBackgroundLeash, veilColor)
+ t.setColor(mBackgroundLeash, getResizingBackgroundColor(resizingTask))
.setLayer(mBackgroundLeash, Integer.MAX_VALUE - 1);
}
@@ -245,7 +246,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
mGapBackgroundLeash = SurfaceUtils.makeColorLayer(mHostLeash,
GAP_BACKGROUND_SURFACE_NAME, mSurfaceSession);
// Fill up another side bounds area.
- t.setColor(mGapBackgroundLeash, veilColor)
+ t.setColor(mGapBackgroundLeash, getResizingBackgroundColor(resizingTask))
.setLayer(mGapBackgroundLeash, Integer.MAX_VALUE - 2)
.setPosition(mGapBackgroundLeash, left, top)
.setWindowCrop(mGapBackgroundLeash, sideBounds.width(), sideBounds.height());
@@ -486,4 +487,9 @@ public class SplitDecorManager extends WindowlessWindowManager {
mIcon = null;
}
}
+
+ private static float[] getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
+ final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
+ return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).getComponents();
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
index e8226051b672..f9259e79472e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.common.split;
+import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED;
+
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -24,18 +26,25 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
import android.app.ActivityManager;
import android.app.PendingIntent;
+import android.content.ComponentName;
import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Color;
import android.graphics.Rect;
+import android.os.UserHandle;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.util.ArrayUtils;
import com.android.wm.shell.Flags;
import com.android.wm.shell.ShellTaskOrganizer;
+import java.util.Arrays;
+import java.util.List;
+
/** Helper utility class for split screen components to use. */
public class SplitScreenUtils {
/** Reverse the split position. */
@@ -128,10 +137,4 @@ public class SplitScreenUtils {
return isLandscape;
}
}
-
- /** Returns the specified background color that matches a RunningTaskInfo. */
- public static Color getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
- final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
- return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor);
- }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java
index 2b0bd3272ed2..688f8ca2dc75 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java
@@ -16,10 +16,7 @@
package com.android.wm.shell.compatui;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
-
import android.annotation.IdRes;
-import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
@@ -57,28 +54,10 @@ class CompatUILayout extends LinearLayout {
mWindowManager = windowManager;
}
- void updateCameraTreatmentButton(@CameraCompatControlState int newState) {
- int buttonBkgId = newState == CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED
- ? R.drawable.camera_compat_treatment_suggested_ripple
- : R.drawable.camera_compat_treatment_applied_ripple;
- int hintStringId = newState == CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED
- ? R.string.camera_compat_treatment_suggested_button_description
- : R.string.camera_compat_treatment_applied_button_description;
- final ImageButton button = findViewById(R.id.camera_compat_treatment_button);
- button.setImageResource(buttonBkgId);
- button.setContentDescription(getResources().getString(hintStringId));
- final LinearLayout hint = findViewById(R.id.camera_compat_hint);
- ((TextView) hint.findViewById(R.id.compat_mode_hint_text)).setText(hintStringId);
- }
-
void setSizeCompatHintVisibility(boolean show) {
setViewVisibility(R.id.size_compat_hint, show);
}
- void setCameraCompatHintVisibility(boolean show) {
- setViewVisibility(R.id.camera_compat_hint, show);
- }
-
void setRestartButtonVisibility(boolean show) {
setViewVisibility(R.id.size_compat_restart_button, show);
// Hint should never be visible without button.
@@ -87,14 +66,6 @@ class CompatUILayout extends LinearLayout {
}
}
- void setCameraControlVisibility(boolean show) {
- setViewVisibility(R.id.camera_compat_control, show);
- // Hint should never be visible without button.
- if (!show) {
- setCameraCompatHintVisibility(/* show= */ false);
- }
- }
-
private void setViewVisibility(@IdRes int resId, boolean show) {
final View view = findViewById(resId);
int visibility = show ? View.VISIBLE : View.GONE;
@@ -127,26 +98,5 @@ class CompatUILayout extends LinearLayout {
((TextView) sizeCompatHint.findViewById(R.id.compat_mode_hint_text))
.setText(R.string.restart_button_description);
sizeCompatHint.setOnClickListener(view -> setSizeCompatHintVisibility(/* show= */ false));
-
- final ImageButton cameraTreatmentButton =
- findViewById(R.id.camera_compat_treatment_button);
- cameraTreatmentButton.setOnClickListener(
- view -> mWindowManager.onCameraTreatmentButtonClicked());
- cameraTreatmentButton.setOnLongClickListener(view -> {
- mWindowManager.onCameraButtonLongClicked();
- return true;
- });
-
- final ImageButton cameraDismissButton = findViewById(R.id.camera_compat_dismiss_button);
- cameraDismissButton.setOnClickListener(
- view -> mWindowManager.onCameraDismissButtonClicked());
- cameraDismissButton.setOnLongClickListener(view -> {
- mWindowManager.onCameraButtonLongClicked();
- return true;
- });
-
- final LinearLayout cameraCompatHint = findViewById(R.id.camera_compat_hint);
- cameraCompatHint.setOnClickListener(
- view -> setCameraCompatHintVisibility(/* show= */ false));
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
index f32683db533a..271c07d4011d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
@@ -16,10 +16,6 @@
package com.android.wm.shell.compatui;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_DISMISSED;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
import static android.view.WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
import static android.window.TaskConstants.TASK_CHILD_LAYER_COMPAT_UI;
@@ -27,11 +23,9 @@ import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.DESKTOP_W
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.content.Context;
import android.graphics.Rect;
-import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
@@ -44,7 +38,6 @@ import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
import com.android.wm.shell.compatui.api.CompatUIEvent;
-import com.android.wm.shell.compatui.impl.CompatUIEvents.CameraControlStateUpdated;
import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonAppeared;
import com.android.wm.shell.shared.desktopmode.DesktopModeFlags;
@@ -69,10 +62,6 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
boolean mHasSizeCompat;
@VisibleForTesting
- @CameraCompatControlState
- int mCameraCompatControlState = CAMERA_COMPAT_CONTROL_HIDDEN;
-
- @VisibleForTesting
@NonNull
CompatUIHintsState mCompatUIHintsState;
@@ -95,12 +84,10 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
mCallback = callback;
mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat;
if (DESKTOP_WINDOWING_MODE.isEnabled(mContext)
- && DesktopModeFlags.THEMED_APP_HEADERS.isEnabled(context)) {
+ && DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(context)) {
// Don't show the SCM button for freeform tasks
mHasSizeCompat &= !taskInfo.isFreeform();
}
- mCameraCompatControlState =
- taskInfo.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState;
mCompatUIHintsState = compatUIHintsState;
mCompatUIConfiguration = compatUIConfiguration;
mOnRestartButtonClicked = onRestartButtonClicked;
@@ -124,8 +111,7 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
@Override
protected boolean eligibleToShowLayout() {
- return (mHasSizeCompat && shouldShowSizeCompatRestartButton(getLastTaskInfo()))
- || shouldShowCameraControl();
+ return mHasSizeCompat && shouldShowSizeCompatRestartButton(getLastTaskInfo());
}
@Override
@@ -152,22 +138,18 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
public boolean updateCompatInfo(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener,
boolean canShow) {
final boolean prevHasSizeCompat = mHasSizeCompat;
- final int prevCameraCompatControlState = mCameraCompatControlState;
mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat;
if (DESKTOP_WINDOWING_MODE.isEnabled(mContext)
&& DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)) {
// Don't show the SCM button for freeform tasks
mHasSizeCompat &= !taskInfo.isFreeform();
}
- mCameraCompatControlState =
- taskInfo.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState;
if (!super.updateCompatInfo(taskInfo, taskListener, canShow)) {
return false;
}
- if (prevHasSizeCompat != mHasSizeCompat
- || prevCameraCompatControlState != mCameraCompatControlState) {
+ if (prevHasSizeCompat != mHasSizeCompat) {
updateVisibilityOfViews();
}
@@ -179,34 +161,6 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
mOnRestartButtonClicked.accept(Pair.create(getLastTaskInfo(), getTaskListener()));
}
- /** Called when the camera treatment button is clicked. */
- void onCameraTreatmentButtonClicked() {
- if (!shouldShowCameraControl()) {
- Log.w(getTag(), "Camera compat shouldn't receive clicks in the hidden state.");
- return;
- }
- // When a camera control is shown, only two states are allowed: "treament applied" and
- // "treatment suggested". Clicks on the conrol's treatment button toggle between these
- // two states.
- mCameraCompatControlState =
- mCameraCompatControlState == CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED
- ? CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED
- : CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- mCallback.accept(new CameraControlStateUpdated(mTaskId, mCameraCompatControlState));
- mLayout.updateCameraTreatmentButton(mCameraCompatControlState);
- }
-
- /** Called when the camera dismiss button is clicked. */
- void onCameraDismissButtonClicked() {
- if (!shouldShowCameraControl()) {
- Log.w(getTag(), "Camera compat shouldn't receive clicks in the hidden state.");
- return;
- }
- mCameraCompatControlState = CAMERA_COMPAT_CONTROL_DISMISSED;
- mCallback.accept(new CameraControlStateUpdated(mTaskId, CAMERA_COMPAT_CONTROL_DISMISSED));
- mLayout.setCameraControlVisibility(/* show= */ false);
- }
-
/** Called when the restart button is long clicked. */
void onRestartButtonLongClicked() {
if (mLayout == null) {
@@ -215,14 +169,6 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
mLayout.setSizeCompatHintVisibility(/* show= */ true);
}
- /** Called when either dismiss or treatment camera buttons is long clicked. */
- void onCameraButtonLongClicked() {
- if (mLayout == null) {
- return;
- }
- mLayout.setCameraCompatHintVisibility(/* show= */ true);
- }
-
@Override
@VisibleForTesting
public void updateSurfacePosition() {
@@ -270,6 +216,7 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
return false;
}
final float percentageAreaOfLetterboxInTask = (float) letterboxArea / taskArea * 100;
+
return percentageAreaOfLetterboxInTask < mHideScmTolerance;
}
@@ -284,21 +231,5 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
mLayout.setSizeCompatHintVisibility(/* show= */ true);
mCompatUIHintsState.mHasShownSizeCompatHint = true;
}
-
- // Camera control for stretched issues.
- mLayout.setCameraControlVisibility(shouldShowCameraControl());
- // Only show by default for the first time.
- if (shouldShowCameraControl() && !mCompatUIHintsState.mHasShownCameraCompatHint) {
- mLayout.setCameraCompatHintVisibility(/* show= */ true);
- mCompatUIHintsState.mHasShownCameraCompatHint = true;
- }
- if (shouldShowCameraControl()) {
- mLayout.updateCameraTreatmentButton(mCameraCompatControlState);
- }
- }
-
- private boolean shouldShowCameraControl() {
- return mCameraCompatControlState != CAMERA_COMPAT_CONTROL_HIDDEN
- && mCameraCompatControlState != CAMERA_COMPAT_CONTROL_DISMISSED;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
index 58ce8ed6c978..23205c3dca9e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
@@ -16,13 +16,10 @@
package com.android.wm.shell.compatui.impl
-import android.app.AppCompatTaskInfo
-import android.app.CameraCompatTaskInfo
import com.android.wm.shell.compatui.api.CompatUIEvent
internal const val SIZE_COMPAT_RESTART_BUTTON_APPEARED = 0
internal const val SIZE_COMPAT_RESTART_BUTTON_CLICKED = 1
-internal const val CAMERA_CONTROL_STATE_UPDATE = 2
/**
* All the {@link CompatUIEvent} the Compat UI Framework can handle
@@ -35,10 +32,4 @@ sealed class CompatUIEvents(override val eventId: Int) : CompatUIEvent {
/** Sent when the size compat restart button is clicked. */
data class SizeCompatRestartButtonClicked(val taskId: Int) :
CompatUIEvents(SIZE_COMPAT_RESTART_BUTTON_CLICKED)
-
- /** Sent when the camera compat control state is updated. */
- data class CameraControlStateUpdated(
- val taskId: Int,
- @CameraCompatTaskInfo.CameraCompatControlState val state: Int
- ) : CompatUIEvents(CAMERA_CONTROL_STATE_UPDATE)
} \ No newline at end of file
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 afe46f500e51..da1af0d40a96 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
@@ -16,7 +16,7 @@
package com.android.wm.shell.dagger;
-import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.DESKTOP_WINDOWING_MODE;
+import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_TASK_LIMIT;
import android.annotation.Nullable;
import android.app.KeyguardManager;
@@ -566,16 +566,23 @@ public abstract class WMShellModule {
Context context,
Transitions transitions,
@DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
- ShellTaskOrganizer shellTaskOrganizer) {
+ ShellTaskOrganizer shellTaskOrganizer,
+ InteractionJankMonitor interactionJankMonitor) {
int maxTaskLimit = DesktopModeStatus.getMaxTaskLimit(context);
if (!DesktopModeStatus.canEnterDesktopMode(context)
- || DESKTOP_WINDOWING_MODE.isEnabled(context)
+ || !ENABLE_DESKTOP_WINDOWING_TASK_LIMIT.isEnabled(context)
|| maxTaskLimit <= 0) {
return Optional.empty();
}
return Optional.of(
new DesktopTasksLimiter(
- transitions, desktopModeTaskRepository, shellTaskOrganizer, maxTaskLimit));
+ transitions,
+ desktopModeTaskRepository,
+ shellTaskOrganizer,
+ maxTaskLimit,
+ interactionJankMonitor,
+ context)
+ );
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
index ea7e9685dd92..06c1e68753e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
@@ -104,6 +104,7 @@ public abstract class Pip2Module {
TaskStackListenerImpl taskStackListener,
ShellTaskOrganizer shellTaskOrganizer,
PipTransitionState pipTransitionState,
+ PipTouchHandler pipTouchHandler,
@ShellMainThread ShellExecutor mainExecutor) {
if (!PipUtils.isPip2ExperimentEnabled()) {
return Optional.empty();
@@ -112,7 +113,7 @@ public abstract class Pip2Module {
context, shellInit, shellCommandHandler, shellController, displayController,
displayInsetsController, pipBoundsState, pipBoundsAlgorithm,
pipDisplayLayoutState, pipScheduler, taskStackListener, shellTaskOrganizer,
- pipTransitionState, mainExecutor));
+ pipTransitionState, pipTouchHandler, mainExecutor));
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
index 247cc42e51ed..83752945e9f9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
@@ -32,77 +32,77 @@ import java.io.PrintWriter
import java.util.concurrent.Executor
import java.util.function.Consumer
-/** Keeps track of task data related to desktop mode. */
+/** Tracks task data for Desktop Mode. */
class DesktopModeTaskRepository {
- /** Task data that is tracked per display */
- private data class DisplayData(
- /**
- * Set of task ids that are marked as active in desktop mode. Active tasks in desktop mode
- * are freeform tasks that are visible or have been visible after desktop mode was
- * activated. Task gets removed from this list when it vanishes. Or when desktop mode is
- * turned off.
- */
+ /**
+ * Task data tracked per desktop.
+ *
+ * @property activeTasks task ids of active tasks currently or previously visible in Desktop
+ * mode session. Tasks become inactive when task closes or when desktop mode session ends.
+ * @property visibleTasks task ids for active freeform tasks that are currently visible. There
+ * might be other active tasks in desktop mode that are not visible.
+ * @property minimizedTasks task ids for active freeform tasks that are currently minimized.
+ * @property closingTasks task ids for tasks that are going to close, but are currently visible.
+ * @property freeformTasksInZOrder list of current freeform task ids ordered from top to bottom
+ * (top is at index 0).
+ */
+ private data class DesktopTaskData(
val activeTasks: ArraySet<Int> = ArraySet(),
val visibleTasks: ArraySet<Int> = ArraySet(),
val minimizedTasks: ArraySet<Int> = ArraySet(),
- // Tasks that are closing, but are still visible
// TODO(b/332682201): Remove when the repository state is updated via TransitionObserver
val closingTasks: ArraySet<Int> = ArraySet(),
- // Tasks currently in freeform mode, ordered from top to bottom (top is at index 0).
val freeformTasksInZOrder: ArrayList<Int> = ArrayList(),
)
- // Token of the current wallpaper activity, used to remove it when the last task is removed
+ /* Current wallpaper activity token to remove wallpaper activity when last task is removed. */
var wallpaperActivityToken: WindowContainerToken? = null
+
private val activeTasksListeners = ArraySet<ActiveTasksListener>()
- // Track visible tasks separately because a task may be part of the desktop but not visible.
private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>()
- // Track corner/caption regions of desktop tasks, used to determine gesture exclusion
+
+ /* Tracks corner/caption regions of desktop tasks, used to determine gesture exclusion. */
private val desktopExclusionRegions = SparseArray<Region>()
- // Track last bounds of task before toggled to stable bounds
+
+ /* Tracks last bounds of task before toggled to stable bounds. */
private val boundsBeforeMaximizeByTaskId = SparseArray<Rect>()
+
private var desktopGestureExclusionListener: Consumer<Region>? = null
private var desktopGestureExclusionExecutor: Executor? = null
- private val displayData =
- object : SparseArray<DisplayData>() {
- /**
- * Get the [DisplayData] associated with this [displayId]
- *
- * Creates a new instance if one does not exist
- */
- fun getOrCreate(displayId: Int): DisplayData {
- if (!contains(displayId)) {
- put(displayId, DisplayData())
- }
- return get(displayId)
- }
- }
+ private val desktopTaskDataByDisplayId = object : SparseArray<DesktopTaskData>() {
+ /** Gets [DesktopTaskData] for existing [displayId] or creates a new one. */
+ fun getOrCreate(displayId: Int): DesktopTaskData =
+ this[displayId] ?: DesktopTaskData().also { this[displayId] = it }
+ }
- /** Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository. */
+ /** Adds [activeTasksListener] to be notified of updates to active tasks. */
fun addActiveTaskListener(activeTasksListener: ActiveTasksListener) {
activeTasksListeners.add(activeTasksListener)
}
- /** Add a [VisibleTasksListener] to be notified when freeform tasks are visible or not. */
+ /** Adds [visibleTasksListener] to be notified of updates to visible tasks. */
fun addVisibleTasksListener(visibleTasksListener: VisibleTasksListener, executor: Executor) {
visibleTasksListeners[visibleTasksListener] = executor
- displayData.keyIterator().forEach {
+ desktopTaskDataByDisplayId.keyIterator().forEach {
+ val visibleTaskCount = getVisibleTaskCount(it)
executor.execute {
- visibleTasksListener.onTasksVisibilityChanged(it, visibleTaskCount(it))
+ visibleTasksListener.onTasksVisibilityChanged(it, visibleTaskCount)
}
}
}
- /** Returns a list of all [DisplayData]. */
- private fun displayDataList(): Sequence<DisplayData> =
- displayData.valueIterator().asSequence()
+ /** Updates tasks changes on all the active task listeners for given display id. */
+ private fun updateActiveTasksListeners(displayId: Int) {
+ activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) }
+ }
- /**
- * Add a Consumer which will inform other classes of changes to exclusion regions for all
- * Desktop tasks.
- */
+ /** Returns a list of all [DesktopTaskData] in the repository. */
+ private fun desktopTaskDataSequence(): Sequence<DesktopTaskData> =
+ desktopTaskDataByDisplayId.valueIterator().asSequence()
+
+ /** Adds [regionListener] to inform about changes to exclusion regions for all Desktop tasks. */
fun setExclusionRegionListener(regionListener: Consumer<Region>, executor: Executor) {
desktopGestureExclusionListener = regionListener
desktopGestureExclusionExecutor = executor
@@ -111,7 +111,7 @@ class DesktopModeTaskRepository {
}
}
- /** Create a new merged region representative of all exclusion regions in all desktop tasks. */
+ /** Creates a new merged region representative of all exclusion regions in all desktop tasks. */
private fun calculateDesktopExclusionRegion(): Region {
val desktopExclusionRegion = Region()
desktopExclusionRegions.valueIterator().forEach { taskExclusionRegion ->
@@ -120,192 +120,120 @@ class DesktopModeTaskRepository {
return desktopExclusionRegion
}
- /** Remove a previously registered [ActiveTasksListener] */
+ /** Remove the previously registered [activeTasksListener] */
fun removeActiveTasksListener(activeTasksListener: ActiveTasksListener) {
activeTasksListeners.remove(activeTasksListener)
}
- /** Remove a previously registered [VisibleTasksListener] */
+ /** Removes the previously registered [visibleTasksListener]. */
fun removeVisibleTasksListener(visibleTasksListener: VisibleTasksListener) {
visibleTasksListeners.remove(visibleTasksListener)
}
- /**
- * Mark a task with given [taskId] as active on given [displayId]
- *
- * @return `true` if the task was not active on given [displayId]
- */
- fun addActiveTask(displayId: Int, taskId: Int): Boolean {
- // Check if task is active on another display, if so, remove it
- displayData.forEach { id, data ->
- if (id != displayId && data.activeTasks.remove(taskId)) {
- activeTasksListeners.onEach { it.onActiveTasksChanged(id) }
- }
- }
+ /** Adds task with [taskId] to the list of active tasks on [displayId]. */
+ fun addActiveTask(displayId: Int, taskId: Int) {
+ // Removes task if it is active on another display excluding [displayId].
+ removeActiveTask(taskId, excludedDisplayId = displayId)
- val added = displayData.getOrCreate(displayId).activeTasks.add(taskId)
- if (added) {
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTaskRepo: add active task=%d displayId=%d",
- taskId,
- displayId
- )
- activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) }
+ if (desktopTaskDataByDisplayId.getOrCreate(displayId).activeTasks.add(taskId)) {
+ logD("Adds active task=%d displayId=%d", taskId, displayId)
+ updateActiveTasksListeners(displayId)
}
- return added
}
- /**
- * Remove task with given [taskId] from active tasks.
- *
- * @return `true` if the task was active
- */
- fun removeActiveTask(taskId: Int): Boolean {
- var result = false
- displayData.forEach { displayId, data ->
- if (data.activeTasks.remove(taskId)) {
- activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) }
- result = true
+ /** Removes task from active task list of displays excluding the [excludedDisplayId]. */
+ fun removeActiveTask(taskId: Int, excludedDisplayId: Int? = null) {
+ desktopTaskDataByDisplayId.forEach { displayId, desktopTaskData ->
+ if ((displayId != excludedDisplayId)
+ && desktopTaskData.activeTasks.remove(taskId)) {
+ logD("Removed active task=%d displayId=%d", taskId, displayId)
+ updateActiveTasksListeners(displayId)
}
}
- if (result) {
- ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove active task=%d", taskId)
- }
- return result
}
- /**
- * Mark a task with given [taskId] as closing on given [displayId]
- *
- * @return `true` if the task was not closing on given [displayId]
- */
- fun addClosingTask(displayId: Int, taskId: Int): Boolean {
- val added = displayData.getOrCreate(displayId).closingTasks.add(taskId)
- if (added) {
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTaskRepo: added closing task=%d displayId=%d",
- taskId,
- displayId
- )
+ /** Adds given task to the closing task list for [displayId]. */
+ fun addClosingTask(displayId: Int, taskId: Int) {
+ if (desktopTaskDataByDisplayId.getOrCreate(displayId).closingTasks.add(taskId)) {
+ logD("Added closing task=%d displayId=%d", taskId, displayId)
+ } else {
+ // If the task hasn't been removed from closing list after it disappeared.
+ logW("Task with taskId=%d displayId=%d is already closing", taskId, displayId)
}
- return added
}
- /**
- * Remove task with given [taskId] from closing tasks.
- *
- * @return `true` if the task was closing
- */
- fun removeClosingTask(taskId: Int): Boolean {
- var removed = false
- displayData.forEach { _, data ->
- if (data.closingTasks.remove(taskId)) {
- removed = true
+ /** Removes task from the list of closing tasks for [displayId]. */
+ fun removeClosingTask(taskId: Int) {
+ desktopTaskDataByDisplayId.forEach { displayId, taskInfo ->
+ if (taskInfo.closingTasks.remove(taskId)) {
+ logD("Removed closing task=%d displayId=%d", taskId, displayId)
}
}
- if (removed) {
- ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove closing task=%d", taskId)
- }
- return removed
}
- fun isActiveTask(taskId: Int) = displayDataList().any { taskId in it.activeTasks }
- fun isClosingTask(taskId: Int) = displayDataList().any { taskId in it.closingTasks }
- fun isVisibleTask(taskId: Int) = displayDataList().any { taskId in it.visibleTasks }
- fun isMinimizedTask(taskId: Int) = displayDataList().any { taskId in it.minimizedTasks }
+ fun isActiveTask(taskId: Int) = desktopTaskDataSequence().any { taskId in it.activeTasks }
+ fun isClosingTask(taskId: Int) = desktopTaskDataSequence().any { taskId in it.closingTasks }
+ fun isVisibleTask(taskId: Int) = desktopTaskDataSequence().any { taskId in it.visibleTasks }
+ fun isMinimizedTask(taskId: Int) = desktopTaskDataSequence().any { taskId in it.minimizedTasks }
- /**
- * Check if a task with the given [taskId] is the only visible, non-closing, not-minimized task
- * on its display
- */
+ /** Checks if a task is the only visible, non-closing, non-minimized task on its display. */
fun isOnlyVisibleNonClosingTask(taskId: Int): Boolean =
- displayDataList().any { data ->
- data.visibleTasks
- .subtract(data.closingTasks)
- .subtract(data.minimizedTasks)
- .singleOrNull() == taskId
+ desktopTaskDataSequence().any { it.visibleTasks
+ .subtract(it.closingTasks)
+ .subtract(it.minimizedTasks)
+ .singleOrNull() == taskId
}
- /** Get a set of the active tasks for given [displayId] */
- fun getActiveTasks(displayId: Int): ArraySet<Int> {
- return ArraySet(displayData[displayId]?.activeTasks)
- }
+ fun getActiveTasks(displayId: Int): ArraySet<Int> =
+ ArraySet(desktopTaskDataByDisplayId[displayId]?.activeTasks)
- /** Returns the minimized tasks for the given [displayId]. */
fun getMinimizedTasks(displayId: Int): ArraySet<Int> =
- ArraySet(displayData[displayId]?.minimizedTasks)
+ ArraySet(desktopTaskDataByDisplayId[displayId]?.minimizedTasks)
- /**
- * Returns a list of Tasks IDs representing all active non-minimized Tasks on the given display,
- * ordered from front to back.
- */
- fun getActiveNonMinimizedTasksOrderedFrontToBack(displayId: Int): List<Int> {
- val activeTasks = getActiveTasks(displayId)
- val allTasksInZOrder = getFreeformTasksInZOrder(displayId)
- return activeTasks
- // Don't show already minimized Tasks
- .filter { taskId -> !isMinimizedTask(taskId) }
- .sortedBy { taskId -> allTasksInZOrder.indexOf(taskId) }
- }
+ /** Returns all active non-minimized tasks for [displayId] ordered from top to bottom. */
+ fun getActiveNonMinimizedOrderedTasks(displayId: Int): List<Int> =
+ getFreeformTasksInZOrder(displayId).filter { !isMinimizedTask(it) }
- /** Get a list of freeform tasks, ordered from top-bottom (top at index 0). */
+ /** Returns a list of freeform tasks, ordered from top-bottom (top at index 0). */
fun getFreeformTasksInZOrder(displayId: Int): ArrayList<Int> =
- ArrayList(displayData[displayId]?.freeformTasksInZOrder ?: emptyList())
+ ArrayList(desktopTaskDataByDisplayId[displayId]?.freeformTasksInZOrder ?: emptyList())
+
+ /** Removes task from visible tasks of all displays except [excludedDisplayId]. */
+ private fun removeVisibleTask(taskId: Int, excludedDisplayId: Int? = null) {
+ desktopTaskDataByDisplayId.forEach { displayId, data ->
+ if ((displayId != excludedDisplayId) && data.visibleTasks.remove(taskId)) {
+ notifyVisibleTaskListeners(displayId, data.visibleTasks.size)
+ }
+ }
+ }
/**
- * Updates whether a freeform task with this id is visible or not and notifies listeners.
+ * Updates visibility of a freeform task with [taskId] on [displayId] and notifies listeners.
*
- * If the task was visible on a different display with a different displayId, it is removed from
- * the set of visible tasks on that display. Listeners will be notified.
+ * If task was visible on a different display with a different [displayId], removes from
+ * the set of visible tasks on that display and notifies listeners.
*/
- fun updateVisibleFreeformTasks(displayId: Int, taskId: Int, visible: Boolean) {
+ fun updateTaskVisibility(displayId: Int, taskId: Int, visible: Boolean) {
if (visible) {
- // Task is visible. Check if we need to remove it from any other display.
- val otherDisplays = displayData.keyIterator().asSequence().filter { it != displayId }
- for (otherDisplayId in otherDisplays) {
- if (displayData[otherDisplayId].visibleTasks.remove(taskId)) {
- notifyVisibleTaskListeners(
- otherDisplayId,
- displayData[otherDisplayId].visibleTasks.size
- )
- }
- }
+ // If task is visible, remove it from any other display besides [displayId].
+ removeVisibleTask(taskId, excludedDisplayId = displayId)
} else if (displayId == INVALID_DISPLAY) {
// Task has vanished. Check which display to remove the task from.
- displayData.forEach { displayId, data ->
- if (data.visibleTasks.remove(taskId)) {
- notifyVisibleTaskListeners(displayId, data.visibleTasks.size)
- }
- }
+ removeVisibleTask(taskId)
return
}
-
- val prevCount = visibleTaskCount(displayId)
+ val prevCount = getVisibleTaskCount(displayId)
if (visible) {
- displayData.getOrCreate(displayId).visibleTasks.add(taskId)
+ desktopTaskDataByDisplayId.getOrCreate(displayId).visibleTasks.add(taskId)
unminimizeTask(displayId, taskId)
} else {
- displayData[displayId]?.visibleTasks?.remove(taskId)
+ desktopTaskDataByDisplayId[displayId]?.visibleTasks?.remove(taskId)
}
- val newCount = visibleTaskCount(displayId)
-
- // Check if count changed
+ val newCount = getVisibleTaskCount(displayId)
if (prevCount != newCount) {
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTaskRepo: update task visibility taskId=%d visible=%b displayId=%d",
- taskId,
- visible,
- displayId
- )
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTaskRepo: visibleTaskCount has changed from %d to %d",
- prevCount,
- newCount
- )
+ logD("Update task visibility taskId=%d visible=%b displayId=%d",
+ taskId, visible, displayId)
+ logD("VisibleTaskCount has changed from %d to %d", prevCount, newCount)
notifyVisibleTaskListeners(displayId, newCount)
}
}
@@ -316,72 +244,80 @@ class DesktopModeTaskRepository {
}
}
- /** Get number of tasks that are marked as visible on given [displayId] */
- fun visibleTaskCount(displayId: Int): Int {
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTaskRepo: visibleTaskCount= %d",
- displayData[displayId]?.visibleTasks?.size ?: 0
- )
- return displayData[displayId]?.visibleTasks?.size ?: 0
- }
+ /** Gets number of visible tasks on given [displayId] */
+ fun getVisibleTaskCount(displayId: Int): Int =
+ desktopTaskDataByDisplayId[displayId]?.visibleTasks?.size ?: 0.also {
+ logD("getVisibleTaskCount=$it")
+ }
- /** Add (or move if it already exists) the task to the top of the ordered list. */
- // TODO(b/342417921): Identify if there is additional checks needed to move tasks for
- // multi-display scenarios.
+ /**
+ * Adds task (or moves if it already exists) to the top of the ordered list.
+ *
+ * Unminimizes the task if it is minimized.
+ */
fun addOrMoveFreeformTaskToTop(displayId: Int, taskId: Int) {
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTaskRepo: add or move task to top: display=%d, taskId=%d",
- displayId,
- taskId
- )
- displayData[displayId]?.freeformTasksInZOrder?.remove(taskId)
- displayData.getOrCreate(displayId).freeformTasksInZOrder.add(0, taskId)
+ logD("Add or move task to top: display=%d taskId=%d", taskId, displayId)
+ desktopTaskDataByDisplayId[displayId]?.freeformTasksInZOrder?.remove(taskId)
+ desktopTaskDataByDisplayId.getOrCreate(displayId).freeformTasksInZOrder.add(0, taskId)
+ // Unminimize the task if it is minimized.
+ unminimizeTask(displayId, taskId)
}
- /** Mark a Task as minimized. */
+ /** Minimizes the task for [taskId] and [displayId] */
fun minimizeTask(displayId: Int, taskId: Int) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopModeTaskRepository: minimize Task: display=%d, task=%d",
- displayId,
- taskId
- )
- displayData.getOrCreate(displayId).minimizedTasks.add(taskId)
+ logD("Minimize Task: display=%d, task=%d", displayId, taskId)
+ desktopTaskDataByDisplayId.getOrCreate(displayId).minimizedTasks.add(taskId)
}
- /** Mark a Task as non-minimized. */
+ /** Unminimizes the task for [taskId] and [displayId] */
fun unminimizeTask(displayId: Int, taskId: Int) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopModeTaskRepository: unminimize Task: display=%d, task=%d",
- displayId,
- taskId
- )
- displayData[displayId]?.minimizedTasks?.remove(taskId)
+ logD("Unminimize Task: display=%d, task=%d", displayId, taskId)
+ desktopTaskDataByDisplayId[displayId]?.minimizedTasks?.remove(taskId) ?:
+ logW("Unminimize Task: display=%d, task=%d, no task data", displayId, taskId)
+ }
+
+ private fun getDisplayIdForTask(taskId: Int): Int? {
+ desktopTaskDataByDisplayId.forEach { displayId, data ->
+ if (taskId in data.freeformTasksInZOrder) {
+ return displayId
+ }
+ }
+ logW("No display id found for task: taskId=%d", taskId)
+ return null
}
- /** Remove the task from the ordered list. */
+ /**
+ * Removes [taskId] from the respective display. If [INVALID_DISPLAY], the original display id
+ * will be looked up from the task id.
+ */
fun removeFreeformTask(displayId: Int, taskId: Int) {
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTaskRepo: remove freeform task from ordered list: display=%d, taskId=%d",
- displayId,
- taskId
- )
- displayData[displayId]?.freeformTasksInZOrder?.remove(taskId)
+ logD("Removes freeform task: taskId=%d", taskId)
+ if (displayId == INVALID_DISPLAY) {
+ // Removes the original display id of the task.
+ getDisplayIdForTask(taskId)?.let { removeTaskFromDisplay(it, taskId) }
+ } else {
+ removeTaskFromDisplay(displayId, taskId)
+ }
+ }
+
+ /** Removes given task from a valid [displayId] and updates the repository state. */
+ private fun removeTaskFromDisplay(displayId: Int, taskId: Int) {
+ logD("Removes freeform task: taskId=%d, displayId=%d", taskId, displayId)
+ desktopTaskDataByDisplayId[displayId]?.freeformTasksInZOrder?.remove(taskId)
boundsBeforeMaximizeByTaskId.remove(taskId)
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTaskRepo: remaining freeform tasks: %s",
- displayData[displayId]?.freeformTasksInZOrder?.toDumpString() ?: ""
- )
+ logD("Remaining freeform tasks: %s",
+ desktopTaskDataByDisplayId[displayId]?.freeformTasksInZOrder?.toDumpString())
+ // Remove task from unminimized task if it is minimized.
+ unminimizeTask(displayId, taskId)
+ removeActiveTask(taskId)
+ updateTaskVisibility(displayId, taskId, visible = false);
}
/**
- * Updates the active desktop gesture exclusion regions; if desktopExclusionRegions has been
- * accepted by desktopGestureExclusionListener, it will be updated in the appropriate classes.
+ * Updates active desktop gesture exclusion regions.
+ *
+ * If [desktopExclusionRegions] is accepted by [desktopGestureExclusionListener], updates it in
+ * appropriate classes.
*/
fun updateTaskExclusionRegions(taskId: Int, taskExclusionRegions: Region) {
desktopExclusionRegions.put(taskId, taskExclusionRegions)
@@ -391,9 +327,10 @@ class DesktopModeTaskRepository {
}
/**
- * Removes the desktop gesture exclusion region for the specified task; if exclusionRegion has
- * been accepted by desktopGestureExclusionListener, it will be updated in the appropriate
- * classes.
+ * Removes desktop gesture exclusion region for the specified task.
+ *
+ * If [desktopExclusionRegions] is accepted by [desktopGestureExclusionListener], updates it in
+ * appropriate classes.
*/
fun removeExclusionRegion(taskId: Int) {
desktopExclusionRegions.delete(taskId)
@@ -403,26 +340,24 @@ class DesktopModeTaskRepository {
}
/** Removes and returns the bounds saved before maximizing the given task. */
- fun removeBoundsBeforeMaximize(taskId: Int): Rect? {
- return boundsBeforeMaximizeByTaskId.removeReturnOld(taskId)
- }
+ fun removeBoundsBeforeMaximize(taskId: Int): Rect? =
+ boundsBeforeMaximizeByTaskId.removeReturnOld(taskId)
/** Saves the bounds of the given task before maximizing. */
- fun saveBoundsBeforeMaximize(taskId: Int, bounds: Rect) {
+ fun saveBoundsBeforeMaximize(taskId: Int, bounds: Rect) =
boundsBeforeMaximizeByTaskId.set(taskId, Rect(bounds))
- }
internal fun dump(pw: PrintWriter, prefix: String) {
val innerPrefix = "$prefix "
pw.println("${prefix}DesktopModeTaskRepository")
- dumpDisplayData(pw, innerPrefix)
+ dumpDesktopTaskData(pw, innerPrefix)
pw.println("${innerPrefix}activeTasksListeners=${activeTasksListeners.size}")
pw.println("${innerPrefix}visibleTasksListeners=${visibleTasksListeners.size}")
}
- private fun dumpDisplayData(pw: PrintWriter, prefix: String) {
+ private fun dumpDesktopTaskData(pw: PrintWriter, prefix: String) {
val innerPrefix = "$prefix "
- displayData.forEach { displayId, data ->
+ desktopTaskDataByDisplayId.forEach { displayId, data ->
pw.println("${prefix}Display $displayId:")
pw.println("${innerPrefix}activeTasks=${data.activeTasks.toDumpString()}")
pw.println("${innerPrefix}visibleTasks=${data.visibleTasks.toDumpString()}")
@@ -432,23 +367,29 @@ class DesktopModeTaskRepository {
}
}
- /**
- * Defines interface for classes that can listen to changes for active tasks in desktop mode.
- */
+ /** Listens to changes for active tasks in desktop mode. */
interface ActiveTasksListener {
- /** Called when the active tasks change in desktop mode. */
fun onActiveTasksChanged(displayId: Int) {}
}
- /**
- * Defines interface for classes that can listen to changes for visible tasks in desktop mode.
- */
+ /** Listens to changes for visible tasks in desktop mode. */
interface VisibleTasksListener {
- /** Called when the desktop changes the number of visible freeform tasks. */
fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {}
}
-}
-private fun <T> Iterable<T>.toDumpString(): String {
- return joinToString(separator = ", ", prefix = "[", postfix = "]")
+ private fun logD(msg: String, vararg arguments: Any?) {
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+
+ private fun logW(msg: String, vararg arguments: Any?) {
+ ProtoLog.w(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+
+ companion object {
+ private const val TAG = "DesktopModeTaskRepository"
+ }
}
+
+private fun <T> Iterable<T>.toDumpString(): String =
+ joinToString(separator = ", ", prefix = "[", postfix = "]")
+
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index da212e704b24..9fcf73d2c375 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -52,8 +52,10 @@ fun calculateInitialBounds(
val idealSize = calculateIdealSize(screenBounds, scale)
// If no top activity exists, apps fullscreen bounds and aspect ratio cannot be calculated.
// Instead default to the desired initial bounds.
+ val stableBounds = Rect()
+ displayLayout.getStableBoundsForDesktopMode(stableBounds)
val topActivityInfo =
- taskInfo.topActivityInfo ?: return positionInScreen(idealSize, screenBounds)
+ taskInfo.topActivityInfo ?: return positionInScreen(idealSize, stableBounds)
val initialSize: Size =
when (taskInfo.configuration.orientation) {
@@ -100,7 +102,7 @@ fun calculateInitialBounds(
}
}
- return positionInScreen(initialSize, screenBounds)
+ return positionInScreen(initialSize, stableBounds)
}
/**
@@ -163,17 +165,11 @@ private fun calculateIdealSize(screenBounds: Rect, scale: Float): Size {
}
/** Adjusts bounds to be positioned in the middle of the screen. */
-private fun positionInScreen(desiredSize: Size, screenBounds: Rect): Rect {
- // TODO(b/325240051): Position apps with bottom heavy offset
- val heightOffset = (screenBounds.height() - desiredSize.height) / 2
- val widthOffset = (screenBounds.width() - desiredSize.width) / 2
- return Rect(
- widthOffset,
- heightOffset,
- desiredSize.width + widthOffset,
- desiredSize.height + heightOffset
- )
-}
+private fun positionInScreen(desiredSize: Size, stableBounds: Rect): Rect =
+ Rect(0, 0, desiredSize.width, desiredSize.height).apply {
+ val offset = DesktopTaskPosition.Center.getTopLeftCoordinates(stableBounds, this)
+ offsetTo(offset.x, offset.y)
+ }
/**
* Adjusts bounds to be positioned in the middle of the area provided, not necessarily the
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index ed0d2b87b03f..6011db7fc752 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -105,7 +105,7 @@ public class DesktopModeVisualIndicator {
// If we are in freeform, we don't want a visible indicator in the "freeform" drag zone.
IndicatorType result = IndicatorType.NO_INDICATOR;
final int transitionAreaWidth = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_transition_area_width);
+ com.android.wm.shell.R.dimen.desktop_mode_transition_region_thickness);
// Because drags in freeform use task position for indicator calculation, we need to
// account for the possibility of the task going off the top of the screen by captionHeight
final int captionHeight = mContext.getResources().getDimensionPixelSize(
@@ -140,18 +140,19 @@ public class DesktopModeVisualIndicator {
final Region region = new Region();
int transitionHeight = windowingMode == WINDOWING_MODE_FREEFORM
? mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height)
+ com.android.wm.shell.R.dimen.desktop_mode_transition_region_thickness)
: 2 * layout.stableInsets().top;
- // A thin, short Rect at the top of the screen.
+ // A Rect at the top of the screen that takes up the center 40%.
if (windowingMode == WINDOWING_MODE_FREEFORM) {
- int fromFreeformWidth = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_width);
- region.union(new Rect((layout.width() / 2) - (fromFreeformWidth / 2),
+ final float toFullscreenScale = mContext.getResources().getFloat(
+ R.dimen.desktop_mode_fullscreen_region_scale);
+ final float toFullscreenWidth = (layout.width() * toFullscreenScale);
+ region.union(new Rect((int) ((layout.width() / 2f) - (toFullscreenWidth / 2f)),
-captionHeight,
- (layout.width() / 2) + (fromFreeformWidth / 2),
+ (int) ((layout.width() / 2f) + (toFullscreenWidth / 2f)),
transitionHeight));
}
- // A screen-wide, shorter Rect if the task is in fullscreen or split.
+ // A screen-wide Rect if the task is in fullscreen or split.
if (windowingMode == WINDOWING_MODE_FULLSCREEN
|| windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
region.union(new Rect(0,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskPosition.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskPosition.kt
new file mode 100644
index 000000000000..97abda81d12d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskPosition.kt
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2024 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.desktopmode
+
+import android.app.TaskInfo
+import android.content.res.Resources
+import android.graphics.Point
+import android.graphics.Rect
+import android.view.Gravity
+import com.android.internal.annotations.VisibleForTesting
+import com.android.wm.shell.desktopmode.DesktopTaskPosition.BottomLeft
+import com.android.wm.shell.desktopmode.DesktopTaskPosition.BottomRight
+import com.android.wm.shell.desktopmode.DesktopTaskPosition.Center
+import com.android.wm.shell.desktopmode.DesktopTaskPosition.TopLeft
+import com.android.wm.shell.desktopmode.DesktopTaskPosition.TopRight
+import com.android.wm.shell.R
+
+/**
+ * The position of a task window in desktop mode.
+ */
+sealed class DesktopTaskPosition {
+ data object Center : DesktopTaskPosition() {
+ private const val WINDOW_HEIGHT_PROPORTION = 0.375
+
+ override fun getTopLeftCoordinates(frame: Rect, window: Rect): Point {
+ val x = (frame.width() - window.width()) / 2
+ // Position with more margin at the bottom.
+ val y = (frame.height() - window.height()) * WINDOW_HEIGHT_PROPORTION + frame.top
+ return Point(x, y.toInt())
+ }
+
+ override fun next(): DesktopTaskPosition {
+ return BottomRight
+ }
+ }
+
+ data object BottomRight : DesktopTaskPosition() {
+ override fun getTopLeftCoordinates(frame: Rect, window: Rect): Point {
+ return Point(frame.right - window.width(), frame.bottom - window.height())
+ }
+
+ override fun next(): DesktopTaskPosition {
+ return TopLeft
+ }
+ }
+
+ data object TopLeft : DesktopTaskPosition() {
+ override fun getTopLeftCoordinates(frame: Rect, window: Rect): Point {
+ return Point(frame.left, frame.top)
+ }
+
+ override fun next(): DesktopTaskPosition {
+ return BottomLeft
+ }
+ }
+
+ data object BottomLeft : DesktopTaskPosition() {
+ override fun getTopLeftCoordinates(frame: Rect, window: Rect): Point {
+ return Point(frame.left, frame.bottom - window.height())
+ }
+
+ override fun next(): DesktopTaskPosition {
+ return TopRight
+ }
+ }
+
+ data object TopRight : DesktopTaskPosition() {
+ override fun getTopLeftCoordinates(frame: Rect, window: Rect): Point {
+ return Point(frame.right - window.width(), frame.top)
+ }
+
+ override fun next(): DesktopTaskPosition {
+ return Center
+ }
+ }
+
+ /**
+ * Returns the top left coordinates for the window to be placed in the given
+ * DesktopTaskPosition in the frame.
+ */
+ abstract fun getTopLeftCoordinates(frame: Rect, window: Rect): Point
+
+ abstract fun next(): DesktopTaskPosition
+}
+
+/**
+ * If the app has specified horizontal or vertical gravity layout, don't change the
+ * task position for cascading effect.
+ */
+fun canChangeTaskPosition(taskInfo: TaskInfo): Boolean {
+ taskInfo.topActivityInfo?.windowLayout?.let {
+ val horizontalGravityApplied = it.gravity.and(Gravity.HORIZONTAL_GRAVITY_MASK)
+ val verticalGravityApplied = it.gravity.and(Gravity.VERTICAL_GRAVITY_MASK)
+ return horizontalGravityApplied == 0 && verticalGravityApplied == 0
+ }
+ return true
+}
+
+/**
+ * Returns the current DesktopTaskPosition for a given window in the frame.
+ */
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+fun Rect.getDesktopTaskPosition(bounds: Rect): DesktopTaskPosition {
+ return when {
+ top == bounds.top && left == bounds.left -> TopLeft
+ top == bounds.top && right == bounds.right -> TopRight
+ bottom == bounds.bottom && left == bounds.left -> BottomLeft
+ bottom == bounds.bottom && right == bounds.right -> BottomRight
+ else -> Center
+ }
+}
+
+internal fun cascadeWindow(res: Resources, frame: Rect, prev: Rect, dest: Rect) {
+ val candidateBounds = Rect(dest)
+ val lastPos = frame.getDesktopTaskPosition(prev)
+ var destCoord = Center.getTopLeftCoordinates(frame, candidateBounds)
+ candidateBounds.offsetTo(destCoord.x, destCoord.y)
+ // If the default center position is not free or if last focused window is not at the
+ // center, get the next cascading window position.
+ if (!prevBoundsMovedAboveThreshold(res, prev, candidateBounds) || Center != lastPos) {
+ val nextCascadingPos = lastPos.next()
+ destCoord = nextCascadingPos.getTopLeftCoordinates(frame, dest)
+ }
+ dest.offsetTo(destCoord.x, destCoord.y)
+}
+
+internal fun prevBoundsMovedAboveThreshold(res: Resources, prev: Rect, newBounds: Rect): Boolean {
+ // This is the required minimum dp for a task to be touchable.
+ val moveThresholdPx = res.getDimensionPixelSize(
+ R.dimen.freeform_required_visible_empty_space_in_header)
+ val leftFar = newBounds.left - prev.left > moveThresholdPx
+ val topFar = newBounds.top - prev.top > moveThresholdPx
+ val rightFar = prev.right - newBounds.right > moveThresholdPx
+ val bottomFar = prev.bottom - newBounds.bottom > moveThresholdPx
+
+ return leftFar || topFar || rightFar || bottomFar
+}
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 2ef045d9fb89..5f838d3adb3c 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
@@ -121,7 +121,7 @@ class DesktopTasksController(
private val exitDesktopTaskTransitionHandler: ExitDesktopTaskTransitionHandler,
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
private val dragToDesktopTransitionHandler: DragToDesktopTransitionHandler,
- private val desktopModeTaskRepository: DesktopModeTaskRepository,
+ private val taskRepository: DesktopModeTaskRepository,
private val desktopModeLoggerTransitionObserver: DesktopModeLoggerTransitionObserver,
private val launchAdjacentController: LaunchAdjacentController,
private val recentsTransitionHandler: RecentsTransitionHandler,
@@ -181,7 +181,7 @@ class DesktopTasksController(
}
private fun onInit() {
- ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
+ logD("onInit")
shellCommandHandler.addDumpCallback(this::dump, this)
shellCommandHandler.addCommandCallback("desktopmode", desktopModeShellCommandHandler, this)
shellController.addExternalInterface(
@@ -190,16 +190,12 @@ class DesktopTasksController(
this
)
transitions.addHandler(this)
- desktopModeTaskRepository.addVisibleTasksListener(taskVisibilityListener, mainExecutor)
+ taskRepository.addVisibleTasksListener(taskVisibilityListener, mainExecutor)
dragToDesktopTransitionHandler.setDragToDesktopStateListener(dragToDesktopStateListener)
recentsTransitionHandler.addTransitionStateListener(
object : RecentsTransitionStateListener {
override fun onAnimationStateChanged(running: Boolean) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: recents animation state changed running=%b",
- running
- )
+ logV("Recents animation state changed running=%b", running)
recentsAnimationRunning = running
}
}
@@ -227,7 +223,7 @@ class DesktopTasksController(
/** Returns the transition type for the given remote transition. */
private fun transitionType(remoteTransition: RemoteTransition?): Int {
if (remoteTransition == null) {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: remoteTransition is null")
+ logV("RemoteTransition is null")
return TRANSIT_NONE
}
return TRANSIT_TO_FRONT
@@ -235,7 +231,7 @@ class DesktopTasksController(
/** Show all tasks, that are part of the desktop, on top of launcher */
fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition? = null) {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: showDesktopApps")
+ logV("showDesktopApps")
val wct = WindowContainerTransaction()
bringDesktopAppsToFront(displayId, wct)
@@ -255,7 +251,7 @@ class DesktopTasksController(
/** Gets number of visible tasks in [displayId]. */
fun visibleTaskCount(displayId: Int): Int =
- desktopModeTaskRepository.visibleTaskCount(displayId)
+ taskRepository.getVisibleTaskCount(displayId)
/** Returns true if any tasks are visible in Desktop Mode. */
fun isDesktopModeShowing(displayId: Int): Boolean = visibleTaskCount(displayId) > 0
@@ -286,14 +282,8 @@ class DesktopTasksController(
// Fullscreen case where we move the current focused task.
moveToDesktop(allFocusedTasks[0].taskId, transitionSource = transitionSource)
}
- else -> {
- ProtoLog.w(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: Cannot enter desktop, expected less " +
- "than 3 focused tasks but found %d",
- allFocusedTasks.size
- )
- }
+ else -> logW("Cannot enter desktop, expected < 3 focused tasks, found %d",
+ allFocusedTasks.size)
}
}
}
@@ -317,11 +307,7 @@ class DesktopTasksController(
transitionSource: DesktopModeTransitionSource,
): Boolean {
recentTasksController?.findTaskInBackground(taskId)?.let {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: moveToDesktopFromNonRunningTask taskId=%d",
- taskId
- )
+ logV("moveToDesktopFromNonRunningTask with taskId=%d, displayId=%d", taskId)
// TODO(342378842): Instead of using default display, support multiple displays
val taskToMinimize =
bringDesktopAppsToFrontBeforeShowingNewTask(DEFAULT_DISPLAY, wct, taskId)
@@ -351,18 +337,10 @@ class DesktopTasksController(
) {
if (DesktopModeFlags.MODALS_POLICY.isEnabled(context)
&& isTopActivityExemptFromDesktopWindowing(context, task)) {
- ProtoLog.w(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: Cannot enter desktop, " +
- "ineligible top activity found."
- )
+ logW("Cannot enter desktop for taskId %d, ineligible top activity found", task.taskId)
return
}
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: moveToDesktop taskId=%d",
- task.taskId
- )
+ logV("moveToDesktop taskId=%d", task.taskId)
exitSplitIfApplicable(wct, task)
// Bring other apps to front first
val taskToMinimize =
@@ -386,11 +364,7 @@ class DesktopTasksController(
dragToDesktopValueAnimator: MoveToDesktopAnimator,
taskSurface: SurfaceControl,
) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: startDragToDesktop taskId=%d",
- taskInfo.taskId
- )
+ logV("startDragToDesktop taskId=%d", taskInfo.taskId)
interactionJankMonitor.begin(taskSurface, context,
CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_HOLD)
dragToDesktopTransitionHandler.startDragToDesktopTransition(
@@ -403,7 +377,7 @@ class DesktopTasksController(
* The second part of the animated drag to desktop transition, called after
* [startDragToDesktop].
*/
- private fun finalizeDragToDesktop(taskInfo: RunningTaskInfo, freeformBounds: Rect) {
+ private fun finalizeDragToDesktop(taskInfo: RunningTaskInfo) {
ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: finalizeDragToDesktop taskId=%d",
@@ -415,7 +389,6 @@ class DesktopTasksController(
val taskToMinimize =
bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
addMoveToDesktopChanges(wct, taskInfo)
- wct.setBounds(taskInfo.token, freeformBounds)
val transition = dragToDesktopTransitionHandler.finishDragToDesktopTransition(wct)
transition?.let { addPendingMinimizeTransition(it, taskToMinimize) }
}
@@ -443,17 +416,10 @@ class DesktopTasksController(
* @param taskId task id of the window that's being closed
*/
fun onDesktopWindowClose(wct: WindowContainerTransaction, displayId: Int, taskId: Int) {
- if (desktopModeTaskRepository.isOnlyVisibleNonClosingTask(taskId)) {
+ if (taskRepository.isOnlyVisibleNonClosingTask(taskId)) {
removeWallpaperActivity(wct)
}
- if (!desktopModeTaskRepository.addClosingTask(displayId, taskId)) {
- // Could happen if the task hasn't been removed from closing list after it disappeared
- ProtoLog.w(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: the task with taskId=%d is already closing!",
- taskId
- )
- }
+ taskRepository.addClosingTask(displayId, taskId)
}
/** Move a task with given `taskId` to fullscreen */
@@ -472,11 +438,7 @@ class DesktopTasksController(
/** Move a desktop app to split screen. */
fun moveToSplit(task: RunningTaskInfo) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: moveToSplit taskId=%d",
- task.taskId
- )
+ logV( "moveToSplit taskId=%s", task.taskId)
val wct = WindowContainerTransaction()
wct.setBounds(task.token, Rect())
// Rather than set windowing mode to multi-window at task level, set it to
@@ -505,11 +467,7 @@ class DesktopTasksController(
* [startDragToDesktop].
*/
fun cancelDragToDesktop(task: RunningTaskInfo) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: cancelDragToDesktop taskId=%d",
- task.taskId
- )
+ logV("cancelDragToDesktop taskId=%d", task.taskId)
dragToDesktopTransitionHandler.cancelDragToDesktopTransition(
DragToDesktopTransitionHandler.CancelState.STANDARD_CANCEL
)
@@ -520,11 +478,7 @@ class DesktopTasksController(
position: Point,
transitionSource: DesktopModeTransitionSource
) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: moveToFullscreen with animation taskId=%d",
- task.taskId
- )
+ logV("moveToFullscreenWithAnimation taskId=%d", task.taskId)
val wct = WindowContainerTransaction()
addMoveToFullscreenChanges(wct, task)
@@ -548,12 +502,7 @@ class DesktopTasksController(
/** Move a task to the front */
fun moveTaskToFront(taskInfo: RunningTaskInfo) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: moveTaskToFront taskId=%d",
- taskInfo.taskId
- )
-
+ logV("moveTaskToFront taskId=%s", taskInfo.taskId)
val wct = WindowContainerTransaction()
wct.reorder(taskInfo.token, true)
val taskToMinimize = addAndGetMinimizeChangesIfNeeded(taskInfo.displayId, wct, taskInfo)
@@ -579,15 +528,10 @@ class DesktopTasksController(
fun moveToNextDisplay(taskId: Int) {
val task = shellTaskOrganizer.getRunningTaskInfo(taskId)
if (task == null) {
- ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: taskId=%d not found", taskId)
+ logW("moveToNextDisplay: taskId=%d not found", taskId)
return
}
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "moveToNextDisplay: taskId=%d taskDisplayId=%d",
- taskId,
- task.displayId
- )
+ logV("moveToNextDisplay: taskId=%d displayId=%d", taskId, task.displayId)
val displayIds = rootTaskDisplayAreaOrganizer.displayIds.sorted()
// Get the first display id that is higher than current task display id
@@ -597,7 +541,7 @@ class DesktopTasksController(
newDisplayId = displayIds.firstOrNull { displayId -> displayId < task.displayId }
}
if (newDisplayId == null) {
- ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: next display not found")
+ logW("moveToNextDisplay: next display not found")
return
}
moveToDisplay(task, newDisplayId)
@@ -609,21 +553,15 @@ class DesktopTasksController(
* No-op if task is already on that display per [RunningTaskInfo.displayId].
*/
private fun moveToDisplay(task: RunningTaskInfo, displayId: Int) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "moveToDisplay: taskId=%d displayId=%d",
- task.taskId,
- displayId
- )
-
+ logV("moveToDisplay: taskId=%d displayId=%d", task.taskId, displayId)
if (task.displayId == displayId) {
- ProtoLog.d(WM_SHELL_DESKTOP_MODE, "moveToDisplay: task already on display")
+ logD("moveToDisplay: task already on display %d", displayId)
return
}
val displayAreaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)
if (displayAreaInfo == null) {
- ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToDisplay: display not found")
+ logW("moveToDisplay: display not found")
return
}
@@ -660,7 +598,7 @@ class DesktopTasksController(
// If the task's pre-maximize stable bounds were saved, toggle the task to those bounds.
// Otherwise, toggle to the default bounds.
val taskBoundsBeforeMaximize =
- desktopModeTaskRepository.removeBoundsBeforeMaximize(taskInfo.taskId)
+ taskRepository.removeBoundsBeforeMaximize(taskInfo.taskId)
if (taskBoundsBeforeMaximize != null) {
destinationBounds.set(taskBoundsBeforeMaximize)
} else {
@@ -673,7 +611,7 @@ class DesktopTasksController(
} else {
// Save current bounds so that task can be restored back to original bounds if necessary
// and toggle to the stable bounds.
- desktopModeTaskRepository.saveBoundsBeforeMaximize(taskInfo.taskId, currentTaskBounds)
+ taskRepository.saveBoundsBeforeMaximize(taskInfo.taskId, currentTaskBounds)
if (taskInfo.isResizeable) {
// if resizable then expand to entire stable bounds (full display minus insets)
@@ -778,12 +716,7 @@ class DesktopTasksController(
wct: WindowContainerTransaction,
newTaskIdInFront: Int? = null
): RunningTaskInfo? {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: bringDesktopAppsToFront, newTaskIdInFront=%s",
- newTaskIdInFront ?: "null"
- )
-
+ logV("bringDesktopAppsToFront, newTaskId=%d", newTaskIdInFront)
// Move home to front, ensures that we go back home when all desktop windows are closed
moveHomeTask(wct, toTop = true)
@@ -794,7 +727,7 @@ class DesktopTasksController(
}
val nonMinimizedTasksOrderedFrontToBack =
- desktopModeTaskRepository.getActiveNonMinimizedTasksOrderedFrontToBack(displayId)
+ taskRepository.getActiveNonMinimizedOrderedTasks(displayId)
// If we're adding a new Task we might need to minimize an old one
val taskToMinimize: RunningTaskInfo? =
if (newTaskIdInFront != null && desktopTasksLimiter.isPresent) {
@@ -812,7 +745,7 @@ class DesktopTasksController(
.filter { taskId -> taskId != taskToMinimize?.taskId }
.mapNotNull { taskId -> shellTaskOrganizer.getRunningTaskInfo(taskId) }
.reversed() // Start from the back so the front task is brought forward last
- .forEach { task -> wct.reorder(task.token, true /* onTop */) }
+ .forEach { task -> wct.reorder(task.token, /* onTop= */ true) }
return taskToMinimize
}
@@ -820,11 +753,11 @@ class DesktopTasksController(
shellTaskOrganizer
.getRunningTasks(context.displayId)
.firstOrNull { task -> task.activityType == ACTIVITY_TYPE_HOME }
- ?.let { homeTask -> wct.reorder(homeTask.getToken(), toTop /* onTop */) }
+ ?.let { homeTask -> wct.reorder(homeTask.getToken(), /* onTop= */ toTop) }
}
private fun addWallpaperActivity(wct: WindowContainerTransaction) {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: addWallpaper")
+ logV("addWallpaperActivity")
val intent = Intent(context, DesktopWallpaperActivity::class.java)
val options =
ActivityOptions.makeBasic().apply {
@@ -842,8 +775,8 @@ class DesktopTasksController(
}
private fun removeWallpaperActivity(wct: WindowContainerTransaction) {
- desktopModeTaskRepository.wallpaperActivityToken?.let { token ->
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: removeWallpaper")
+ taskRepository.wallpaperActivityToken?.let { token ->
+ logV("removeWallpaperActivity")
wct.removeTask(token)
}
}
@@ -881,11 +814,7 @@ class DesktopTasksController(
transition: IBinder,
request: TransitionRequestInfo
): WindowContainerTransaction? {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: handleRequest request=%s",
- request
- )
+ logV("handleRequest request=%s", request)
// Check if we should skip handling this transition
var reason = ""
val triggerTask = request.triggerTask
@@ -923,11 +852,7 @@ class DesktopTasksController(
}
if (!shouldHandleRequest) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: skipping handleRequest reason=%s",
- reason
- )
+ logV("skipping handleRequest reason=%s", reason)
return null
}
@@ -947,11 +872,7 @@ class DesktopTasksController(
}
}
}
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: handleRequest result=%s",
- result ?: "null"
- )
+ logV("handleRequest result=%s", result)
return result
}
@@ -985,25 +906,20 @@ class DesktopTasksController(
task: RunningTaskInfo,
transition: IBinder
): WindowContainerTransaction? {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFreeformTaskLaunch")
+ logV("handleFreeformTaskLaunch")
if (keyguardManager.isKeyguardLocked) {
// Do NOT handle freeform task launch when locked.
// It will be launched in fullscreen windowing mode (Details: b/160925539)
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: skip keyguard is locked")
+ logV("skip keyguard is locked")
return null
}
val wct = WindowContainerTransaction()
if (!isDesktopModeShowing(task.displayId)) {
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: bring desktop tasks to front on transition" +
- " taskId=%d",
- task.taskId
- )
+ logD("Bring desktop tasks to front on transition=taskId=%d", task.taskId)
// We are outside of desktop mode and already existing desktop task is being launched.
// We should make this task go to fullscreen instead of freeform. Note that this means
// any re-launch of a freeform window outside of desktop will be in fullscreen.
- if (desktopModeTaskRepository.isActiveTask(task.taskId)) {
+ if (taskRepository.isActiveTask(task.taskId)) {
addMoveToFullscreenChanges(wct, task)
return wct
}
@@ -1028,14 +944,9 @@ class DesktopTasksController(
task: RunningTaskInfo,
transition: IBinder
): WindowContainerTransaction? {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFullscreenTaskLaunch")
+ logV("handleFullscreenTaskLaunch")
if (isDesktopModeShowing(task.displayId)) {
- ProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: switch fullscreen task to freeform on transition" +
- " taskId=%d",
- task.taskId
- )
+ logD("Switch fullscreen task to freeform on transition: taskId=%d", task.taskId)
return WindowContainerTransaction().also { wct ->
addMoveToDesktopChanges(wct, task)
// In some launches home task is moved behind new task being launched. Make sure
@@ -1062,33 +973,28 @@ class DesktopTasksController(
/** Handle task closing by removing wallpaper activity if it's the last active task */
private fun handleTaskClosing(task: RunningTaskInfo): WindowContainerTransaction? {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleTaskClosing")
+ logV("handleTaskClosing")
val wct = WindowContainerTransaction()
- if (desktopModeTaskRepository.isOnlyVisibleNonClosingTask(task.taskId)
- && desktopModeTaskRepository.wallpaperActivityToken != null) {
+ if (taskRepository.isOnlyVisibleNonClosingTask(task.taskId)
+ && taskRepository.wallpaperActivityToken != null) {
// Remove wallpaper activity when the last active task is removed
removeWallpaperActivity(wct)
}
- if (!desktopModeTaskRepository.addClosingTask(task.displayId, task.taskId)) {
- // Could happen if the task hasn't been removed from closing list after it disappeared
- ProtoLog.w(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: the task with taskId=%d is already closing!",
- task.taskId
- )
- }
+ taskRepository.addClosingTask(task.displayId, task.taskId)
// If a CLOSE or TO_BACK is triggered on a desktop task, remove the task.
if (Flags.enableDesktopWindowingBackNavigation() &&
- desktopModeTaskRepository.isVisibleTask(task.taskId)) {
+ taskRepository.isVisibleTask(task.taskId)) {
wct.removeTask(task.token)
}
return if (wct.isEmpty) null else wct
}
- private fun addMoveToDesktopChanges(
+ @VisibleForTesting
+ fun addMoveToDesktopChanges(
wct: WindowContainerTransaction,
taskInfo: RunningTaskInfo
) {
+ val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!!
val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode
val targetWindowingMode =
@@ -1098,6 +1004,28 @@ class DesktopTasksController(
} else {
WINDOWING_MODE_FREEFORM
}
+ val initialBounds = if (DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(context)) {
+ calculateInitialBounds(displayLayout, taskInfo)
+ } else {
+ getDefaultDesktopTaskBounds(displayLayout)
+ }
+
+ if (DesktopModeFlags.CASCADING_WINDOWS.isEnabled(context)) {
+ val stableBounds = Rect()
+ displayLayout.getStableBoundsForDesktopMode(stableBounds)
+
+ val activeTasks = taskRepository
+ .getActiveNonMinimizedOrderedTasks(taskInfo.displayId)
+ activeTasks.firstOrNull()?.let { activeTask ->
+ shellTaskOrganizer.getRunningTaskInfo(activeTask)?.let {
+ cascadeWindow(context.resources, stableBounds,
+ it.configuration.windowConfiguration.bounds, initialBounds)
+ }
+ }
+ }
+ if (canChangeTaskPosition(taskInfo)) {
+ wct.setBounds(taskInfo.token, initialBounds)
+ }
wct.setWindowingMode(taskInfo.token, targetWindowingMode)
wct.reorder(taskInfo.token, true /* onTop */)
if (useDesktopOverrideDensity()) {
@@ -1123,7 +1051,7 @@ class DesktopTasksController(
if (useDesktopOverrideDensity()) {
wct.setDensityDpi(taskInfo.token, getDefaultDensityDpi())
}
- if (desktopModeTaskRepository.isOnlyVisibleNonClosingTask(taskInfo.taskId)) {
+ if (taskRepository.isOnlyVisibleNonClosingTask(taskInfo.taskId)) {
// Remove wallpaper activity when leaving desktop mode
removeWallpaperActivity(wct)
}
@@ -1142,7 +1070,7 @@ class DesktopTasksController(
// The task's density may have been overridden in freeform; revert it here as we don't
// want it overridden in multi-window.
wct.setDensityDpi(taskInfo.token, getDefaultDensityDpi())
- if (desktopModeTaskRepository.isOnlyVisibleNonClosingTask(taskInfo.taskId)) {
+ if (taskRepository.isOnlyVisibleNonClosingTask(taskInfo.taskId)) {
// Remove wallpaper activity when leaving desktop mode
removeWallpaperActivity(wct)
}
@@ -1357,16 +1285,10 @@ class DesktopTasksController(
val indicatorType = indicator.updateIndicatorType(inputCoordinates, taskInfo.windowingMode)
when (indicatorType) {
IndicatorType.TO_DESKTOP_INDICATOR -> {
- val displayLayout = displayController.getDisplayLayout(taskInfo.displayId)
- ?: return IndicatorType.NO_INDICATOR
// Start a new jank interaction for the drag release to desktop window animation.
interactionJankMonitor.begin(taskSurface, context,
CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE, "to_desktop")
- if (DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(context)) {
- finalizeDragToDesktop(taskInfo, calculateInitialBounds(displayLayout, taskInfo))
- } else {
- finalizeDragToDesktop(taskInfo, getDefaultDesktopTaskBounds(displayLayout))
- }
+ finalizeDragToDesktop(taskInfo)
}
IndicatorType.NO_INDICATOR,
IndicatorType.TO_FULLSCREEN_INDICATOR -> {
@@ -1384,12 +1306,12 @@ class DesktopTasksController(
/** Update the exclusion region for a specified task */
fun onExclusionRegionChanged(taskId: Int, exclusionRegion: Region) {
- desktopModeTaskRepository.updateTaskExclusionRegions(taskId, exclusionRegion)
+ taskRepository.updateTaskExclusionRegions(taskId, exclusionRegion)
}
/** Remove a previously tracked exclusion region for a specified task. */
fun removeExclusionRegionForTask(taskId: Int) {
- desktopModeTaskRepository.removeExclusionRegion(taskId)
+ taskRepository.removeExclusionRegion(taskId)
}
/**
@@ -1399,7 +1321,7 @@ class DesktopTasksController(
* @param callbackExecutor the executor to call the listener on.
*/
fun addVisibleTasksListener(listener: VisibleTasksListener, callbackExecutor: Executor) {
- desktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor)
+ taskRepository.addVisibleTasksListener(listener, callbackExecutor)
}
/**
@@ -1409,7 +1331,7 @@ class DesktopTasksController(
* @param callbackExecutor the executor to call the listener on.
*/
fun setTaskRegionListener(listener: Consumer<Region>, callbackExecutor: Executor) {
- desktopModeTaskRepository.setExclusionRegionListener(listener, callbackExecutor)
+ taskRepository.setExclusionRegionListener(listener, callbackExecutor)
}
override fun onUnhandledDrag(
@@ -1427,7 +1349,7 @@ class DesktopTasksController(
if (!multiInstanceHelper.supportsMultiInstanceSplit(launchComponent)) {
// TODO(b/320797628): Should only return early if there is an existing running task, and
// notify the user as well. But for now, just ignore the drop.
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "Dropped intent does not support multi-instance")
+ logV("Dropped intent does not support multi-instance")
return false
}
@@ -1459,7 +1381,7 @@ class DesktopTasksController(
private fun dump(pw: PrintWriter, prefix: String) {
val innerPrefix = "$prefix "
pw.println("${prefix}DesktopTasksController")
- desktopModeTaskRepository.dump(pw, innerPrefix)
+ taskRepository.dump(pw, innerPrefix)
}
/** The interface for calls from outside the shell, within the host process. */
@@ -1534,12 +1456,12 @@ class DesktopTasksController(
SingleInstanceRemoteListener<DesktopTasksController, IDesktopTaskListener>(
controller,
{ c ->
- c.desktopModeTaskRepository.addVisibleTasksListener(
+ c.taskRepository.addVisibleTasksListener(
listener,
c.mainExecutor
)
},
- { c -> c.desktopModeTaskRepository.removeVisibleTasksListener(listener) }
+ { c -> c.taskRepository.removeVisibleTasksListener(listener) }
)
}
@@ -1566,10 +1488,7 @@ class DesktopTasksController(
}
override fun hideStashedDesktopApps(displayId: Int) {
- ProtoLog.w(
- WM_SHELL_DESKTOP_MODE,
- "IDesktopModeImpl: hideStashedDesktopApps is deprecated"
- )
+ ProtoLog.w(WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: hideStashedDesktopApps is deprecated")
}
override fun getVisibleTaskCount(displayId: Int): Int {
@@ -1593,11 +1512,7 @@ class DesktopTasksController(
}
override fun setTaskListener(listener: IDesktopTaskListener?) {
- ProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "IDesktopModeImpl: set task listener=%s",
- listener ?: "null"
- )
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: set task listener=%s", listener)
executeRemoteCallWithTaskPermission(controller, "setTaskListener") { _ ->
listener?.let { remoteListener.register(it) } ?: remoteListener.unregister()
}
@@ -1610,10 +1525,22 @@ class DesktopTasksController(
}
}
+ private fun logV(msg: String, vararg arguments: Any?) {
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+ private fun logD(msg: String, vararg arguments: Any?) {
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+ private fun logW(msg: String, vararg arguments: Any?) {
+ ProtoLog.w(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+
companion object {
@JvmField
val DESKTOP_MODE_INITIAL_BOUNDS_SCALE =
SystemProperties.getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f
+
+ private const val TAG = "DesktopTasksController"
}
/** The positions on a screen that a task can snap to. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
index c5ed1be004e5..38675129ce57 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
@@ -17,12 +17,15 @@
package com.android.wm.shell.desktopmode
import android.app.ActivityManager.RunningTaskInfo
+import android.content.Context
import android.os.IBinder
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_TO_BACK
import android.window.TransitionInfo
import android.window.WindowContainerTransaction
import androidx.annotation.VisibleForTesting
+import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_MINIMIZE_WINDOW
+import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup
@@ -33,13 +36,16 @@ import com.android.wm.shell.transition.Transitions.TransitionObserver
* Limits the number of tasks shown in Desktop Mode.
*
* This class should only be used if
- * [com.android.window.flags.Flags.enableDesktopWindowingTaskLimit()] is true.
+ * [com.android.wm.shell.shared.desktopmode.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_TASK_LIMIT]
+ * is enabled and [maxTasksLimit] is strictly greater than 0.
*/
class DesktopTasksLimiter (
transitions: Transitions,
private val taskRepository: DesktopModeTaskRepository,
private val shellTaskOrganizer: ShellTaskOrganizer,
private val maxTasksLimit: Int,
+ private val interactionJankMonitor: InteractionJankMonitor,
+ private val context: Context
) {
private val minimizeTransitionObserver = MinimizeTransitionObserver()
@VisibleForTesting
@@ -52,25 +58,34 @@ class DesktopTasksLimiter (
}
transitions.registerObserver(minimizeTransitionObserver)
taskRepository.addActiveTaskListener(leftoverMinimizedTasksRemover)
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksLimiter: starting limiter with a maximum of %d tasks", maxTasksLimit)
}
- private data class TaskDetails (val displayId: Int, val taskId: Int)
+ private data class TaskDetails(
+ val displayId: Int,
+ val taskId: Int,
+ var transitionInfo: TransitionInfo?
+ )
// TODO(b/333018485): replace this observer when implementing the minimize-animation
private inner class MinimizeTransitionObserver : TransitionObserver {
private val mPendingTransitionTokensAndTasks = mutableMapOf<IBinder, TaskDetails>()
+ private val mActiveTransitionTokensAndTasks = mutableMapOf<IBinder, TaskDetails>()
fun addPendingTransitionToken(transition: IBinder, taskDetails: TaskDetails) {
mPendingTransitionTokensAndTasks[transition] = taskDetails
}
override fun onTransitionReady(
- transition: IBinder,
- info: TransitionInfo,
- startTransaction: SurfaceControl.Transaction,
- finishTransaction: SurfaceControl.Transaction
+ transition: IBinder,
+ info: TransitionInfo,
+ startTransaction: SurfaceControl.Transaction,
+ finishTransaction: SurfaceControl.Transaction
) {
val taskToMinimize = mPendingTransitionTokensAndTasks.remove(transition) ?: return
+ taskToMinimize.transitionInfo = info
+ mActiveTransitionTokensAndTasks[transition] = taskToMinimize
if (!taskRepository.isActiveTask(taskToMinimize.taskId)) return
@@ -81,15 +96,16 @@ class DesktopTasksLimiter (
taskToMinimize.taskId)
return
}
+
this@DesktopTasksLimiter.markTaskMinimized(
taskToMinimize.displayId, taskToMinimize.taskId)
}
/**
- * Returns whether the given Task is being reordered to the back in the given transition, or
- * is already invisible.
+ * Returns whether the Task [taskDetails] is being reordered to the back in the transition
+ * [info], or is already invisible.
*
- * <p> This check can be used to double-check that a task was indeed minimized before
+ * This check can be used to double-check that a task was indeed minimized before
* marking it as such.
*/
private fun isTaskReorderedToBackOrInvisible(
@@ -104,9 +120,21 @@ class DesktopTasksLimiter (
return taskChange.mode == TRANSIT_TO_BACK
}
- override fun onTransitionStarting(transition: IBinder) {}
+ override fun onTransitionStarting(transition: IBinder) {
+ val mActiveTaskDetails = mActiveTransitionTokensAndTasks[transition]
+ if (mActiveTaskDetails != null && mActiveTaskDetails.transitionInfo != null) {
+ // Begin minimize window CUJ instrumentation.
+ interactionJankMonitor.begin(
+ mActiveTaskDetails.transitionInfo?.rootLeash, context,
+ CUJ_DESKTOP_MODE_MINIMIZE_WINDOW
+ )
+ }
+ }
override fun onTransitionMerged(merged: IBinder, playing: IBinder) {
+ if (mActiveTransitionTokensAndTasks.remove(merged) != null) {
+ interactionJankMonitor.end(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW)
+ }
mPendingTransitionTokensAndTasks.remove(merged)?.let { taskToTransfer ->
mPendingTransitionTokensAndTasks[playing] = taskToTransfer
}
@@ -116,6 +144,13 @@ class DesktopTasksLimiter (
ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopTasksLimiter: transition %s finished", transition)
+ if (mActiveTransitionTokensAndTasks.remove(transition) != null) {
+ if (aborted) {
+ interactionJankMonitor.cancel(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW)
+ } else {
+ interactionJankMonitor.end(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW)
+ }
+ }
mPendingTransitionTokensAndTasks.remove(transition)
}
}
@@ -129,8 +164,7 @@ class DesktopTasksLimiter (
}
fun removeLeftoverMinimizedTasks(displayId: Int, wct: WindowContainerTransaction) {
- if (taskRepository
- .getActiveNonMinimizedTasksOrderedFrontToBack(displayId).isNotEmpty()) {
+ if (taskRepository.getActiveNonMinimizedOrderedTasks(displayId).isNotEmpty()) {
return
}
val remainingMinimizedTasks = taskRepository.getMinimizedTasks(displayId)
@@ -139,7 +173,9 @@ class DesktopTasksLimiter (
}
ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
- "DesktopTasksLimiter: removing leftover minimized tasks: $remainingMinimizedTasks")
+ "DesktopTasksLimiter: removing leftover minimized tasks: %s",
+ remainingMinimizedTasks,
+ )
remainingMinimizedTasks.forEach { taskIdToRemove ->
val taskToRemove = shellTaskOrganizer.getRunningTaskInfo(taskIdToRemove)
if (taskToRemove != null) {
@@ -150,8 +186,8 @@ class DesktopTasksLimiter (
}
/**
- * Mark a task as minimized, this should only be done after the corresponding transition has
- * finished so we don't minimize the task if the transition fails.
+ * Mark [taskId], which must be on [displayId], as minimized, this should only be done after the
+ * corresponding transition has finished so we don't minimize the task if the transition fails.
*/
private fun markTaskMinimized(displayId: Int, taskId: Int) {
ProtoLog.v(
@@ -162,11 +198,9 @@ class DesktopTasksLimiter (
/**
* Add a minimize-transition to [wct] if adding [newFrontTaskInfo] brings us over the task
- * limit.
+ * limit, returning the task to minimize.
*
- * @param transition the transition that the minimize-transition will be appended to, or null if
- * the transition will be started later.
- * @return the ID of the minimized task, or null if no task is being minimized.
+ * The task must be on [displayId].
*/
fun addAndGetMinimizeTaskChangesIfNeeded(
displayId: Int,
@@ -178,7 +212,7 @@ class DesktopTasksLimiter (
"DesktopTasksLimiter: addMinimizeBackTaskChangesIfNeeded, newFrontTask=%d",
newFrontTaskInfo.taskId)
val newTaskListOrderedFrontToBack = createOrderedTaskListWithGivenTaskInFront(
- taskRepository.getActiveNonMinimizedTasksOrderedFrontToBack(displayId),
+ taskRepository.getActiveNonMinimizedOrderedTasks(displayId),
newFrontTaskInfo.taskId)
val taskToMinimize = getTaskToMinimizeIfNeeded(newTaskListOrderedFrontToBack)
if (taskToMinimize != null) {
@@ -194,7 +228,7 @@ class DesktopTasksLimiter (
*/
fun addPendingMinimizeChange(transition: IBinder, displayId: Int, taskId: Int) {
minimizeTransitionObserver.addPendingTransitionToken(
- transition, TaskDetails(displayId, taskId))
+ transition, TaskDetails(displayId, taskId, transitionInfo = null))
}
/**
@@ -221,13 +255,15 @@ class DesktopTasksLimiter (
// No need to minimize anything
return null
}
+ val taskIdToMinimize = visibleFreeformTaskIdsOrderedFrontToBack.last()
val taskToMinimize =
- shellTaskOrganizer.getRunningTaskInfo(
- visibleFreeformTaskIdsOrderedFrontToBack.last())
+ shellTaskOrganizer.getRunningTaskInfo(taskIdToMinimize)
if (taskToMinimize == null) {
ProtoLog.e(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
- "DesktopTasksLimiter: taskToMinimize == null")
+ "DesktopTasksLimiter: taskToMinimize(taskId = %d) == null",
+ taskIdToMinimize,
+ )
return null
}
return taskToMinimize
@@ -242,7 +278,5 @@ class DesktopTasksLimiter (
}
@VisibleForTesting
- fun getTransitionObserver(): TransitionObserver {
- return minimizeTransitionObserver
- }
+ fun getTransitionObserver(): TransitionObserver = minimizeTransitionObserver
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index e4aa115347eb..d03a561cd3ea 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -21,11 +21,11 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
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.common.split.SplitScreenUtils.getResizingBackgroundColor;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
@@ -40,6 +40,7 @@ import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
@@ -290,7 +291,7 @@ public class DragLayout extends LinearLayout
final int activityType = taskInfo1.getActivityType();
if (activityType == ACTIVITY_TYPE_STANDARD) {
Drawable icon1 = mIconProvider.getIcon(taskInfo1.topActivityInfo);
- int bgColor1 = getResizingBackgroundColor(taskInfo1).toArgb();
+ int bgColor1 = getResizingBackgroundColor(taskInfo1);
mDropZoneView1.setAppInfo(bgColor1, icon1);
mDropZoneView2.setAppInfo(bgColor1, icon1);
mDropZoneView1.setForceIgnoreBottomMargin(false);
@@ -312,10 +313,10 @@ public class DragLayout extends LinearLayout
mSplitScreenController.getTaskInfo(SPLIT_POSITION_BOTTOM_OR_RIGHT);
if (topOrLeftTask != null && bottomOrRightTask != null) {
Drawable topOrLeftIcon = mIconProvider.getIcon(topOrLeftTask.topActivityInfo);
- int topOrLeftColor = getResizingBackgroundColor(topOrLeftTask).toArgb();
+ int topOrLeftColor = getResizingBackgroundColor(topOrLeftTask);
Drawable bottomOrRightIcon = mIconProvider.getIcon(
bottomOrRightTask.topActivityInfo);
- int bottomOrRightColor = getResizingBackgroundColor(bottomOrRightTask).toArgb();
+ int bottomOrRightColor = getResizingBackgroundColor(bottomOrRightTask);
mDropZoneView1.setAppInfo(topOrLeftColor, topOrLeftIcon);
mDropZoneView2.setAppInfo(bottomOrRightColor, bottomOrRightIcon);
}
@@ -586,6 +587,11 @@ public class DragLayout extends LinearLayout
}
}
+ private static int getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
+ final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
+ return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).toArgb();
+ }
+
/**
* Dumps information about this drag layout.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 4531967d6f93..456767a1c9af 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -99,14 +99,10 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
mDesktopModeTaskRepository.ifPresent(repository -> {
repository.addOrMoveFreeformTaskToTop(taskInfo.displayId, taskInfo.taskId);
- repository.unminimizeTask(taskInfo.displayId, taskInfo.taskId);
if (taskInfo.isVisible) {
- if (repository.addActiveTask(taskInfo.displayId, taskInfo.taskId)) {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
- "Adding active freeform task: #%d", taskInfo.taskId);
- }
- repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId,
- true);
+ repository.addActiveTask(taskInfo.displayId, taskInfo.taskId);
+ repository.updateTaskVisibility(taskInfo.displayId, taskInfo.taskId,
+ /* visible= */ true);
}
});
}
@@ -121,12 +117,6 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
mDesktopModeTaskRepository.ifPresent(repository -> {
repository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId);
- repository.unminimizeTask(taskInfo.displayId, taskInfo.taskId);
- if (repository.removeActiveTask(taskInfo.taskId)) {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
- "Removing active freeform task: #%d", taskInfo.taskId);
- }
- repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId, false);
});
}
mWindowDecorationViewModel.onTaskVanished(taskInfo);
@@ -146,16 +136,11 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
mDesktopModeTaskRepository.ifPresent(repository -> {
if (taskInfo.isVisible) {
- if (repository.addActiveTask(taskInfo.displayId, taskInfo.taskId)) {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
- "Adding active freeform task: #%d", taskInfo.taskId);
- }
- } else if (repository.isClosingTask(taskInfo.taskId)
- && repository.removeClosingTask(taskInfo.taskId)) {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
- "Removing closing freeform task: #%d", taskInfo.taskId);
+ repository.addActiveTask(taskInfo.displayId, taskInfo.taskId);
+ } else if (repository.isClosingTask(taskInfo.taskId)) {
+ repository.removeClosingTask(taskInfo.taskId);
}
- repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId,
+ repository.updateTaskVisibility(taskInfo.displayId, taskInfo.taskId,
taskInfo.isVisible);
});
}
@@ -172,7 +157,6 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
if (DesktopModeStatus.canEnterDesktopMode(mContext) && taskInfo.isFocused) {
mDesktopModeTaskRepository.ifPresent(repository -> {
repository.addOrMoveFreeformTaskToTop(taskInfo.displayId, taskInfo.taskId);
- repository.unminimizeTask(taskInfo.displayId, taskInfo.taskId);
});
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 7451d2251588..284620e7d0c4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -272,6 +272,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
final boolean changed = onDisplayRotationChanged(mContext, outBounds, currentBounds,
mTmpInsetBounds, displayId, fromRotation, toRotation, t);
if (changed) {
+ mMenuController.hideMenu();
// If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the
// movement bounds
mTouchHandler.adjustBoundsForRotation(outBounds, mPipBoundsState.getBounds(),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index df3803d54d9d..999ab95ccb1e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -416,6 +416,17 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
// location now.
mSpringingToTouch = false;
+ // Boost the velocityX if it's zero to forcefully push it towards the nearest edge.
+ // We don't simply change the xEndValue below since the PhysicsAnimator would rely on the
+ // same velocityX to find out which edge to snap to.
+ if (velocityX == 0) {
+ final int motionCenterX = mPipBoundsState
+ .getMotionBoundsState().getBoundsInMotion().centerX();
+ final int displayCenterX = mPipBoundsState
+ .getDisplayBounds().centerX();
+ velocityX = (motionCenterX < displayCenterX) ? -0.001f : 0.001f;
+ }
+
mTemporaryBoundsPhysicsAnimator
.spring(FloatProperties.RECT_WIDTH, getBounds().width(), mSpringConfig)
.spring(FloatProperties.RECT_HEIGHT, getBounds().height(), mSpringConfig)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index b939b169d8bd..94fe286de869 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -44,6 +44,7 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ExternalInterfaceBinder;
+import com.android.wm.shell.common.ImeListener;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SingleInstanceRemoteListener;
@@ -56,7 +57,6 @@ import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.pip.Pip;
-import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
@@ -88,6 +88,7 @@ public class PipController implements ConfigurationChangeListener,
private final TaskStackListenerImpl mTaskStackListener;
private final ShellTaskOrganizer mShellTaskOrganizer;
private final PipTransitionState mPipTransitionState;
+ private final PipTouchHandler mPipTouchHandler;
private final ShellExecutor mMainExecutor;
private final PipImpl mImpl;
private Consumer<Boolean> mOnIsInPipStateChangedListener;
@@ -130,6 +131,7 @@ public class PipController implements ConfigurationChangeListener,
TaskStackListenerImpl taskStackListener,
ShellTaskOrganizer shellTaskOrganizer,
PipTransitionState pipTransitionState,
+ PipTouchHandler pipTouchHandler,
ShellExecutor mainExecutor) {
mContext = context;
mShellCommandHandler = shellCommandHandler;
@@ -144,6 +146,7 @@ public class PipController implements ConfigurationChangeListener,
mShellTaskOrganizer = shellTaskOrganizer;
mPipTransitionState = pipTransitionState;
mPipTransitionState.addPipTransitionStateChangedListener(this);
+ mPipTouchHandler = pipTouchHandler;
mMainExecutor = mainExecutor;
mImpl = new PipImpl();
@@ -168,6 +171,7 @@ public class PipController implements ConfigurationChangeListener,
TaskStackListenerImpl taskStackListener,
ShellTaskOrganizer shellTaskOrganizer,
PipTransitionState pipTransitionState,
+ PipTouchHandler pipTouchHandler,
ShellExecutor mainExecutor) {
if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
@@ -177,7 +181,7 @@ public class PipController implements ConfigurationChangeListener,
return new PipController(context, shellInit, shellCommandHandler, shellController,
displayController, displayInsetsController, pipBoundsState, pipBoundsAlgorithm,
pipDisplayLayoutState, pipScheduler, taskStackListener, shellTaskOrganizer,
- pipTransitionState, mainExecutor);
+ pipTransitionState, pipTouchHandler, mainExecutor);
}
public PipImpl getPipImpl() {
@@ -201,6 +205,13 @@ public class PipController implements ConfigurationChangeListener,
.getDisplayLayout(mPipDisplayLayoutState.getDisplayId()));
}
});
+ mDisplayInsetsController.addInsetsChangedListener(mPipDisplayLayoutState.getDisplayId(),
+ new ImeListener(mDisplayController, mPipDisplayLayoutState.getDisplayId()) {
+ @Override
+ public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+ mPipTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
+ }
+ });
// Allow other outside processes to bind to PiP controller using the key below.
mShellController.addExternalInterface(KEY_EXTRA_SHELL_PIP,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
index ea02de9d9704..83253c6006fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
@@ -134,6 +134,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
private final PhysicsAnimator.SpringConfig mConflictResolutionSpringConfig =
new PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_NO_BOUNCY);
+ @Nullable private Runnable mUpdateMovementBoundsRunnable;
+
private final Consumer<Rect> mUpdateBoundsCallback = (Rect newBounds) -> {
if (mPipBoundsState.getBounds().equals(newBounds)) {
return;
@@ -141,6 +143,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
mMenuController.updateMenuLayout(newBounds);
mPipBoundsState.setBounds(newBounds);
+ maybeUpdateMovementBounds();
};
/**
@@ -416,6 +419,17 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
// location now.
mSpringingToTouch = false;
+ // Boost the velocityX if it's zero to forcefully push it towards the nearest edge.
+ // We don't simply change the xEndValue below since the PhysicsAnimator would rely on the
+ // same velocityX to find out which edge to snap to.
+ if (velocityX == 0) {
+ final int motionCenterX = mPipBoundsState
+ .getMotionBoundsState().getBoundsInMotion().centerX();
+ final int displayCenterX = mPipBoundsState
+ .getDisplayBounds().centerX();
+ velocityX = (motionCenterX < displayCenterX) ? -0.001f : 0.001f;
+ }
+
mTemporaryBoundsPhysicsAnimator
.spring(FloatProperties.RECT_WIDTH, getBounds().width(), mSpringConfig)
.spring(FloatProperties.RECT_HEIGHT, getBounds().height(), mSpringConfig)
@@ -555,11 +569,20 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
+ " callers=\n%s", TAG, originalBounds, offset,
Debug.getCallers(5, " "));
}
+ if (offset == 0) {
+ return;
+ }
+
cancelPhysicsAnimation();
- /*
- mPipTaskOrganizer.scheduleOffsetPip(originalBounds, offset, SHIFT_DURATION,
- mUpdateBoundsCallback);
- */
+
+ Rect adjustedBounds = new Rect(originalBounds);
+ adjustedBounds.offset(0, offset);
+
+ setAnimatingToBounds(adjustedBounds);
+ Bundle extra = new Bundle();
+ extra.putBoolean(ANIMATING_BOUNDS_CHANGE, true);
+ extra.putInt(ANIMATING_BOUNDS_CHANGE_DURATION, SHIFT_DURATION);
+ mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra);
}
/**
@@ -574,11 +597,11 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
/** Set new fling configs whose min/max values respect the given movement bounds. */
private void rebuildFlingConfigs() {
mFlingConfigX = new PhysicsAnimator.FlingConfig(DEFAULT_FRICTION,
- mPipBoundsAlgorithm.getMovementBounds(getBounds()).left,
- mPipBoundsAlgorithm.getMovementBounds(getBounds()).right);
+ mPipBoundsState.getMovementBounds().left,
+ mPipBoundsState.getMovementBounds().right);
mFlingConfigY = new PhysicsAnimator.FlingConfig(DEFAULT_FRICTION,
- mPipBoundsAlgorithm.getMovementBounds(getBounds()).top,
- mPipBoundsAlgorithm.getMovementBounds(getBounds()).bottom);
+ mPipBoundsState.getMovementBounds().top,
+ mPipBoundsState.getMovementBounds().bottom);
final Rect insetBounds = mPipBoundsState.getDisplayLayout().stableInsets();
mStashConfigX = new PhysicsAnimator.FlingConfig(
DEFAULT_FRICTION,
@@ -660,6 +683,16 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
cleanUpHighPerfSessionMaybe();
}
+ void setUpdateMovementBoundsRunnable(Runnable updateMovementBoundsRunnable) {
+ mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
+ }
+
+ private void maybeUpdateMovementBounds() {
+ if (mUpdateMovementBoundsRunnable != null) {
+ mUpdateMovementBoundsRunnable.run();
+ }
+ }
+
/**
* Notifies the floating coordinator that we're moving, and sets the animating to bounds so
* we return these bounds from
@@ -796,8 +829,14 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(),
destinationBounds, duration, 0f /* angle */);
animator.setAnimationEndCallback(() -> {
- mPipBoundsState.setBounds(destinationBounds);
- // All motion operations have actually finished, so make bounds cache updates.
+ mUpdateBoundsCallback.accept(destinationBounds);
+
+ // In case an ongoing drag/fling was present before a deterministic resize transition
+ // kicked in, we need to update the update bounds properly before cleaning in-motion
+ // state.
+ mPipBoundsState.getMotionBoundsState().setBoundsInMotion(destinationBounds);
+ settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */);
+
cleanUpHighPerfSessionMaybe();
// Signal that we are done with resize transition
mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */);
@@ -806,7 +845,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
}
private void settlePipBoundsAfterPhysicsAnimation(boolean animatingAfter) {
- if (!animatingAfter) {
+ if (!animatingAfter && mPipBoundsState.getMotionBoundsState().isInMotion()) {
// The physics animation ended, though we may not necessarily be done animating, such as
// when we're still dragging after moving out of the magnetic target. Only set the final
// bounds state and clear motion bounds completely if the whole animation is over.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
index 5b0ca1837a1c..d28204add0ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
@@ -146,8 +146,8 @@ public class PipResizeGestureHandler implements
mUpdateResizeBoundsCallback = (rect) -> {
mUserResizeBounds.set(rect);
// mMotionHelper.synchronizePinnedStackBounds();
- mUpdateMovementBoundsRunnable.run();
mPipBoundsState.setBounds(rect);
+ mUpdateMovementBoundsRunnable.run();
resetState();
};
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
index 53b80e8b7542..f387e72b3da6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -199,6 +199,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
mMenuController.addListener(new PipMenuListener());
mGesture = new DefaultPipTouchGesture();
mMotionHelper = pipMotionHelper;
+ mMotionHelper.setUpdateMovementBoundsRunnable(this::updateMovementBounds);
mPipDismissTargetHandler = new PipDismissTargetHandler(context, pipUiEventLogger,
mMotionHelper, mainExecutor);
mTouchState = new PipTouchState(ViewConfiguration.get(context),
@@ -317,6 +318,8 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
mFloatingContentCoordinator.onContentRemoved(mMotionHelper);
mPipResizeGestureHandler.onActivityUnpinned();
mPipInputConsumer.unregisterInputConsumer();
+ mPipBoundsState.setHasUserMovedPip(false);
+ mPipBoundsState.setHasUserResizedPip(false);
}
void onPinnedStackAnimationEnded(
@@ -346,6 +349,22 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
mIsImeShowing = imeVisible;
mImeHeight = imeHeight;
+
+ // Cache new movement bounds using the new potential IME height.
+ updateMovementBounds();
+
+ mPipTransitionState.setOnIdlePipTransitionStateRunnable(() -> {
+ int delta = mPipBoundsState.getMovementBounds().bottom
+ - mPipBoundsState.getBounds().top;
+
+ boolean hasUserInteracted = (mPipBoundsState.hasUserMovedPip()
+ || mPipBoundsState.hasUserResizedPip());
+ if ((imeVisible && delta < 0) || (!imeVisible && !hasUserInteracted)) {
+ // The policy is to ignore an IME disappearing if user has interacted with PiP.
+ // Otherwise, only offset due to an appearing IME if PiP occludes it.
+ mMotionHelper.animateToOffset(mPipBoundsState.getBounds(), delta);
+ }
+ });
}
void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
@@ -1077,6 +1096,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
switch (newState) {
case PipTransitionState.ENTERED_PIP:
onActivityPinned();
+ updateMovementBounds();
mTouchState.setAllowInputEvents(true);
mTouchState.reset();
break;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
index 29272be6e9bd..a132796f4a84 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
@@ -149,6 +149,12 @@ public class PipTransitionState {
@Nullable
private SurfaceControl mSwipePipToHomeOverlay;
+ //
+ // Scheduling-related state
+ //
+ @Nullable
+ private Runnable mOnIdlePipTransitionStateRunnable;
+
/**
* An interface to track state updates as we progress through PiP transitions.
*/
@@ -197,6 +203,8 @@ public class PipTransitionState {
mState = state;
dispatchPipTransitionStateChanged(prevState, mState, extra);
}
+
+ maybeRunOnIdlePipTransitionStateCallback();
}
/**
@@ -231,6 +239,29 @@ public class PipTransitionState {
}
/**
+ * Schedule a callback to run when in a valid idle PiP state.
+ *
+ * <p>We only allow for one callback to be scheduled to avoid cases with multiple transitions
+ * being scheduled. For instance, if user double taps and IME shows, this would
+ * schedule a bounds change transition for IME appearing. But if some other transition would
+ * want to animate PiP before the scheduled callback executes, we would rather want to replace
+ * the existing callback with a new one, to avoid multiple animations
+ * as soon as we are idle.</p>
+ */
+ public void setOnIdlePipTransitionStateRunnable(
+ @Nullable Runnable onIdlePipTransitionStateRunnable) {
+ mOnIdlePipTransitionStateRunnable = onIdlePipTransitionStateRunnable;
+ maybeRunOnIdlePipTransitionStateCallback();
+ }
+
+ private void maybeRunOnIdlePipTransitionStateCallback() {
+ if (mOnIdlePipTransitionStateRunnable != null && isPipStateIdle()) {
+ mOnIdlePipTransitionStateRunnable.run();
+ mOnIdlePipTransitionStateRunnable = null;
+ }
+ }
+
+ /**
* Adds a {@link PipTransitionStateChangedListener} for future PiP transition state updates.
*/
public void addPipTransitionStateChangedListener(PipTransitionStateChangedListener listener) {
@@ -318,6 +349,11 @@ public class PipTransitionState {
throw new IllegalStateException("Unknown state: " + state);
}
+ public boolean isPipStateIdle() {
+ // This needs to be a valid in-PiP state that isn't a transient state.
+ return mState == ENTERED_PIP || mState == CHANGED_PIP_BOUNDS;
+ }
+
@Override
public String toString() {
return String.format("PipTransitionState(mState=%s, mInSwipePipToHomeTransition=%b)",
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index d7ee563b562c..2531ff150f43 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -41,7 +41,6 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.common.split.SplitScreenConstants.splitPositionToString;
-import static com.android.wm.shell.common.split.SplitScreenUtils.getResizingBackgroundColor;
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
import static com.android.wm.shell.common.split.SplitScreenUtils.splitFailureMessage;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
@@ -2458,13 +2457,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
updateSurfaceBounds(layout, t, shouldUseParallaxEffect);
getMainStageBounds(mTempRect1);
getSideStageBounds(mTempRect2);
- // TODO (b/307490004): "commonColor" below is a temporary fix to ensure the colors on both
- // sides match. When b/307490004 is fixed, this code can be reverted.
- float[] commonColor = getResizingBackgroundColor(mSideStage.mRootTaskInfo).getComponents();
- mMainStage.onResizing(
- mTempRect1, mTempRect2, t, offsetX, offsetY, mShowDecorImmediately, commonColor);
- mSideStage.onResizing(
- mTempRect2, mTempRect1, t, offsetX, offsetY, mShowDecorImmediately, commonColor);
+ mMainStage.onResizing(mTempRect1, mTempRect2, t, offsetX, offsetY, mShowDecorImmediately);
+ mSideStage.onResizing(mTempRect2, mTempRect1, t, offsetX, offsetY, mShowDecorImmediately);
t.apply();
mTransactionPool.release(t);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 1076eca60369..d1ab3e96d4c2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -314,10 +314,10 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
}
void onResizing(Rect newBounds, Rect sideBounds, SurfaceControl.Transaction t, int offsetX,
- int offsetY, boolean immediately, float[] veilColor) {
+ int offsetY, boolean immediately) {
if (mSplitDecorManager != null && mRootTaskInfo != null) {
mSplitDecorManager.onResizing(mRootTaskInfo, newBounds, sideBounds, t, offsetX,
- offsetY, immediately, veilColor);
+ offsetY, immediately);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
index e6d1b4593a46..15fe7abb96a5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
@@ -217,6 +217,11 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
return null;
}
+ /** Returns true if the given {@code taskInfo} belongs to a task view. */
+ public boolean isTaskViewTask(ActivityManager.RunningTaskInfo taskInfo) {
+ return findTaskView(taskInfo) != null;
+ }
+
void startTaskView(@NonNull WindowContainerTransaction wct,
@NonNull TaskViewTaskController taskView, @NonNull IBinder launchCookie) {
updateVisibilityState(taskView, true /* visible */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 5c230c0a505c..d8dba71c0a4f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -33,6 +33,7 @@ import android.graphics.Region;
import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.SparseArray;
@@ -288,6 +289,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
final CaptionWindowDecoration windowDecoration =
new CaptionWindowDecoration(
mContext,
+ mContext.createContextAsUser(UserHandle.of(taskInfo.userId), 0 /* flags */),
mDisplayController,
mTaskOrganizer,
taskInfo,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index cf42a49f7103..de514f661d01 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -77,6 +77,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
CaptionWindowDecoration(
Context context,
+ @NonNull Context userContext,
DisplayController displayController,
ShellTaskOrganizer taskOrganizer,
RunningTaskInfo taskInfo,
@@ -85,7 +86,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
@ShellBackgroundThread ShellExecutor bgExecutor,
Choreographer choreographer,
SyncTransactionQueue syncQueue) {
- super(context, displayController, taskOrganizer, taskInfo, taskSurface);
+ super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface);
mHandler = handler;
mBgExecutor = bgExecutor;
mChoreographer = choreographer;
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 0ff35226b77e..7c8f205ce78f 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
@@ -59,6 +59,7 @@ import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
import android.view.Choreographer;
@@ -1149,6 +1150,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
final DesktopModeWindowDecoration windowDecoration =
mDesktopModeWindowDecorFactory.create(
mContext,
+ mContext.createContextAsUser(UserHandle.of(taskInfo.userId), 0 /* flags */),
mDisplayController,
mSplitScreenController,
mTaskOrganizer,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 41f428b6ca83..e82990f9fe1d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -160,6 +160,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
DesktopModeWindowDecoration(
Context context,
+ @NonNull Context userContext,
DisplayController displayController,
SplitScreenController splitScreenController,
ShellTaskOrganizer taskOrganizer,
@@ -171,8 +172,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
SyncTransactionQueue syncQueue,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
AppToWebGenericLinksParser genericLinksParser) {
- this (context, displayController, splitScreenController, taskOrganizer, taskInfo,
- taskSurface, handler, bgExecutor, choreographer, syncQueue,
+ this (context, userContext, displayController, splitScreenController, taskOrganizer,
+ taskInfo, taskSurface, handler, bgExecutor, choreographer, syncQueue,
rootTaskDisplayAreaOrganizer, genericLinksParser, SurfaceControl.Builder::new,
SurfaceControl.Transaction::new, WindowContainerTransaction::new,
SurfaceControl::new, new SurfaceControlViewHostFactory() {},
@@ -181,6 +182,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
DesktopModeWindowDecoration(
Context context,
+ @NonNull Context userContext,
DisplayController displayController,
SplitScreenController splitScreenController,
ShellTaskOrganizer taskOrganizer,
@@ -199,7 +201,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
SurfaceControlViewHostFactory surfaceControlViewHostFactory,
MaximizeMenuFactory maximizeMenuFactory,
HandleMenuFactory handleMenuFactory) {
- super(context, displayController, taskOrganizer, taskInfo, taskSurface,
+ super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface,
surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
windowContainerTransactionSupplier, surfaceControlSupplier,
surfaceControlViewHostFactory);
@@ -737,12 +739,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
Slog.e(TAG, "Base activity component not found in task");
return;
}
- final PackageManager pm = mContext.getApplicationContext().getPackageManager();
- final ActivityInfo activityInfo = pm.getActivityInfo(baseActivity,
- // Include uninstalled apps. Despite its name, adding this flag is a workaround
- // to #getActivityInfo throwing a NameNotFoundException for installed packages
- // when HSUM is enabled. See b/354884302.
- PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ final PackageManager pm = mUserContext.getPackageManager();
+ final ActivityInfo activityInfo = pm.getActivityInfo(baseActivity, 0 /* flags */);
final IconProvider provider = new IconProvider(mContext);
final Drawable appIconDrawable = provider.getIcon(activityInfo);
final BaseIconFactory headerIconFactory = createIconFactory(mContext,
@@ -1264,6 +1262,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
DesktopModeWindowDecoration create(
Context context,
+ @NonNull Context userContext,
DisplayController displayController,
SplitScreenController splitScreenController,
ShellTaskOrganizer taskOrganizer,
@@ -1277,6 +1276,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
AppToWebGenericLinksParser genericLinksParser) {
return new DesktopModeWindowDecoration(
context,
+ userContext,
displayController,
splitScreenController,
taskOrganizer,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 3b8657d4adf5..68285602a26e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -106,6 +106,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
* System-wide context. Only used to create context with overridden configurations.
*/
final Context mContext;
+ final @NonNull Context mUserContext;
final @NonNull DisplayController mDisplayController;
final ShellTaskOrganizer mTaskOrganizer;
final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
@@ -147,11 +148,12 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
WindowDecoration(
Context context,
+ @NonNull Context userContext,
DisplayController displayController,
ShellTaskOrganizer taskOrganizer,
RunningTaskInfo taskInfo,
SurfaceControl taskSurface) {
- this(context, displayController, taskOrganizer, taskInfo, taskSurface,
+ this(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface,
SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
WindowContainerTransaction::new, SurfaceControl::new,
new SurfaceControlViewHostFactory() {});
@@ -159,6 +161,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
WindowDecoration(
Context context,
+ @NonNull Context userContext,
@NonNull DisplayController displayController,
ShellTaskOrganizer taskOrganizer,
RunningTaskInfo taskInfo,
@@ -169,6 +172,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
Supplier<SurfaceControl> surfaceControlSupplier,
SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
mContext = context;
+ mUserContext = userContext;
mDisplayController = displayController;
mTaskOrganizer = taskOrganizer;
mTaskInfo = taskInfo;
@@ -177,7 +181,6 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier;
mWindowContainerTransactionSupplier = windowContainerTransactionSupplier;
mSurfaceControlViewHostFactory = surfaceControlViewHostFactory;
-
mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index e91828be4ebe..716a148175df 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -16,10 +16,6 @@
package com.android.wm.shell;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_DISMISSED;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
@@ -443,84 +439,6 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
}
@Test
- public void testOnCameraCompatActivityChanged() {
- final RunningTaskInfo taskInfo1 = createTaskInfo(/* taskId= */ 1,
- WINDOWING_MODE_FULLSCREEN);
- taskInfo1.displayId = DEFAULT_DISPLAY;
- taskInfo1.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- CAMERA_COMPAT_CONTROL_HIDDEN;
- final TrackingTaskListener taskListener = new TrackingTaskListener();
- mOrganizer.addListenerForType(taskListener, TASK_LISTENER_TYPE_FULLSCREEN);
- mOrganizer.onTaskAppeared(taskInfo1, /* leash= */ null);
-
- // Task listener sent to compat UI is null if top activity doesn't request a camera
- // compat control.
- verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
-
- // Task listener is non-null when request a camera compat control for a visible task.
- clearInvocations(mCompatUI);
- final RunningTaskInfo taskInfo2 =
- createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
- taskInfo2.displayId = taskInfo1.displayId;
- taskInfo2.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- taskInfo2.isVisible = true;
- mOrganizer.onTaskInfoChanged(taskInfo2);
- verifyOnCompatInfoChangedInvokedWith(taskInfo2, taskListener);
-
- // CompatUIController#onCompatInfoChanged is called when requested state for a camera
- // compat control changes for a visible task.
- clearInvocations(mCompatUI);
- final RunningTaskInfo taskInfo3 =
- createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
- taskInfo3.displayId = taskInfo1.displayId;
- taskInfo3.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
- taskInfo3.isVisible = true;
- mOrganizer.onTaskInfoChanged(taskInfo3);
- verifyOnCompatInfoChangedInvokedWith(taskInfo3, taskListener);
-
- // CompatUIController#onCompatInfoChanged is called when a top activity goes in size compat
- // mode for a visible task that has a compat control.
- clearInvocations(mCompatUI);
- final RunningTaskInfo taskInfo4 =
- createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
- taskInfo4.displayId = taskInfo1.displayId;
- taskInfo4.appCompatTaskInfo.topActivityInSizeCompat = true;
- taskInfo4.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
- taskInfo4.isVisible = true;
- mOrganizer.onTaskInfoChanged(taskInfo4);
- verifyOnCompatInfoChangedInvokedWith(taskInfo4, taskListener);
-
- // Task linster is null when a camera compat control is dimissed for a visible task.
- clearInvocations(mCompatUI);
- final RunningTaskInfo taskInfo5 =
- createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
- taskInfo5.displayId = taskInfo1.displayId;
- taskInfo5.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- CAMERA_COMPAT_CONTROL_DISMISSED;
- taskInfo5.isVisible = true;
- mOrganizer.onTaskInfoChanged(taskInfo5);
- verifyOnCompatInfoChangedInvokedWith(taskInfo5, null /* taskListener */);
-
- // Task linster is null when request a camera compat control for a invisible task.
- clearInvocations(mCompatUI);
- final RunningTaskInfo taskInfo6 =
- createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
- taskInfo6.displayId = taskInfo1.displayId;
- taskInfo6.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- taskInfo6.isVisible = false;
- mOrganizer.onTaskInfoChanged(taskInfo6);
- verifyOnCompatInfoChangedInvokedWith(taskInfo6, null /* taskListener */);
-
- clearInvocations(mCompatUI);
- mOrganizer.onTaskVanished(taskInfo1);
- verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
- }
-
- @Test
public void testAddLocusListener() {
RunningTaskInfo task1 = createTaskInfo(/* taskId= */ 1, WINDOWING_MODE_MULTI_WINDOW);
task1.isVisible = true;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
index 2c0aa12f22d2..764d5a97e3e1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
@@ -83,7 +83,7 @@ public class DisplayImeControllerTest extends ShellTestCase {
}
}, mExecutor) {
@Override
- void removeImeSurface() { }
+ void removeImeSurface(int displayId) { }
}.new PerDisplay(DEFAULT_DISPLAY, ROTATION_0);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/ImeListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/ImeListenerTest.kt
new file mode 100644
index 000000000000..3b0a0722968b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/ImeListenerTest.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2024 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.common
+
+import android.content.res.Configuration
+import android.content.res.Resources
+import android.graphics.Insets
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.view.DisplayCutout
+import android.view.DisplayInfo
+import android.view.InsetsSource.ID_IME
+import android.view.InsetsState
+import android.view.Surface
+import android.view.WindowInsets.Type
+import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.wm.shell.ShellTestCase
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.kotlin.whenever
+
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ImeListenerTest : ShellTestCase() {
+ private lateinit var imeListener: CachingImeListener
+ private lateinit var displayLayout: DisplayLayout
+
+ @Mock private lateinit var displayController: DisplayController
+ @Before
+ fun setUp() {
+ val resources = createResources(40, 50, false)
+ val displayInfo = createDisplayInfo(1000, 1500, 0, Surface.ROTATION_0)
+ displayLayout = DisplayLayout(displayInfo, resources, false, false)
+ whenever(displayController.getDisplayLayout(DEFAULT_DISPLAY_ID)).thenReturn(displayLayout)
+ imeListener = CachingImeListener(displayController, DEFAULT_DISPLAY_ID)
+ }
+
+ @Test
+ fun testImeAppears() {
+ val insetsState = createInsetsStateWithIme(true, DEFAULT_IME_HEIGHT)
+ imeListener.insetsChanged(insetsState)
+ assertTrue("Ime insets source should become visible", imeListener.cachedImeVisible)
+ assertEquals(DEFAULT_IME_HEIGHT, imeListener.cachedImeHeight)
+ }
+
+ @Test
+ fun testImeAppears_thenDisappears() {
+ // Send insetsState with an IME as a visible source.
+ val insetsStateWithIme = createInsetsStateWithIme(true, DEFAULT_IME_HEIGHT)
+ imeListener.insetsChanged(insetsStateWithIme)
+
+ // Send insetsState without IME.
+ val insetsStateWithoutIme = createInsetsStateWithIme(false, 0)
+ imeListener.insetsChanged(insetsStateWithoutIme)
+
+ assertFalse("Ime insets source should become invisible",
+ imeListener.cachedImeVisible)
+ assertEquals(0, imeListener.cachedImeHeight)
+ }
+
+ private fun createInsetsStateWithIme(isVisible: Boolean, imeHeight: Int): InsetsState {
+ val stableBounds = Rect()
+ displayLayout.getStableBounds(stableBounds)
+ val insetsState = InsetsState()
+
+ val insetsSource = insetsState.getOrCreateSource(ID_IME, Type.ime())
+ insetsSource.setVisible(isVisible)
+ insetsSource.setFrame(stableBounds.left, stableBounds.bottom - imeHeight,
+ stableBounds.right, stableBounds.bottom)
+ return insetsState
+ }
+
+ private fun createDisplayInfo(width: Int, height: Int, cutoutHeight: Int,
+ rotation: Int): DisplayInfo {
+ val info = DisplayInfo()
+ info.logicalWidth = width
+ info.logicalHeight = height
+ info.rotation = rotation
+ if (cutoutHeight > 0) {
+ info.displayCutout = DisplayCutout(
+ Insets.of(0, cutoutHeight, 0, 0) /* safeInsets */,
+ null /* boundLeft */,
+ Rect(width / 2 - cutoutHeight, 0, width / 2 + cutoutHeight,
+ cutoutHeight) /* boundTop */, null /* boundRight */,
+ null /* boundBottom */)
+ } else {
+ info.displayCutout = DisplayCutout.NO_CUTOUT
+ }
+ info.logicalDensityDpi = 300
+ return info
+ }
+
+ private fun createResources(navLand: Int, navPort: Int, navMoves: Boolean): Resources {
+ val cfg = Configuration()
+ cfg.uiMode = Configuration.UI_MODE_TYPE_NORMAL
+ val res = Mockito.mock(Resources::class.java)
+ Mockito.doReturn(navLand).whenever(res).getDimensionPixelSize(
+ R.dimen.navigation_bar_height_landscape_car_mode)
+ Mockito.doReturn(navPort).whenever(res).getDimensionPixelSize(
+ R.dimen.navigation_bar_height_car_mode)
+ Mockito.doReturn(navLand).whenever(res).getDimensionPixelSize(
+ R.dimen.navigation_bar_width_car_mode)
+ Mockito.doReturn(navLand).whenever(res).getDimensionPixelSize(
+ R.dimen.navigation_bar_height_landscape)
+ Mockito.doReturn(navPort).whenever(res).getDimensionPixelSize(
+ R.dimen.navigation_bar_height)
+ Mockito.doReturn(navLand).whenever(res).getDimensionPixelSize(
+ R.dimen.navigation_bar_width)
+ Mockito.doReturn(navMoves).whenever(res).getBoolean(R.bool.config_navBarCanMove)
+ Mockito.doReturn(cfg).whenever(res).configuration
+ return res
+ }
+
+ private class CachingImeListener(
+ displayController: DisplayController,
+ displayId: Int
+ ) : ImeListener(displayController, displayId) {
+ var cachedImeVisible = false
+ var cachedImeHeight = 0
+ public override fun onImeVisibilityChanged(imeVisible: Boolean, imeHeight: Int) {
+ cachedImeVisible = imeVisible
+ cachedImeHeight = imeHeight
+ }
+ }
+
+ companion object {
+ private const val DEFAULT_DISPLAY_ID = 0
+ private const val DEFAULT_IME_HEIGHT = 500
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index fc7a7770b8ca..77e22cd17f6f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -16,8 +16,6 @@
package com.android.wm.shell.compatui;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
import static android.view.WindowInsets.Type.navigationBars;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -34,7 +32,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager.RunningTaskInfo;
-import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.content.Context;
import android.content.res.Configuration;
@@ -199,8 +196,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@Test
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnCompatInfoChanged() {
- TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_HIDDEN);
+ TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
// Verify that the compat controls are added with non-null task listener.
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
@@ -214,8 +210,7 @@ public class CompatUIControllerTest extends ShellTestCase {
// Verify that the compat controls and letterbox education are updated with new size compat
// info.
clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
- taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
+ taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
@@ -228,7 +223,7 @@ public class CompatUIControllerTest extends ShellTestCase {
// Verify that compat controls and letterbox education are removed with null task listener.
clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN),
+ /* hasSizeCompat= */ true),
/* taskListener= */ null));
verify(mMockCompatLayout).release();
@@ -243,8 +238,7 @@ public class CompatUIControllerTest extends ShellTestCase {
doReturn(false).when(mMockLetterboxEduLayout).createLayout(anyBoolean());
doReturn(false).when(mMockRestartDialogLayout).createLayout(anyBoolean());
- TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_HIDDEN);
+ TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
@@ -274,8 +268,7 @@ public class CompatUIControllerTest extends ShellTestCase {
doReturn(false).when(mMockLetterboxEduLayout).updateCompatInfo(any(), any(), anyBoolean());
doReturn(false).when(mMockRestartDialogLayout).updateCompatInfo(any(), any(), anyBoolean());
- TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_HIDDEN);
+ TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
@@ -326,7 +319,7 @@ public class CompatUIControllerTest extends ShellTestCase {
public void testOnDisplayRemoved() {
mController.onDisplayAdded(DISPLAY_ID);
mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
+ /* hasSizeCompat= */ true), mMockTaskListener));
mController.onDisplayRemoved(DISPLAY_ID + 1);
@@ -348,7 +341,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnDisplayConfigurationChanged() {
mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
+ /* hasSizeCompat= */ true), mMockTaskListener));
mController.onDisplayConfigurationChanged(DISPLAY_ID + 1, new Configuration());
@@ -368,7 +361,7 @@ public class CompatUIControllerTest extends ShellTestCase {
public void testInsetsChanged() {
mController.onDisplayAdded(DISPLAY_ID);
mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
+ /* hasSizeCompat= */ true), mMockTaskListener));
InsetsState insetsState = new InsetsState();
InsetsSource insetsSource = new InsetsSource(
InsetsSource.createId(null, 0, navigationBars()), navigationBars());
@@ -395,7 +388,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testChangeLayoutsVisibilityOnImeShowHide() {
mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
+ /* hasSizeCompat= */ true), mMockTaskListener));
// Verify that the restart button is hidden after IME is showing.
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
@@ -405,8 +398,7 @@ public class CompatUIControllerTest extends ShellTestCase {
verify(mMockRestartDialogLayout).updateVisibility(false);
// Verify button remains hidden while IME is showing.
- TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_HIDDEN);
+ TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
@@ -428,7 +420,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testChangeLayoutsVisibilityOnKeyguardShowingChanged() {
mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
+ /* hasSizeCompat= */ true), mMockTaskListener));
// Verify that the restart button is hidden after keyguard becomes showing.
mController.onKeyguardVisibilityChanged(true, false, false);
@@ -438,8 +430,7 @@ public class CompatUIControllerTest extends ShellTestCase {
verify(mMockRestartDialogLayout).updateVisibility(false);
// Verify button remains hidden while keyguard is showing.
- TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_HIDDEN);
+ TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
@@ -461,7 +452,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testLayoutsRemainHiddenOnKeyguardShowingFalseWhenImeIsShowing() {
mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
+ /* hasSizeCompat= */ true), mMockTaskListener));
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
mController.onKeyguardVisibilityChanged(true, false, false);
@@ -491,7 +482,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testLayoutsRemainHiddenOnImeHideWhenKeyguardIsShowing() {
mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
+ /* hasSizeCompat= */ true), mMockTaskListener));
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
mController.onKeyguardVisibilityChanged(true, false, false);
@@ -520,8 +511,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@Test
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRestartLayoutRecreatedIfNeeded() {
- final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN);
+ final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
doReturn(true).when(mMockRestartDialogLayout)
.needsToBeRecreated(any(TaskInfo.class),
any(ShellTaskOrganizer.TaskListener.class));
@@ -536,8 +526,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@Test
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRestartLayoutNotRecreatedIfNotNeeded() {
- final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN);
+ final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
doReturn(false).when(mMockRestartDialogLayout)
.needsToBeRecreated(any(TaskInfo.class),
any(ShellTaskOrganizer.TaskListener.class));
@@ -557,9 +546,8 @@ public class CompatUIControllerTest extends ShellTestCase {
Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
// Create new task
- final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
- /* isFocused */ true);
+ final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
+ /* isVisible */ true, /* isFocused */ true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo);
@@ -574,9 +562,8 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateActiveTaskInfo_newTask_notVisibleOrFocused_notUpdated() {
// Create new task
- final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
- /* isFocused */ true);
+ final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
+ /* isVisible */ true, /* isFocused */ true);
// Simulate task being shown
mController.updateActiveTaskInfo(taskInfo);
@@ -593,9 +580,8 @@ public class CompatUIControllerTest extends ShellTestCase {
final int newTaskId = TASK_ID + 1;
// Create visible but NOT focused task
- final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
- /* isFocused */ false);
+ final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
+ /* isVisible */ true, /* isFocused */ false);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo1);
@@ -606,9 +592,8 @@ public class CompatUIControllerTest extends ShellTestCase {
Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
// Create focused but NOT visible task
- final TaskInfo taskInfo2 = createTaskInfo(DISPLAY_ID, newTaskId,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ false,
- /* isFocused */ true);
+ final TaskInfo taskInfo2 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
+ /* isVisible */ false, /* isFocused */ true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo2);
@@ -619,9 +604,8 @@ public class CompatUIControllerTest extends ShellTestCase {
Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
// Create NOT focused but NOT visible task
- final TaskInfo taskInfo3 = createTaskInfo(DISPLAY_ID, newTaskId,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ false,
- /* isFocused */ false);
+ final TaskInfo taskInfo3 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
+ /* isVisible */ false, /* isFocused */ false);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo3);
@@ -636,9 +620,8 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateActiveTaskInfo_sameTask_notUpdated() {
// Create new task
- final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
- /* isFocused */ true);
+ final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
+ /* isVisible */ true, /* isFocused */ true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo);
@@ -665,9 +648,8 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateActiveTaskInfo_transparentTask_notUpdated() {
// Create new task
- final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
- /* isFocused */ true);
+ final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
+ /* isVisible */ true, /* isFocused */ true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo);
@@ -684,9 +666,8 @@ public class CompatUIControllerTest extends ShellTestCase {
final int newTaskId = TASK_ID + 1;
// Create transparent task
- final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
- /* isFocused */ true, /* isTopActivityTransparent */ true);
+ final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
+ /* isVisible */ true, /* isFocused */ true, /* isTopActivityTransparent */ true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo1);
@@ -699,8 +680,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@Test
public void testLetterboxEduLayout_notCreatedWhenLetterboxEducationIsDisabled() {
- TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_HIDDEN);
+ TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
taskInfo.appCompatTaskInfo.isLetterboxEducationEnabled = false;
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
@@ -709,29 +689,23 @@ public class CompatUIControllerTest extends ShellTestCase {
eq(mMockTaskListener));
}
- private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
- @CameraCompatControlState int cameraCompatControlState) {
- return createTaskInfo(displayId, taskId, hasSizeCompat, cameraCompatControlState,
- /* isVisible */ false, /* isFocused */ false,
- /* isTopActivityTransparent */ false);
+ private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat) {
+ return createTaskInfo(displayId, taskId, hasSizeCompat, /* isVisible */ false,
+ /* isFocused */ false, /* isTopActivityTransparent */ false);
}
private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
- @CameraCompatControlState int cameraCompatControlState, boolean isVisible,
- boolean isFocused) {
- return createTaskInfo(displayId, taskId, hasSizeCompat, cameraCompatControlState,
+ boolean isVisible, boolean isFocused) {
+ return createTaskInfo(displayId, taskId, hasSizeCompat,
isVisible, isFocused, /* isTopActivityTransparent */ false);
}
private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
- @CameraCompatControlState int cameraCompatControlState, boolean isVisible,
- boolean isFocused, boolean isTopActivityTransparent) {
+ boolean isVisible, boolean isFocused, boolean isTopActivityTransparent) {
RunningTaskInfo taskInfo = new RunningTaskInfo();
taskInfo.taskId = taskId;
taskInfo.displayId = displayId;
taskInfo.appCompatTaskInfo.topActivityInSizeCompat = hasSizeCompat;
- taskInfo.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- cameraCompatControlState;
taskInfo.isVisible = isVisible;
taskInfo.isFocused = isFocused;
taskInfo.isTopActivityTransparent = isTopActivityTransparent;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
index 33d69f5c34c8..3b93861d6cd2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
@@ -16,20 +16,13 @@
package com.android.wm.shell.compatui;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_DISMISSED;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
-
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
-import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.graphics.Rect;
import android.platform.test.annotations.RequiresFlagsDisabled;
@@ -52,7 +45,6 @@ import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
import com.android.wm.shell.compatui.api.CompatUIEvent;
-import com.android.wm.shell.compatui.impl.CompatUIEvents;
import junit.framework.Assert;
@@ -97,7 +89,7 @@ public class CompatUILayoutTest extends ShellTestCase {
public void setUp() {
MockitoAnnotations.initMocks(this);
doReturn(100).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
- mTaskInfo = createTaskInfo(/* hasSizeCompat= */ false, CAMERA_COMPAT_CONTROL_HIDDEN);
+ mTaskInfo = createTaskInfo(/* hasSizeCompat= */ false);
mWindowManager = new CompatUIWindowManager(mContext, mTaskInfo, mSyncTransactionQueue,
mCallback, mTaskListener, new DisplayLayout(), new CompatUIHintsState(),
mCompatUIConfiguration, mOnRestartButtonClicked);
@@ -151,113 +143,13 @@ public class CompatUILayoutTest extends ShellTestCase {
verify(mLayout).setSizeCompatHintVisibility(/* show= */ false);
}
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testUpdateCameraTreatmentButton_treatmentAppliedByDefault() {
- mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
- mWindowManager.createLayout(/* canShow= */ true);
- final ImageButton button =
- mLayout.findViewById(R.id.camera_compat_treatment_button);
- button.performClick();
-
- verify(mWindowManager).onCameraTreatmentButtonClicked();
- verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
- CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
-
- button.performClick();
-
- verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
- CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
- }
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testUpdateCameraTreatmentButton_treatmentSuggestedByDefault() {
- mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- mWindowManager.createLayout(/* canShow= */ true);
- final ImageButton button =
- mLayout.findViewById(R.id.camera_compat_treatment_button);
- button.performClick();
-
- verify(mWindowManager).onCameraTreatmentButtonClicked();
- verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
- CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
-
- button.performClick();
-
- verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
- CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
- }
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testOnCameraDismissButtonClicked() {
- mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- mWindowManager.createLayout(/* canShow= */ true);
- final ImageButton button =
- mLayout.findViewById(R.id.camera_compat_dismiss_button);
- button.performClick();
-
- verify(mWindowManager).onCameraDismissButtonClicked();
- verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
- verify(mLayout).setCameraControlVisibility(/* show */ false);
- }
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testOnLongClickForCameraTreatmentButton() {
- doNothing().when(mWindowManager).onCameraButtonLongClicked();
-
- final ImageButton button =
- mLayout.findViewById(R.id.camera_compat_treatment_button);
- button.performLongClick();
-
- verify(mWindowManager).onCameraButtonLongClicked();
- }
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testOnLongClickForCameraDismissButton() {
- doNothing().when(mWindowManager).onCameraButtonLongClicked();
-
- final ImageButton button = mLayout.findViewById(R.id.camera_compat_dismiss_button);
- button.performLongClick();
-
- verify(mWindowManager).onCameraButtonLongClicked();
- }
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testOnClickForCameraCompatHint() {
- mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- mWindowManager.createLayout(/* canShow= */ true);
- final LinearLayout hint = mLayout.findViewById(R.id.camera_compat_hint);
- hint.performClick();
-
- verify(mLayout).setCameraCompatHintVisibility(/* show= */ false);
- }
-
- private static TaskInfo createTaskInfo(boolean hasSizeCompat,
- @CameraCompatControlState int cameraCompatControlState) {
+ private static TaskInfo createTaskInfo(boolean hasSizeCompat) {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = TASK_ID;
taskInfo.appCompatTaskInfo.topActivityInSizeCompat = hasSizeCompat;
- taskInfo.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- cameraCompatControlState;
taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 1000;
taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000;
taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 2000, 2000));
return taskInfo;
}
-
- private void verifyOnCameraControlStateUpdatedInvokedWith(int taskId, int state) {
- final ArgumentCaptor<CompatUIEvent> captureValue = ArgumentCaptor.forClass(
- CompatUIEvent.class);
- verify(mCallback).accept(captureValue.capture());
- final CompatUIEvents.CameraControlStateUpdated compatUIEvent =
- (CompatUIEvents.CameraControlStateUpdated) captureValue.getValue();
- Assert.assertEquals((compatUIEvent).getTaskId(), taskId);
- Assert.assertEquals((compatUIEvent).getState(), state);
- clearInvocations(mCallback);
- }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
index eb3da8f65b5d..c5033f3ae64b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
@@ -16,10 +16,6 @@
package com.android.wm.shell.compatui;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_DISMISSED;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
@@ -36,10 +32,10 @@ import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
-import android.app.CameraCompatTaskInfo;
import android.app.TaskInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -65,7 +61,6 @@ import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
import com.android.wm.shell.compatui.api.CompatUIEvent;
-import com.android.wm.shell.compatui.impl.CompatUIEvents;
import junit.framework.Assert;
@@ -115,7 +110,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
public void setUp() {
MockitoAnnotations.initMocks(this);
doReturn(100).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
- mTaskInfo = createTaskInfo(/* hasSizeCompat= */ false, CAMERA_COMPAT_CONTROL_HIDDEN);
+ mTaskInfo = createTaskInfo(/* hasSizeCompat= */ false);
final DisplayInfo displayInfo = new DisplayInfo();
displayInfo.logicalWidth = TASK_WIDTH;
@@ -186,45 +181,6 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
@Test
@RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testCreateCameraCompatControl() {
- // Doesn't create layout if show is false.
- mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- assertTrue(mWindowManager.createLayout(/* canShow= */ false));
-
- verify(mWindowManager, never()).inflateLayout();
-
- // Doesn't create hint popup.
- mWindowManager.mCompatUIHintsState.mHasShownCameraCompatHint = true;
- assertTrue(mWindowManager.createLayout(/* canShow= */ true));
-
- verify(mWindowManager).inflateLayout();
- verify(mLayout).setCameraControlVisibility(/* show= */ true);
- verify(mLayout, never()).setCameraCompatHintVisibility(/* show= */ true);
-
- // Creates hint popup.
- clearInvocations(mWindowManager);
- clearInvocations(mLayout);
- mWindowManager.release();
- mWindowManager.mCompatUIHintsState.mHasShownCameraCompatHint = false;
- assertTrue(mWindowManager.createLayout(/* canShow= */ true));
-
- verify(mWindowManager).inflateLayout();
- assertNotNull(mLayout);
- verify(mLayout).setCameraControlVisibility(/* show= */ true);
- verify(mLayout).setCameraCompatHintVisibility(/* show= */ true);
- assertTrue(mWindowManager.mCompatUIHintsState.mHasShownCameraCompatHint);
-
- // Returns false and doesn't create layout if Camera Compat state is hidden
- clearInvocations(mWindowManager);
- mWindowManager.release();
- mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_HIDDEN;
- assertFalse(mWindowManager.createLayout(/* canShow= */ true));
-
- verify(mWindowManager, never()).inflateLayout();
- }
-
- @Test
- @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRelease() {
mWindowManager.mHasSizeCompat = true;
mWindowManager.createLayout(/* canShow= */ true);
@@ -241,10 +197,11 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
public void testUpdateCompatInfo() {
mWindowManager.mHasSizeCompat = true;
mWindowManager.createLayout(/* canShow= */ true);
+ verify(mLayout).setRestartButtonVisibility(/* show= */ true);
// No diff
clearInvocations(mWindowManager);
- TaskInfo taskInfo = createTaskInfo(/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN);
+ TaskInfo taskInfo = createTaskInfo(/* hasSizeCompat= */ true);
doReturn(true).when(mWindowManager).shouldShowSizeCompatRestartButton(any());
assertTrue(mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true));
@@ -261,58 +218,25 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
verify(mWindowManager).release();
verify(mWindowManager).createLayout(/* canShow= */ true);
- // Change Camera Compat state, show a control.
- clearInvocations(mWindowManager);
- clearInvocations(mLayout);
- taskInfo = createTaskInfo(/* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
- assertTrue(mWindowManager.updateCompatInfo(taskInfo, newTaskListener, /* canShow= */ true));
-
- verify(mLayout).setCameraControlVisibility(/* show= */ true);
- verify(mLayout).updateCameraTreatmentButton(
- CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
-
- // Change Camera Compat state, update a control.
- clearInvocations(mWindowManager);
- clearInvocations(mLayout);
- taskInfo = createTaskInfo(/* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
- assertTrue(mWindowManager.updateCompatInfo(taskInfo, newTaskListener, /* canShow= */ true));
-
- verify(mLayout).setCameraControlVisibility(/* show= */ true);
- verify(mLayout).updateCameraTreatmentButton(
- CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
-
- // Change has Size Compat to false, hides restart button.
+ // Change has Size Compat to false, no more CompatIU.
clearInvocations(mWindowManager);
clearInvocations(mLayout);
- taskInfo = createTaskInfo(/* hasSizeCompat= */ false,
- CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
- assertTrue(mWindowManager.updateCompatInfo(taskInfo, newTaskListener, /* canShow= */ true));
-
- verify(mLayout).setRestartButtonVisibility(/* show= */ false);
+ taskInfo = createTaskInfo(/* hasSizeCompat= */ false);
+ assertFalse(mWindowManager.updateCompatInfo(taskInfo, newTaskListener,
+ /* canShow= */ true));
// Change has Size Compat to true, shows restart button.
clearInvocations(mWindowManager);
clearInvocations(mLayout);
- taskInfo = createTaskInfo(/* hasSizeCompat= */ true,
- CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
- assertTrue(mWindowManager.updateCompatInfo(taskInfo, newTaskListener, /* canShow= */ true));
-
- verify(mLayout).setRestartButtonVisibility(/* show= */ true);
-
- // Change Camera Compat state to dismissed, hide a control.
- clearInvocations(mWindowManager);
- clearInvocations(mLayout);
- taskInfo = createTaskInfo(/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_DISMISSED);
+ taskInfo = createTaskInfo(/* hasSizeCompat= */ true);
assertTrue(mWindowManager.updateCompatInfo(taskInfo, newTaskListener, /* canShow= */ true));
- verify(mLayout).setCameraControlVisibility(/* show= */ false);
+ verify(mLayout, times(2)).setRestartButtonVisibility(/* show= */ true);
// Change task bounds, update position.
clearInvocations(mWindowManager);
clearInvocations(mLayout);
- taskInfo = createTaskInfo(/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN);
+ taskInfo = createTaskInfo(/* hasSizeCompat= */ true);
taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 1000, 0, 2000));
assertTrue(mWindowManager.updateCompatInfo(taskInfo, newTaskListener, /* canShow= */ true));
@@ -321,7 +245,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
// Change has Size Compat to false, release layout.
clearInvocations(mWindowManager);
clearInvocations(mLayout);
- taskInfo = createTaskInfo(/* hasSizeCompat= */ false, CAMERA_COMPAT_CONTROL_HIDDEN);
+ taskInfo = createTaskInfo(/* hasSizeCompat= */ false);
assertFalse(
mWindowManager.updateCompatInfo(taskInfo, newTaskListener, /* canShow= */ true));
@@ -338,15 +262,14 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
// Change topActivityInSizeCompat to false and pass canShow true, layout shouldn't be
// inflated
clearInvocations(mWindowManager);
- TaskInfo taskInfo = createTaskInfo(/* hasSizeCompat= */ false,
- CAMERA_COMPAT_CONTROL_HIDDEN);
+ TaskInfo taskInfo = createTaskInfo(/* hasSizeCompat= */ false);
mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true);
verify(mWindowManager, never()).inflateLayout();
// Change topActivityInSizeCompat to true and pass canShow true, layout should be inflated.
clearInvocations(mWindowManager);
- taskInfo = createTaskInfo(/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN);
+ taskInfo = createTaskInfo(/* hasSizeCompat= */ true);
mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true);
verify(mWindowManager).inflateLayout();
@@ -443,37 +366,6 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
@Test
@RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testOnCameraDismissButtonClicked() {
- mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- mWindowManager.createLayout(/* canShow= */ true);
- clearInvocations(mLayout);
- mWindowManager.onCameraDismissButtonClicked();
-
- verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
- verify(mLayout).setCameraControlVisibility(/* show= */ false);
- }
-
- @Test
- @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testOnCameraTreatmentButtonClicked() {
- mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- mWindowManager.createLayout(/* canShow= */ true);
- clearInvocations(mLayout);
- mWindowManager.onCameraTreatmentButtonClicked();
-
- verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
- CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
- verify(mLayout).updateCameraTreatmentButton(CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
-
- mWindowManager.onCameraTreatmentButtonClicked();
-
- verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
- CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
- verify(mLayout).updateCameraTreatmentButton(CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
- }
-
- @Test
- @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnRestartButtonClicked() {
mWindowManager.onRestartButtonClicked();
@@ -505,22 +397,6 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
@Test
@RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
- public void testOnCameraControlLongClicked_showHint() {
- // Not create hint popup.
- mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- mWindowManager.mCompatUIHintsState.mHasShownCameraCompatHint = true;
- mWindowManager.createLayout(/* canShow= */ true);
-
- verify(mWindowManager).inflateLayout();
- verify(mLayout, never()).setCameraCompatHintVisibility(/* show= */ true);
-
- mWindowManager.onCameraButtonLongClicked();
-
- verify(mLayout).setCameraCompatHintVisibility(/* show= */ true);
- }
-
- @Test
- @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testWhenDockedStateHasChanged_needsToBeRecreated() {
ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
newTaskInfo.configuration.uiMode |= Configuration.UI_MODE_TYPE_DESK;
@@ -538,7 +414,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
mCompatUIConfiguration, mOnRestartButtonClicked);
// Simulate rotation of activity in square display
- TaskInfo taskInfo = createTaskInfo(true, CAMERA_COMPAT_CONTROL_HIDDEN);
+ TaskInfo taskInfo = createTaskInfo(true);
taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = TASK_HEIGHT;
taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1850;
@@ -567,13 +443,10 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));
}
- private static TaskInfo createTaskInfo(boolean hasSizeCompat,
- @CameraCompatTaskInfo.CameraCompatControlState int cameraCompatControlState) {
+ private static TaskInfo createTaskInfo(boolean hasSizeCompat) {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = TASK_ID;
taskInfo.appCompatTaskInfo.topActivityInSizeCompat = hasSizeCompat;
- taskInfo.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- cameraCompatControlState;
taskInfo.configuration.uiMode &= ~Configuration.UI_MODE_TYPE_DESK;
// Letterboxed activity that takes half the screen should show size compat restart button
taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 1000;
@@ -582,15 +455,4 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
taskInfo.configuration.smallestScreenWidthDp = LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
return taskInfo;
}
-
- private void verifyOnCameraControlStateUpdatedInvokedWith(int taskId, int state) {
- final ArgumentCaptor<CompatUIEvent> captureValue = ArgumentCaptor.forClass(
- CompatUIEvent.class);
- verify(mCallback).accept(captureValue.capture());
- final CompatUIEvents.CameraControlStateUpdated compatUIEvent =
- (CompatUIEvents.CameraControlStateUpdated) captureValue.getValue();
- Assert.assertEquals((compatUIEvent).getTaskId(), taskId);
- Assert.assertEquals((compatUIEvent).getState(), state);
- clearInvocations(mCallback);
- }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
index 3fa21cee0d68..7a641960a2c5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
@@ -16,8 +16,6 @@
package com.android.wm.shell.compatui;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
-
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
@@ -26,7 +24,6 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
-import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.platform.test.annotations.RequiresFlagsDisabled;
@@ -98,7 +95,7 @@ public class UserAspectRatioSettingsLayoutTest extends ShellTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mTaskInfo = createTaskInfo(/* hasSizeCompat= */ false, CAMERA_COMPAT_CONTROL_HIDDEN);
+ mTaskInfo = createTaskInfo(/* hasSizeCompat= */ false);
mWindowManager = new UserAspectRatioSettingsWindowManager(mContext, mTaskInfo,
mSyncTransactionQueue, mTaskListener, new DisplayLayout(),
new CompatUIController.CompatUIHintsState(),
@@ -155,13 +152,10 @@ public class UserAspectRatioSettingsLayoutTest extends ShellTestCase {
verify(mLayout).setUserAspectRatioSettingsHintVisibility(/* show= */ false);
}
- private static TaskInfo createTaskInfo(boolean hasSizeCompat,
- @CameraCompatControlState int cameraCompatControlState) {
+ private static TaskInfo createTaskInfo(boolean hasSizeCompat) {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = TASK_ID;
taskInfo.appCompatTaskInfo.topActivityInSizeCompat = hasSizeCompat;
- taskInfo.appCompatTaskInfo.cameraCompatTaskInfo.cameraCompatControlState =
- cameraCompatControlState;
taskInfo.realActivity = new ComponentName("com.mypackage.test", "TestActivity");
return taskInfo;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
index 18b08bfb0f47..d3404f7bd261 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
@@ -41,32 +41,44 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun addActiveTask_listenerNotifiedAndTaskIsActive() {
+ fun addActiveTask_notifiesListener() {
val listener = TestListener()
repo.addActiveTaskListener(listener)
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(1)
+ }
+
+ @Test
+ fun addActiveTask_taskIsActive() {
+ val listener = TestListener()
+ repo.addActiveTaskListener(listener)
+
+ repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+
assertThat(repo.isActiveTask(1)).isTrue()
}
@Test
- fun addActiveTask_sameTaskDoesNotNotify() {
+ fun addSameActiveTaskTwice_notifiesOnce() {
val listener = TestListener()
repo.addActiveTaskListener(listener)
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(1)
}
@Test
- fun addActiveTask_multipleTasksAddedNotifiesForEach() {
+ fun addActiveTask_multipleTasksAdded_notifiesForAllTasks() {
val listener = TestListener()
repo.addActiveTaskListener(listener)
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 2)
+
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
}
@@ -84,22 +96,35 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun removeActiveTask_listenerNotifiedAndTaskNotActive() {
+ fun removeActiveTask_notifiesListener() {
val listener = TestListener()
repo.addActiveTaskListener(listener)
-
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+
repo.removeActiveTask(1)
+
// Notify once for add and once for remove
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
+ }
+
+ @Test
+ fun removeActiveTask_taskNotActive() {
+ val listener = TestListener()
+ repo.addActiveTaskListener(listener)
+ repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+
+ repo.removeActiveTask(1)
+
assertThat(repo.isActiveTask(1)).isFalse()
}
@Test
- fun removeActiveTask_removeNotExistingTaskDoesNotNotify() {
+ fun removeActiveTask_nonExistingTask_doesNotNotify() {
val listener = TestListener()
repo.addActiveTaskListener(listener)
+
repo.removeActiveTask(99)
+
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(0)
}
@@ -108,32 +133,38 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
val listener = TestListener()
repo.addActiveTaskListener(listener)
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+
repo.removeActiveTask(1)
+
assertThat(listener.activeChangesOnSecondaryDisplay).isEqualTo(0)
assertThat(repo.isActiveTask(1)).isFalse()
}
@Test
- fun isActiveTask_notExistingTaskReturnsFalse() {
+ fun isActiveTask_nonExistingTask_returnsFalse() {
assertThat(repo.isActiveTask(99)).isFalse()
}
@Test
- fun isOnlyVisibleNonClosingTask_noTasks() {
+ fun isOnlyVisibleNonClosingTask_noTasks_returnsFalse() {
// No visible tasks
assertThat(repo.isOnlyVisibleNonClosingTask(1)).isFalse()
+ }
+
+ @Test
+ fun isClosingTask_noTasks_returnsFalse() {
+ // No visible tasks
assertThat(repo.isClosingTask(1)).isFalse()
}
@Test
- fun isOnlyVisibleNonClosingTask_singleVisibleNonClosingTask() {
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ fun updateTaskVisibility_singleVisibleNonClosingTask_updatesTasksCorrectly() {
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
- // The only visible task
assertThat(repo.isVisibleTask(1)).isTrue()
assertThat(repo.isClosingTask(1)).isFalse()
assertThat(repo.isOnlyVisibleNonClosingTask(1)).isTrue()
- // Not a visible task
+
assertThat(repo.isVisibleTask(99)).isFalse()
assertThat(repo.isClosingTask(99)).isFalse()
assertThat(repo.isOnlyVisibleNonClosingTask(99)).isFalse()
@@ -141,7 +172,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
@Test
fun isOnlyVisibleNonClosingTask_singleVisibleClosingTask() {
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
repo.addClosingTask(DEFAULT_DISPLAY, 1)
// A visible task that's closing
@@ -155,7 +186,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
@Test
fun isOnlyVisibleNonClosingTask_singleVisibleMinimizedTask() {
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
repo.minimizeTask(DEFAULT_DISPLAY, 1)
// The visible task that's closing
@@ -169,8 +200,8 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
@Test
fun isOnlyVisibleNonClosingTask_multipleVisibleNonClosingTasks() {
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 2, visible = true)
// Not the only task
assertThat(repo.isVisibleTask(1)).isTrue()
@@ -188,9 +219,9 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
@Test
fun isOnlyVisibleNonClosingTask_multipleDisplays() {
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
- repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 3, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 2, visible = true)
+ repo.updateTaskVisibility(SECOND_DISPLAY, taskId = 3, visible = true)
// Not the only task on DEFAULT_DISPLAY
assertThat(repo.isVisibleTask(1)).isTrue()
@@ -207,10 +238,11 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun addListener_notifiesVisibleFreeformTask() {
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ fun addVisibleTasksListener_notifiesVisibleFreeformTask() {
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
val listener = TestVisibilityListener()
val executor = TestShellExecutor()
+
repo.addVisibleTasksListener(listener, executor)
executor.flushAll()
@@ -220,7 +252,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
@Test
fun addListener_tasksOnDifferentDisplay_doesNotNotify() {
- repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(SECOND_DISPLAY, taskId = 1, visible = true)
val listener = TestVisibilityListener()
val executor = TestShellExecutor()
repo.addVisibleTasksListener(listener, executor)
@@ -232,12 +264,13 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun updateVisibleFreeformTasks_addVisibleTasksNotifiesListener() {
+ fun updateTaskVisibility_addVisibleTasksNotifiesListener() {
val listener = TestVisibilityListener()
val executor = TestShellExecutor()
repo.addVisibleTasksListener(listener, executor)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
+
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 2, visible = true)
executor.flushAll()
assertThat(listener.visibleTasksCountOnDefaultDisplay).isEqualTo(2)
@@ -245,12 +278,12 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun updateVisibleFreeformTasks_addVisibleTaskNotifiesListenerForThatDisplay() {
+ fun updateTaskVisibility_addVisibleTaskNotifiesListenerForThatDisplay() {
val listener = TestVisibilityListener()
val executor = TestShellExecutor()
repo.addVisibleTasksListener(listener, executor)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
executor.flushAll()
assertThat(listener.visibleTasksCountOnDefaultDisplay).isEqualTo(1)
@@ -258,7 +291,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
assertThat(listener.visibleTasksCountOnSecondaryDisplay).isEqualTo(0)
assertThat(listener.visibleChangesOnSecondaryDisplay).isEqualTo(0)
- repo.updateVisibleFreeformTasks(displayId = 1, taskId = 2, visible = true)
+ repo.updateTaskVisibility(displayId = 1, taskId = 2, visible = true)
executor.flushAll()
// Listener for secondary display is notified
@@ -269,17 +302,17 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun updateVisibleFreeformTasks_taskOnDefaultBecomesVisibleOnSecondDisplay_listenersNotified() {
+ fun updateTaskVisibility_taskOnDefaultBecomesVisibleOnSecondDisplay_listenersNotified() {
val listener = TestVisibilityListener()
val executor = TestShellExecutor()
repo.addVisibleTasksListener(listener, executor)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
executor.flushAll()
assertThat(listener.visibleTasksCountOnDefaultDisplay).isEqualTo(1)
// Mark task 1 visible on secondary display
- repo.updateVisibleFreeformTasks(displayId = 1, taskId = 1, visible = true)
+ repo.updateTaskVisibility(displayId = 1, taskId = 1, visible = true)
executor.flushAll()
// Default display should have 2 calls
@@ -294,21 +327,22 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun updateVisibleFreeformTasks_removeVisibleTasksNotifiesListener() {
+ fun updateTaskVisibility_removeVisibleTasksNotifiesListener() {
val listener = TestVisibilityListener()
val executor = TestShellExecutor()
repo.addVisibleTasksListener(listener, executor)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 2, visible = true)
executor.flushAll()
assertThat(listener.visibleTasksCountOnDefaultDisplay).isEqualTo(2)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
+
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = false)
executor.flushAll()
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(3)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = false)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 2, visible = false)
executor.flushAll()
assertThat(listener.visibleTasksCountOnDefaultDisplay).isEqualTo(0)
@@ -320,16 +354,17 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
* This tests that task is removed from the last parent display when it vanishes.
*/
@Test
- fun updateVisibleFreeformTasks_removeVisibleTasksRemovesTaskWithInvalidDisplay() {
+ fun updateTaskVisibility_removeVisibleTasksRemovesTaskWithInvalidDisplay() {
val listener = TestVisibilityListener()
val executor = TestShellExecutor()
repo.addVisibleTasksListener(listener, executor)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 2, visible = true)
executor.flushAll()
assertThat(listener.visibleTasksCountOnDefaultDisplay).isEqualTo(2)
- repo.updateVisibleFreeformTasks(INVALID_DISPLAY, taskId = 1, visible = false)
+
+ repo.updateTaskVisibility(INVALID_DISPLAY, taskId = 1, visible = false)
executor.flushAll()
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(3)
@@ -337,65 +372,73 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun visibleTaskCount_defaultDisplay_returnsCorrectCount() {
+ fun getVisibleTaskCount_defaultDisplay_returnsCorrectCount() {
// No tasks, count is 0
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
// New task increments count to 1
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
+
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
// Visibility update to same task does not increase count
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
+
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
// Second task visible increments count
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 2, visible = true)
+
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
// Hiding a task decrements count
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = false)
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
// Hiding all tasks leaves count at 0
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = false)
- assertThat(repo.visibleTaskCount(displayId = 9)).isEqualTo(0)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 2, visible = false)
+ assertThat(repo.getVisibleTaskCount(displayId = 9)).isEqualTo(0)
// Hiding a not existing task, count remains at 0
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 999, visible = false)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 999, visible = false)
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
}
@Test
- fun visibleTaskCount_multipleDisplays_returnsCorrectCount() {
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
- assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
+ fun getVisibleTaskCount_multipleDisplays_returnsCorrectCount() {
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
// New task on default display increments count for that display only
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
- assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = true)
+
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
// New task on secondary display, increments count for that display only
- repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 2, visible = true)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
- assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
+ repo.updateTaskVisibility(SECOND_DISPLAY, taskId = 2, visible = true)
+
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
// Marking task visible on another display, updates counts for both displays
- repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = true)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
- assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
+ repo.updateTaskVisibility(SECOND_DISPLAY, taskId = 1, visible = true)
+
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
// Marking task that is on secondary display, hidden on default display, does not affect
// secondary display
- repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
- assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
+ repo.updateTaskVisibility(DEFAULT_DISPLAY, taskId = 1, visible = false)
+
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
// Hiding a task on that display, decrements count
- repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = false)
- assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
- assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
+ repo.updateTaskVisibility(SECOND_DISPLAY, taskId = 1, visible = false)
+
+ assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
}
@Test
@@ -425,18 +468,116 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
+ fun addOrMoveFreeformTaskToTop_taskIsMinimized_unminimizesTask() {
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, 5)
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, 6)
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, 7)
+ repo.minimizeTask(displayId = 0, taskId = 6)
+
+ val tasks = repo.getFreeformTasksInZOrder(DEFAULT_DISPLAY)
+ assertThat(tasks).containsExactly(7, 6, 5).inOrder()
+ assertThat(repo.isMinimizedTask(taskId = 6)).isTrue()
+ }
+
+ @Test
+ fun addOrMoveFreeformTaskToTop_taskIsUnminimized_noop() {
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, 5)
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, 6)
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, 7)
+
+ val tasks = repo.getFreeformTasksInZOrder(DEFAULT_DISPLAY)
+ assertThat(tasks).containsExactly(7, 6, 5).inOrder()
+ assertThat(repo.isMinimizedTask(taskId = 6)).isFalse()
+ }
+
+ @Test
+ fun removeFreeformTask_invalidDisplay_removesTaskFromFreeformTasks() {
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, taskId = 1)
+
+ repo.removeFreeformTask(INVALID_DISPLAY, taskId = 1)
+
+ val invalidDisplayTasks = repo.getFreeformTasksInZOrder(INVALID_DISPLAY)
+ assertThat(invalidDisplayTasks).isEmpty()
+ val validDisplayTasks = repo.getFreeformTasksInZOrder(DEFAULT_DISPLAY)
+ assertThat(validDisplayTasks).isEmpty()
+ }
+
+ @Test
+ fun removeFreeformTask_validDisplay_removesTaskFromFreeformTasks() {
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, taskId = 1)
+
+ repo.removeFreeformTask(DEFAULT_DISPLAY, taskId = 1)
+
+ val tasks = repo.getFreeformTasksInZOrder(DEFAULT_DISPLAY)
+ assertThat(tasks).isEmpty()
+ }
+
+ @Test
+ fun removeFreeformTask_validDisplay_differentDisplay_doesNotRemovesTask() {
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, taskId = 1)
+
+ repo.removeFreeformTask(SECOND_DISPLAY, taskId = 1)
+
+ val tasks = repo.getFreeformTasksInZOrder(DEFAULT_DISPLAY)
+ assertThat(tasks).containsExactly(1)
+ }
+
+ @Test
fun removeFreeformTask_removesTaskBoundsBeforeMaximize() {
val taskId = 1
+ repo.addActiveTask(THIRD_DISPLAY, taskId)
+ repo.addOrMoveFreeformTaskToTop(THIRD_DISPLAY, taskId)
repo.saveBoundsBeforeMaximize(taskId, Rect(0, 0, 200, 200))
+
repo.removeFreeformTask(THIRD_DISPLAY, taskId)
+
assertThat(repo.removeBoundsBeforeMaximize(taskId)).isNull()
}
@Test
+ fun removeFreeformTask_removesActiveTask() {
+ val taskId = 1
+ val listener = TestListener()
+ repo.addActiveTaskListener(listener)
+ repo.addActiveTask(DEFAULT_DISPLAY, taskId)
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, taskId)
+
+ repo.removeFreeformTask(THIRD_DISPLAY, taskId)
+
+ assertThat(repo.isActiveTask(taskId)).isFalse()
+ assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
+ }
+
+ @Test
+ fun removeFreeformTask_unminimizesTask() {
+ val taskId = 1
+ repo.addActiveTask(DEFAULT_DISPLAY, taskId)
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, taskId)
+ repo.minimizeTask(DEFAULT_DISPLAY, taskId)
+
+ repo.removeFreeformTask(DEFAULT_DISPLAY, taskId)
+
+ assertThat(repo.isMinimizedTask(taskId)).isFalse()
+ }
+
+ @Test
+ fun removeFreeformTask_updatesTaskVisibility() {
+ val taskId = 1
+ repo.addActiveTask(DEFAULT_DISPLAY, taskId)
+ repo.addOrMoveFreeformTaskToTop(DEFAULT_DISPLAY, taskId)
+
+ repo.removeFreeformTask(THIRD_DISPLAY, taskId)
+
+ assertThat(repo.isVisibleTask(taskId)).isFalse()
+ }
+
+ @Test
fun saveBoundsBeforeMaximize_boundsSavedByTaskId() {
val taskId = 1
val bounds = Rect(0, 0, 200, 200)
+
repo.saveBoundsBeforeMaximize(taskId, bounds)
+
assertThat(repo.removeBoundsBeforeMaximize(taskId)).isEqualTo(bounds)
}
@@ -446,17 +587,20 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
val bounds = Rect(0, 0, 200, 200)
repo.saveBoundsBeforeMaximize(taskId, bounds)
repo.removeBoundsBeforeMaximize(taskId)
- assertThat(repo.removeBoundsBeforeMaximize(taskId)).isNull()
+
+ val boundsBeforeMaximize = repo.removeBoundsBeforeMaximize(taskId)
+
+ assertThat(boundsBeforeMaximize).isNull()
}
@Test
- fun minimizeTaskNotCalled_noTasksMinimized() {
+ fun isMinimizedTask_minimizeTaskNotCalled_noTasksMinimized() {
assertThat(repo.isMinimizedTask(taskId = 0)).isFalse()
assertThat(repo.isMinimizedTask(taskId = 1)).isFalse()
}
@Test
- fun minimizeTask_onlyThatTaskIsMinimized() {
+ fun minimizeTask_minimizesCorrectTask() {
repo.minimizeTask(displayId = 0, taskId = 0)
assertThat(repo.isMinimizedTask(taskId = 0)).isTrue()
@@ -465,8 +609,9 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun unminimizeTask_taskNoLongerMinimized() {
+ fun unminimizeTask_unminimizesTask() {
repo.minimizeTask(displayId = 0, taskId = 0)
+
repo.unminimizeTask(displayId = 0, taskId = 0)
assertThat(repo.isMinimizedTask(taskId = 0)).isFalse()
@@ -478,6 +623,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
fun unminimizeTask_nonExistentTask_doesntCrash() {
repo.unminimizeTask(displayId = 0, taskId = 0)
+ // No change
assertThat(repo.isMinimizedTask(taskId = 0)).isFalse()
assertThat(repo.isMinimizedTask(taskId = 1)).isFalse()
assertThat(repo.isMinimizedTask(taskId = 2)).isFalse()
@@ -485,41 +631,44 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
@Test
- fun updateVisibleFreeformTasks_toVisible_taskIsUnminimized() {
+ fun updateTaskVisibility_minimizedTaskBecomesVisible_unminimizesTask() {
repo.minimizeTask(displayId = 10, taskId = 2)
+ repo.updateTaskVisibility(displayId = 10, taskId = 2, visible = true)
- repo.updateVisibleFreeformTasks(displayId = 10, taskId = 2, visible = true)
+ val isMinimizedTask = repo.isMinimizedTask(taskId = 2)
- assertThat(repo.isMinimizedTask(taskId = 2)).isFalse()
+ assertThat(isMinimizedTask).isFalse()
}
@Test
- fun getActiveNonMinimizedTasksOrderedFrontToBack_returnsFreeformTasksInCorrectOrder() {
+ fun getActiveNonMinimizedOrderedTasks_returnsFreeformTasksInCorrectOrder() {
repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 1)
repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 2)
repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 3)
- // The front-most task will be the one added last through addOrMoveFreeformTaskToTop
+ // The front-most task will be the one added last through `addOrMoveFreeformTaskToTop`
repo.addOrMoveFreeformTaskToTop(displayId = DEFAULT_DISPLAY, taskId = 3)
repo.addOrMoveFreeformTaskToTop(displayId = 0, taskId = 2)
repo.addOrMoveFreeformTaskToTop(displayId = 0, taskId = 1)
- assertThat(repo.getActiveNonMinimizedTasksOrderedFrontToBack(displayId = 0))
- .containsExactly(1, 2, 3).inOrder()
+ val tasks = repo.getActiveNonMinimizedOrderedTasks(displayId = 0)
+
+ assertThat(tasks).containsExactly(1, 2, 3).inOrder()
}
@Test
- fun getActiveNonMinimizedTasksOrderedFrontToBack_minimizedTaskNotIncluded() {
+ fun getActiveNonMinimizedOrderedTasks_excludesMinimizedTasks() {
repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 1)
repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 2)
repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 3)
- // The front-most task will be the one added last through addOrMoveFreeformTaskToTop
+ // The front-most task will be the one added last through `addOrMoveFreeformTaskToTop`
repo.addOrMoveFreeformTaskToTop(displayId = DEFAULT_DISPLAY, taskId = 3)
repo.addOrMoveFreeformTaskToTop(displayId = DEFAULT_DISPLAY, taskId = 2)
repo.addOrMoveFreeformTaskToTop(displayId = DEFAULT_DISPLAY, taskId = 1)
repo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = 2)
- assertThat(repo.getActiveNonMinimizedTasksOrderedFrontToBack(
- displayId = DEFAULT_DISPLAY)).containsExactly(1, 3).inOrder()
+ val tasks = repo.getActiveNonMinimizedOrderedTasks(displayId = DEFAULT_DISPLAY)
+
+ assertThat(tasks).containsExactly(1, 3).inOrder()
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
index bd39aa6ace42..2dea43b508ae 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
@@ -61,20 +61,23 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
@Test
fun testFullscreenRegionCalculation() {
- val transitionHeight = context.resources.getDimensionPixelSize(
- R.dimen.desktop_mode_fullscreen_from_desktop_height)
- val fromFreeformWidth = mContext.resources.getDimensionPixelSize(
- R.dimen.desktop_mode_fullscreen_from_desktop_width
- )
var testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
WINDOWING_MODE_FULLSCREEN, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 2400, 2 * STABLE_INSETS.top))
testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
WINDOWING_MODE_FREEFORM, CAPTION_HEIGHT)
+
+ val transitionHeight = context.resources.getDimensionPixelSize(
+ R.dimen.desktop_mode_transition_region_thickness)
+ val toFullscreenScale = mContext.resources.getFloat(
+ R.dimen.desktop_mode_fullscreen_region_scale
+ )
+ val toFullscreenWidth = displayLayout.width() * toFullscreenScale
+
assertThat(testRegion.bounds).isEqualTo(Rect(
- DISPLAY_BOUNDS.width() / 2 - fromFreeformWidth / 2,
+ (DISPLAY_BOUNDS.width() / 2f - toFullscreenWidth / 2f).toInt(),
-50,
- DISPLAY_BOUNDS.width() / 2 + fromFreeformWidth / 2,
+ (DISPLAY_BOUNDS.width() / 2f + toFullscreenWidth / 2f).toInt(),
transitionHeight))
testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
WINDOWING_MODE_MULTI_WINDOW, CAPTION_HEIGHT)
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 e66018f26d46..95d90176c6f9 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
@@ -43,6 +43,7 @@ import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
import android.view.Display.DEFAULT_DISPLAY
+import android.view.Gravity
import android.view.SurfaceControl
import android.view.WindowManager
import android.view.WindowManager.TRANSIT_CHANGE
@@ -70,6 +71,7 @@ import com.android.internal.jank.InteractionJankMonitor
import com.android.window.flags.Flags
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
import com.android.wm.shell.MockToken
+import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
@@ -174,7 +176,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
private lateinit var mockitoSession: StaticMockitoSession
private lateinit var controller: DesktopTasksController
private lateinit var shellInit: ShellInit
- private lateinit var desktopModeTaskRepository: DesktopModeTaskRepository
+ private lateinit var taskRepository: DesktopModeTaskRepository
private lateinit var desktopTasksLimiter: DesktopTasksLimiter
private lateinit var recentsTransitionStateListener: RecentsTransitionStateListener
@@ -185,12 +187,12 @@ class DesktopTasksControllerTest : ShellTestCase() {
private val DISPLAY_DIMENSION_SHORT = 1600
private val DISPLAY_DIMENSION_LONG = 2560
- private val DEFAULT_LANDSCAPE_BOUNDS = Rect(320, 200, 2240, 1400)
- private val DEFAULT_PORTRAIT_BOUNDS = Rect(200, 320, 1400, 2240)
- private val RESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 680, 1575, 1880)
- private val RESIZABLE_PORTRAIT_BOUNDS = Rect(680, 200, 1880, 1400)
- private val UNRESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 699, 1575, 1861)
- private val UNRESIZABLE_PORTRAIT_BOUNDS = Rect(830, 200, 1730, 1400)
+ private val DEFAULT_LANDSCAPE_BOUNDS = Rect(320, 75, 2240, 1275)
+ private val DEFAULT_PORTRAIT_BOUNDS = Rect(200, 165, 1400, 2085)
+ private val RESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 435, 1575, 1635)
+ private val RESIZABLE_PORTRAIT_BOUNDS = Rect(680, 75, 1880, 1275)
+ private val UNRESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 449, 1575, 1611)
+ private val UNRESIZABLE_PORTRAIT_BOUNDS = Rect(830, 75, 1730, 1275)
@Before
fun setUp() {
@@ -202,14 +204,15 @@ class DesktopTasksControllerTest : ShellTestCase() {
doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
shellInit = spy(ShellInit(testExecutor))
- desktopModeTaskRepository = DesktopModeTaskRepository()
+ taskRepository = DesktopModeTaskRepository()
desktopTasksLimiter =
DesktopTasksLimiter(
transitions,
- desktopModeTaskRepository,
+ taskRepository,
shellTaskOrganizer,
MAX_TASK_LIMIT,
- )
+ mockInteractionJankMonitor,
+ mContext)
whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks }
whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() }
@@ -250,7 +253,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
exitDesktopTransitionHandler,
toggleResizeDesktopTaskTransitionHandler,
dragToDesktopTransitionHandler,
- desktopModeTaskRepository,
+ taskRepository,
desktopModeLoggerTransitionObserver,
launchAdjacentController,
recentsTransitionHandler,
@@ -528,7 +531,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
markTaskHidden(freeformTask)
markTaskHidden(minimizedTask)
- desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, minimizedTask.taskId)
+ taskRepository.minimizeTask(DEFAULT_DISPLAY, minimizedTask.taskId)
controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
@@ -547,7 +550,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
markTaskHidden(freeformTask)
markTaskHidden(minimizedTask)
- desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, minimizedTask.taskId)
+ taskRepository.minimizeTask(DEFAULT_DISPLAY, minimizedTask.taskId)
controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
@@ -590,6 +593,161 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun addMoveToDesktopChanges_gravityLeft_noBoundsApplied() {
+ setUpLandscapeDisplay()
+ val task = setUpFullscreenTask(gravity = Gravity.LEFT)
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(finalBounds).isEqualTo(Rect())
+ }
+
+ @Test
+ fun addMoveToDesktopChanges_gravityRight_noBoundsApplied() {
+ setUpLandscapeDisplay()
+ val task = setUpFullscreenTask(gravity = Gravity.RIGHT)
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(finalBounds).isEqualTo(Rect())
+ }
+
+ @Test
+ fun addMoveToDesktopChanges_gravityTop_noBoundsApplied() {
+ setUpLandscapeDisplay()
+ val task = setUpFullscreenTask(gravity = Gravity.TOP)
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(finalBounds).isEqualTo(Rect())
+ }
+
+ @Test
+ fun addMoveToDesktopChanges_gravityBottom_noBoundsApplied() {
+ setUpLandscapeDisplay()
+ val task = setUpFullscreenTask(gravity = Gravity.BOTTOM)
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(finalBounds).isEqualTo(Rect())
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS)
+ fun addMoveToDesktopChanges_positionBottomRight() {
+ setUpLandscapeDisplay()
+ val stableBounds = Rect()
+ displayLayout.getStableBoundsForDesktopMode(stableBounds)
+
+ setUpFreeformTask(bounds = DEFAULT_LANDSCAPE_BOUNDS)
+
+ val task = setUpFullscreenTask()
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!))
+ .isEqualTo(DesktopTaskPosition.BottomRight)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS)
+ fun addMoveToDesktopChanges_positionTopLeft() {
+ setUpLandscapeDisplay()
+ val stableBounds = Rect()
+ displayLayout.getStableBoundsForDesktopMode(stableBounds)
+
+ addFreeformTaskAtPosition(DesktopTaskPosition.BottomRight, stableBounds)
+
+ val task = setUpFullscreenTask()
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!))
+ .isEqualTo(DesktopTaskPosition.TopLeft)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS)
+ fun addMoveToDesktopChanges_positionBottomLeft() {
+ setUpLandscapeDisplay()
+ val stableBounds = Rect()
+ displayLayout.getStableBoundsForDesktopMode(stableBounds)
+
+ addFreeformTaskAtPosition(DesktopTaskPosition.TopLeft, stableBounds)
+
+ val task = setUpFullscreenTask()
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!))
+ .isEqualTo(DesktopTaskPosition.BottomLeft)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS)
+ fun addMoveToDesktopChanges_positionTopRight() {
+ setUpLandscapeDisplay()
+ val stableBounds = Rect()
+ displayLayout.getStableBoundsForDesktopMode(stableBounds)
+
+ addFreeformTaskAtPosition(DesktopTaskPosition.BottomLeft, stableBounds)
+
+ val task = setUpFullscreenTask()
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!))
+ .isEqualTo(DesktopTaskPosition.TopRight)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS)
+ fun addMoveToDesktopChanges_positionResetsToCenter() {
+ setUpLandscapeDisplay()
+ val stableBounds = Rect()
+ displayLayout.getStableBoundsForDesktopMode(stableBounds)
+
+ addFreeformTaskAtPosition(DesktopTaskPosition.TopRight, stableBounds)
+
+ val task = setUpFullscreenTask()
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!))
+ .isEqualTo(DesktopTaskPosition.Center)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS)
+ fun addMoveToDesktopChanges_defaultToCenterIfFree() {
+ setUpLandscapeDisplay()
+ val stableBounds = Rect()
+ displayLayout.getStableBoundsForDesktopMode(stableBounds)
+
+ val minTouchTarget = context.resources.getDimensionPixelSize(
+ R.dimen.freeform_required_visible_empty_space_in_header)
+ addFreeformTaskAtPosition(DesktopTaskPosition.Center, stableBounds,
+ Rect(0, 0, 1600, 1200), Point(0, minTouchTarget + 1))
+
+ val task = setUpFullscreenTask()
+ val wct = WindowContainerTransaction()
+ controller.addMoveToDesktopChanges(wct, task)
+
+ val finalBounds = findBoundsChange(wct, task)
+ assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!))
+ .isEqualTo(DesktopTaskPosition.Center)
+ }
+
+ @Test
fun moveToDesktop_tdaFullscreen_windowingModeSetToFreeform() {
val task = setUpFullscreenTask()
val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
@@ -838,7 +996,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
@@ -867,7 +1025,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM
@@ -887,7 +1045,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
@@ -1028,7 +1186,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun onDesktopWindowClose_singleActiveTask_hasWallpaperActivityToken() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
val wct = WindowContainerTransaction()
controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
@@ -1040,8 +1198,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun onDesktopWindowClose_singleActiveTask_isClosing() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.addClosingTask(DEFAULT_DISPLAY, task.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.addClosingTask(DEFAULT_DISPLAY, task.taskId)
val wct = WindowContainerTransaction()
controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
@@ -1053,8 +1211,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun onDesktopWindowClose_singleActiveTask_isMinimized() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, task.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(DEFAULT_DISPLAY, task.taskId)
val wct = WindowContainerTransaction()
controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
@@ -1067,7 +1225,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
val wct = WindowContainerTransaction()
controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task1.taskId)
@@ -1080,8 +1238,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
val task2 = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.addClosingTask(DEFAULT_DISPLAY, task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.addClosingTask(DEFAULT_DISPLAY, task2.taskId)
val wct = WindowContainerTransaction()
controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task1.taskId)
@@ -1094,8 +1252,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
val task2 = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(DEFAULT_DISPLAY, task2.taskId)
val wct = WindowContainerTransaction()
controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task1.taskId)
@@ -1501,7 +1659,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun handleRequest_backTransition_singleTaskWithToken_noWallpaper_noBackNav_doesNotHandle() {
val task = setUpFreeformTask()
- desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ taskRepository.wallpaperActivityToken = MockToken().token()
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
assertNull(result, "Should not handle request")
@@ -1516,7 +1674,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
// Should create remove wallpaper transaction
@@ -1531,7 +1689,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
// Should create remove wallpaper transaction
@@ -1547,7 +1705,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
- desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ taskRepository.wallpaperActivityToken = MockToken().token()
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
assertNull(result, "Should not handle request")
@@ -1562,7 +1720,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
- desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ taskRepository.wallpaperActivityToken = MockToken().token()
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, task1.token)
@@ -1575,7 +1733,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
- desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ taskRepository.wallpaperActivityToken = MockToken().token()
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
assertNull(result, "Should not handle request")
@@ -1591,8 +1749,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
// Should create remove wallpaper transaction
@@ -1608,8 +1766,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
// Should create remove wallpaper transaction
@@ -1626,8 +1784,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
// Should create remove wallpaper transaction
@@ -1643,8 +1801,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
// Should create remove wallpaper transaction
@@ -1661,11 +1819,11 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
// Task is being minimized so mark it as not visible.
- desktopModeTaskRepository
- .updateVisibleFreeformTasks(displayId = DEFAULT_DISPLAY, task2.taskId, false)
+ taskRepository
+ .updateTaskVisibility(displayId = DEFAULT_DISPLAY, task2.taskId, false)
val result = controller.handleRequest(Binder(), createTransition(task2, type = TRANSIT_TO_BACK))
assertNull(result, "Should not handle request")
@@ -1716,7 +1874,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun handleRequest_closeTransition_singleTaskWithToken_noWallpaper_noBackNav_doesNotHandle() {
val task = setUpFreeformTask()
- desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ taskRepository.wallpaperActivityToken = MockToken().token()
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
assertNull(result, "Should not handle request")
@@ -1731,7 +1889,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
// Should create remove wallpaper transaction
@@ -1746,7 +1904,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
// Should create remove wallpaper transaction
@@ -1762,7 +1920,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
- desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ taskRepository.wallpaperActivityToken = MockToken().token()
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
assertNull(result, "Should not handle request")
@@ -1777,7 +1935,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
- desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ taskRepository.wallpaperActivityToken = MockToken().token()
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
assertNotNull(result, "Should handle request")
@@ -1791,7 +1949,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
- desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ taskRepository.wallpaperActivityToken = MockToken().token()
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
assertNull(result, "Should not handle request")
@@ -1807,8 +1965,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
// Should create remove wallpaper transaction
@@ -1824,8 +1982,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
// Should create remove wallpaper transaction
@@ -1842,8 +2000,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
// Should create remove wallpaper transaction
@@ -1859,8 +2017,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
// Should create remove wallpaper transaction
@@ -1877,11 +2035,11 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
// Task is being minimized so mark it as not visible.
- desktopModeTaskRepository
- .updateVisibleFreeformTasks(displayId = DEFAULT_DISPLAY, task2.taskId, false)
+ taskRepository
+ .updateTaskVisibility(displayId = DEFAULT_DISPLAY, task2.taskId, false)
val result = controller.handleRequest(Binder(), createTransition(task2, type = TRANSIT_TO_BACK))
assertNull(result, "Should not handle request")
@@ -1975,9 +2133,9 @@ class DesktopTasksControllerTest : ShellTestCase() {
task1.isFocused = false
task2.isFocused = true
task3.isFocused = false
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, task1.taskId)
- desktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task3.taskId,
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(DEFAULT_DISPLAY, task1.taskId)
+ taskRepository.updateTaskVisibility(DEFAULT_DISPLAY, task3.taskId,
visible = false)
controller.enterFullscreen(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
@@ -1998,7 +2156,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
task1.isFocused = false
task2.isFocused = true
task3.isFocused = false
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
controller.enterFullscreen(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
val wct = getLatestExitDesktopWct()
@@ -2247,9 +2405,9 @@ class DesktopTasksControllerTest : ShellTestCase() {
task1.isFocused = false
task2.isFocused = true
task3.isFocused = false
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
- desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, task1.taskId)
- desktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task3.taskId,
+ taskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.minimizeTask(DEFAULT_DISPLAY, task1.taskId)
+ taskRepository.updateTaskVisibility(DEFAULT_DISPLAY, task3.taskId,
visible = false)
controller.enterSplit(DEFAULT_DISPLAY, leftOrTop = false)
@@ -2275,7 +2433,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
task1.isFocused = false
task2.isFocused = true
task3.isFocused = false
- desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ taskRepository.wallpaperActivityToken = wallpaperToken
controller.enterSplit(DEFAULT_DISPLAY, leftOrTop = false)
@@ -2327,7 +2485,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
controller.toggleDesktopTaskSize(task)
- assertThat(desktopModeTaskRepository.removeBoundsBeforeMaximize(task.taskId)).isEqualTo(bounds)
+ assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isEqualTo(bounds)
}
@Test
@@ -2400,12 +2558,24 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.toggleDesktopTaskSize(task)
// Assert last bounds before maximize removed after use
- assertThat(desktopModeTaskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
+ assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
}
private val desktopWallpaperIntent: Intent
get() = Intent(context, DesktopWallpaperActivity::class.java)
+ private fun addFreeformTaskAtPosition(
+ pos: DesktopTaskPosition,
+ stableBounds: Rect,
+ bounds: Rect = DEFAULT_LANDSCAPE_BOUNDS,
+ offsetPos: Point = Point(0, 0)
+ ): RunningTaskInfo {
+ val offset = pos.getTopLeftCoordinates(stableBounds, bounds)
+ val prevTaskBounds = Rect(bounds)
+ prevTaskBounds.offsetTo(offset.x + offsetPos.x, offset.y + offsetPos.y)
+ return setUpFreeformTask(bounds = prevTaskBounds)
+ }
+
private fun setUpFreeformTask(
displayId: Int = DEFAULT_DISPLAY,
bounds: Rect? = null
@@ -2414,9 +2584,9 @@ class DesktopTasksControllerTest : ShellTestCase() {
val activityInfo = ActivityInfo()
task.topActivityInfo = activityInfo
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
- desktopModeTaskRepository.addActiveTask(displayId, task.taskId)
- desktopModeTaskRepository.updateVisibleFreeformTasks(displayId, task.taskId, visible = true)
- desktopModeTaskRepository.addOrMoveFreeformTaskToTop(displayId, task.taskId)
+ taskRepository.addActiveTask(displayId, task.taskId)
+ taskRepository.updateTaskVisibility(displayId, task.taskId, visible = true)
+ taskRepository.addOrMoveFreeformTaskToTop(displayId, task.taskId)
runningTasks.add(task)
return task
}
@@ -2434,11 +2604,13 @@ class DesktopTasksControllerTest : ShellTestCase() {
windowingMode: Int = WINDOWING_MODE_FULLSCREEN,
deviceOrientation: Int = ORIENTATION_LANDSCAPE,
screenOrientation: Int = SCREEN_ORIENTATION_UNSPECIFIED,
- shouldLetterbox: Boolean = false
+ shouldLetterbox: Boolean = false,
+ gravity: Int = Gravity.NO_GRAVITY
): RunningTaskInfo {
val task = createFullscreenTask(displayId)
val activityInfo = ActivityInfo()
activityInfo.screenOrientation = screenOrientation
+ activityInfo.windowLayout = ActivityInfo.WindowLayout(0, 0F, 0, 0F, gravity, 0, 0)
with(task) {
topActivityInfo = activityInfo
isResizeable = isResizable
@@ -2479,11 +2651,23 @@ class DesktopTasksControllerTest : ShellTestCase() {
private fun setUpLandscapeDisplay() {
whenever(displayLayout.width()).thenReturn(DISPLAY_DIMENSION_LONG)
whenever(displayLayout.height()).thenReturn(DISPLAY_DIMENSION_SHORT)
+ val stableBounds = Rect(0, 0, DISPLAY_DIMENSION_LONG,
+ DISPLAY_DIMENSION_SHORT - Companion.TASKBAR_FRAME_HEIGHT
+ )
+ whenever(displayLayout.getStableBoundsForDesktopMode(any())).thenAnswer { i ->
+ (i.arguments.first() as Rect).set(stableBounds)
+ }
}
private fun setUpPortraitDisplay() {
whenever(displayLayout.width()).thenReturn(DISPLAY_DIMENSION_SHORT)
whenever(displayLayout.height()).thenReturn(DISPLAY_DIMENSION_LONG)
+ val stableBounds = Rect(0, 0, DISPLAY_DIMENSION_SHORT,
+ DISPLAY_DIMENSION_LONG - Companion.TASKBAR_FRAME_HEIGHT
+ )
+ whenever(displayLayout.getStableBoundsForDesktopMode(any())).thenAnswer { i ->
+ (i.arguments.first() as Rect).set(stableBounds)
+ }
}
private fun setUpSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
@@ -2495,12 +2679,12 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
private fun markTaskVisible(task: RunningTaskInfo) {
- desktopModeTaskRepository.updateVisibleFreeformTasks(
+ taskRepository.updateTaskVisibility(
task.displayId, task.taskId, visible = true)
}
private fun markTaskHidden(task: RunningTaskInfo) {
- desktopModeTaskRepository.updateVisibleFreeformTasks(
+ taskRepository.updateTaskVisibility(
task.displayId, task.taskId, visible = false)
}
@@ -2601,6 +2785,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
const val SECOND_DISPLAY = 2
val STABLE_BOUNDS = Rect(0, 0, 1000, 1000)
const val MAX_TASK_LIMIT = 6
+ private const val TASKBAR_FRAME_HEIGHT = 200
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
index 70f3bf8828fa..2d0e428c45cb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
@@ -30,6 +30,8 @@ import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_MINIMIZE_WINDOW
+import com.android.internal.jank.InteractionJankMonitor
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
@@ -47,6 +49,8 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.`when`
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.verify
import org.mockito.quality.Strictness
@@ -65,6 +69,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
@Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer
@Mock lateinit var transitions: Transitions
+ @Mock lateinit var interactionJankMonitor: InteractionJankMonitor
private lateinit var mockitoSession: StaticMockitoSession
private lateinit var desktopTasksLimiter: DesktopTasksLimiter
@@ -79,7 +84,8 @@ class DesktopTasksLimiterTest : ShellTestCase() {
desktopTaskRepo = DesktopModeTaskRepository()
desktopTasksLimiter =
- DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, MAX_TASK_LIMIT)
+ DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, MAX_TASK_LIMIT,
+ interactionJankMonitor, mContext)
}
@After
@@ -90,14 +96,16 @@ class DesktopTasksLimiterTest : ShellTestCase() {
@Test
fun createDesktopTasksLimiter_withZeroLimit_shouldThrow() {
assertFailsWith<IllegalArgumentException> {
- DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, 0)
+ DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, 0,
+ interactionJankMonitor, mContext)
}
}
@Test
fun createDesktopTasksLimiter_withNegativeLimit_shouldThrow() {
assertFailsWith<IllegalArgumentException> {
- DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, -5)
+ DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, -5,
+ interactionJankMonitor, mContext)
}
}
@@ -325,7 +333,8 @@ class DesktopTasksLimiterTest : ShellTestCase() {
@Test
fun getTaskToMinimizeIfNeeded_tasksAboveLimit_otherLimit_returnsBackTask() {
desktopTasksLimiter =
- DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, MAX_TASK_LIMIT2)
+ DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, MAX_TASK_LIMIT2,
+ interactionJankMonitor, mContext)
val tasks = (1..MAX_TASK_LIMIT2 + 1).map { setUpFreeformTask() }
val minimizedTask = desktopTasksLimiter.getTaskToMinimizeIfNeeded(
@@ -347,6 +356,91 @@ class DesktopTasksLimiterTest : ShellTestCase() {
assertThat(minimizedTask).isEqualTo(tasks.last())
}
+ @Test
+ fun minimizeTransitionReadyAndFinished_logsJankInstrumentationBeginAndEnd() {
+ (1..<MAX_TASK_LIMIT).forEach { _ -> setUpFreeformTask() }
+ val transition = Binder()
+ val task = setUpFreeformTask()
+ desktopTasksLimiter.addPendingMinimizeChange(
+ transition, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
+
+ desktopTasksLimiter.getTransitionObserver().onTransitionReady(
+ transition,
+ TransitionInfoBuilder(TRANSIT_OPEN).build(),
+ StubTransaction() /* startTransaction */,
+ StubTransaction() /* finishTransaction */)
+
+ desktopTasksLimiter.getTransitionObserver().onTransitionStarting(transition)
+
+ verify(interactionJankMonitor).begin(
+ any(),
+ eq(mContext),
+ eq(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW))
+
+ desktopTasksLimiter.getTransitionObserver().onTransitionFinished(
+ transition,
+ /* aborted = */ false)
+
+ verify(interactionJankMonitor).end(eq(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW))
+ }
+
+ @Test
+ fun minimizeTransitionReadyAndAborted_logsJankInstrumentationBeginAndCancel() {
+ (1..<MAX_TASK_LIMIT).forEach { _ -> setUpFreeformTask() }
+ val transition = Binder()
+ val task = setUpFreeformTask()
+ desktopTasksLimiter.addPendingMinimizeChange(
+ transition, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
+
+ desktopTasksLimiter.getTransitionObserver().onTransitionReady(
+ transition,
+ TransitionInfoBuilder(TRANSIT_OPEN).build(),
+ StubTransaction() /* startTransaction */,
+ StubTransaction() /* finishTransaction */)
+
+ desktopTasksLimiter.getTransitionObserver().onTransitionStarting(transition)
+
+ verify(interactionJankMonitor).begin(
+ any(),
+ eq(mContext),
+ eq(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW))
+
+ desktopTasksLimiter.getTransitionObserver().onTransitionFinished(
+ transition,
+ /* aborted = */ true)
+
+ verify(interactionJankMonitor).cancel(eq(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW))
+ }
+
+ @Test
+ fun minimizeTransitionReadyAndMerged_logsJankInstrumentationBeginAndEnd() {
+ (1..<MAX_TASK_LIMIT).forEach { _ -> setUpFreeformTask() }
+ val mergedTransition = Binder()
+ val newTransition = Binder()
+ val task = setUpFreeformTask()
+ desktopTasksLimiter.addPendingMinimizeChange(
+ mergedTransition, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
+
+ desktopTasksLimiter.getTransitionObserver().onTransitionReady(
+ mergedTransition,
+ TransitionInfoBuilder(TRANSIT_OPEN).build(),
+ StubTransaction() /* startTransaction */,
+ StubTransaction() /* finishTransaction */)
+
+ desktopTasksLimiter.getTransitionObserver().onTransitionStarting(mergedTransition)
+
+ verify(interactionJankMonitor).begin(
+ any(),
+ eq(mContext),
+ eq(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW))
+
+ desktopTasksLimiter.getTransitionObserver().onTransitionMerged(
+ mergedTransition,
+ newTransition)
+
+ verify(interactionJankMonitor).end(eq(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW))
+ }
+
private fun setUpFreeformTask(
displayId: Int = DEFAULT_DISPLAY,
): RunningTaskInfo {
@@ -358,7 +452,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
}
private fun markTaskVisible(task: RunningTaskInfo) {
- desktopTaskRepo.updateVisibleFreeformTasks(
+ desktopTaskRepo.updateTaskVisibility(
task.displayId,
task.taskId,
visible = true
@@ -366,7 +460,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
}
private fun markTaskHidden(task: RunningTaskInfo) {
- desktopTaskRepo.updateVisibleFreeformTasks(
+ desktopTaskRepo.updateTaskVisibility(
task.displayId,
task.taskId,
visible = false
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 409b87723e79..81e6d071045a 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
@@ -442,6 +442,27 @@ public class ShellTransitionTests extends ShellTestCase {
}
@Test
+ public void testTransitionFilterAnimOverride() {
+ TransitionFilter filter = new TransitionFilter();
+ filter.mRequirements =
+ new TransitionFilter.Requirement[]{new TransitionFilter.Requirement()};
+ filter.mRequirements[0].mCustomAnimation = true;
+ filter.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
+
+ final RunningTaskInfo taskInf = createTaskInfo(1);
+ final TransitionInfo openTask = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(TRANSIT_OPEN, taskInf).build();
+ assertFalse(filter.matches(openTask));
+
+ final TransitionInfo.AnimationOptions overOpts =
+ TransitionInfo.AnimationOptions.makeCustomAnimOptions("pakname", 0, 0, 0, true);
+ final TransitionInfo openTaskOpts = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(TRANSIT_OPEN, taskInf).build();
+ openTaskOpts.getChanges().get(0).setAnimationOptions(overOpts);
+ assertTrue(filter.matches(openTaskOpts));
+ }
+
+ @Test
public void testRegisteredRemoteTransition() {
Transitions transitions = createTestTransitions();
transitions.replaceDefaultHandlerForTest(mDefaultHandler);
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 01c4f3ad6870..e26416047c56 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
@@ -103,6 +103,8 @@ import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
import java.util.Optional
import java.util.function.Supplier
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
/**
* Tests of [DesktopModeWindowDecorViewModel]
@@ -206,25 +208,13 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
val decoration = setUpMockDecorationForTask(task)
onTaskOpening(task, taskSurface)
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
task.setWindowingMode(WINDOWING_MODE_UNDEFINED)
task.setActivityType(ACTIVITY_TYPE_UNDEFINED)
onTaskChanging(task, taskSurface)
- verify(mockDesktopModeWindowDecorFactory).create(
- mContext,
- mockDisplayController,
- mockSplitScreenController,
- mockTaskOrganizer,
- task,
- taskSurface,
- mockMainHandler,
- bgExecutor,
- mockMainChoreographer,
- mockSyncQueue,
- mockRootTaskDisplayAreaOrganizer,
- mockGenericLinksParser
- )
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
verify(decoration).close()
}
@@ -238,38 +228,12 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
setUpMockDecorationForTask(task)
onTaskChanging(task, taskSurface)
- verify(mockDesktopModeWindowDecorFactory, never()).create(
- mContext,
- mockDisplayController,
- mockSplitScreenController,
- mockTaskOrganizer,
- task,
- taskSurface,
- mockMainHandler,
- bgExecutor,
- mockMainChoreographer,
- mockSyncQueue,
- mockRootTaskDisplayAreaOrganizer,
- mockGenericLinksParser
- )
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
task.setWindowingMode(WINDOWING_MODE_FREEFORM)
task.setActivityType(ACTIVITY_TYPE_STANDARD)
onTaskChanging(task, taskSurface)
- verify(mockDesktopModeWindowDecorFactory, times(1)).create(
- mContext,
- mockDisplayController,
- mockSplitScreenController,
- mockTaskOrganizer,
- task,
- taskSurface,
- mockMainHandler,
- bgExecutor,
- mockMainChoreographer,
- mockSyncQueue,
- mockRootTaskDisplayAreaOrganizer,
- mockGenericLinksParser
- )
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
}
@Test
@@ -364,9 +328,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
task.setWindowingMode(ACTIVITY_TYPE_UNDEFINED)
onTaskChanging(task)
- verify(mockDesktopModeWindowDecorFactory, never())
- .create(any(), any(), any(), any(), eq(task), any(), any(), any(), any(), any(),
- any(), any())
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
}
@Test
@@ -386,9 +348,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
setUpMockDecorationsForTasks(task)
onTaskOpening(task)
- verify(mockDesktopModeWindowDecorFactory)
- .create(any(), any(), any(), any(), eq(task), any(), any(), any(), any(),
- any(), any(), any())
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
} finally {
mockitoSession.finishMocking()
}
@@ -404,9 +364,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
}
onTaskOpening(task)
- verify(mockDesktopModeWindowDecorFactory, never())
- .create(any(), any(), any(), any(), eq(task), any(), any(), any(), any(), any(),
- any(), any())
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
}
@Test
@@ -422,9 +380,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onTaskOpening(task)
- verify(mockDesktopModeWindowDecorFactory, never())
- .create(any(), any(), any(), any(), eq(task), any(), any(), any(), any(), any(),
- any(), any())
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
}
@Test
@@ -520,9 +476,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
onTaskOpening(task)
- verify(mockDesktopModeWindowDecorFactory, never())
- .create(any(), any(), any(), any(), eq(task), any(), any(), any(), any(), any(),
- any(), any())
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
} finally {
mockitoSession.finishMocking()
}
@@ -545,9 +499,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
setUpMockDecorationsForTasks(task)
onTaskOpening(task)
- verify(mockDesktopModeWindowDecorFactory)
- .create(any(), any(), any(), any(), eq(task), any(), any(), any(), any(), any(),
- any(), any())
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
} finally {
mockitoSession.finishMocking()
}
@@ -569,9 +521,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
setUpMockDecorationsForTasks(task)
onTaskOpening(task)
- verify(mockDesktopModeWindowDecorFactory)
- .create(any(), any(), any(), any(), eq(task), any(), any(), any(), any(), any(),
- any(), any())
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
} finally {
mockitoSession.finishMocking()
}
@@ -693,7 +643,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@WindowConfiguration.WindowingMode windowingMode: Int,
activityType: Int = ACTIVITY_TYPE_STANDARD,
focused: Boolean = true,
- activityInfo: ActivityInfo = ActivityInfo()
+ activityInfo: ActivityInfo = ActivityInfo(),
): RunningTaskInfo {
return TestRunningTaskInfoBuilder()
.setDisplayId(displayId)
@@ -709,8 +659,8 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
private fun setUpMockDecorationForTask(task: RunningTaskInfo): DesktopModeWindowDecoration {
val decoration = mock(DesktopModeWindowDecoration::class.java)
whenever(
- mockDesktopModeWindowDecorFactory.create(any(), any(), any(), any(), eq(task), any(),
- any(), any(), any(), any(), any(), any())
+ mockDesktopModeWindowDecorFactory.create(any(), any(), any(), any(), any(), eq(task),
+ any(), any(), any(), any(), any(), any(), any())
).thenReturn(decoration)
decoration.mTaskInfo = task
whenever(decoration.isFocused).thenReturn(task.isFocused)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index cee9307379ea..04b1eed02950 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -826,10 +826,10 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
ActivityManager.RunningTaskInfo taskInfo,
MaximizeMenuFactory maximizeMenuFactory) {
final DesktopModeWindowDecoration windowDecor = new DesktopModeWindowDecoration(mContext,
- mMockDisplayController, mMockSplitScreenController, mMockShellTaskOrganizer,
- taskInfo, mMockSurfaceControl, mMockHandler, mBgExecutor, mMockChoreographer,
- mMockSyncQueue, mMockRootTaskDisplayAreaOrganizer, mMockGenericLinksParser,
- SurfaceControl.Builder::new, mMockTransactionSupplier,
+ mContext, mMockDisplayController, mMockSplitScreenController,
+ mMockShellTaskOrganizer, taskInfo, mMockSurfaceControl, mMockHandler, mBgExecutor,
+ mMockChoreographer, mMockSyncQueue, mMockRootTaskDisplayAreaOrganizer,
+ mMockGenericLinksParser, SurfaceControl.Builder::new, mMockTransactionSupplier,
WindowContainerTransaction::new, SurfaceControl::new,
mMockSurfaceControlViewHostFactory, maximizeMenuFactory, mMockHandleMenuFactory);
windowDecor.setCaptionListeners(mMockTouchEventListener, mMockTouchEventListener,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index ca6e03c45e7e..e6e2d0928240 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -51,6 +51,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.quality.Strictness.LENIENT;
+import android.annotation.NonNull;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
@@ -893,8 +894,8 @@ public class WindowDecorationTests extends ShellTestCase {
}
private TestWindowDecoration createWindowDecoration(ActivityManager.RunningTaskInfo taskInfo) {
- return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer,
- taskInfo, mMockTaskSurface,
+ return new TestWindowDecoration(mContext, mContext, mMockDisplayController,
+ mMockShellTaskOrganizer, taskInfo, mMockTaskSurface,
new MockObjectSupplier<>(mMockSurfaceControlBuilders,
() -> createMockSurfaceControlBuilder(mock(SurfaceControl.class))),
new MockObjectSupplier<>(mMockSurfaceControlTransactions,
@@ -932,7 +933,8 @@ public class WindowDecorationTests extends ShellTestCase {
}
private class TestWindowDecoration extends WindowDecoration<TestView> {
- TestWindowDecoration(Context context, DisplayController displayController,
+ TestWindowDecoration(Context context, @NonNull Context userContext,
+ DisplayController displayController,
ShellTaskOrganizer taskOrganizer, ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
@@ -940,7 +942,7 @@ public class WindowDecorationTests extends ShellTestCase {
Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
Supplier<SurfaceControl> surfaceControlSupplier,
SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
- super(context, displayController, taskOrganizer, taskInfo, taskSurface,
+ super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface,
surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
windowContainerTransactionSupplier, surfaceControlSupplier,
surfaceControlViewHostFactory);
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index e302fa8b1fc3..d71f3b6884ae 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -736,6 +736,7 @@ cc_defaults {
cc_test {
name: "hwui_unit_tests",
+ test_config: "tests/unit/AndroidTest.xml",
defaults: [
"hwui_test_defaults",
"android_graphics_apex",
@@ -803,6 +804,7 @@ cc_test {
cc_benchmark {
name: "hwuimacro",
+ test_config: "tests/macrobench/AndroidTest.xml",
defaults: ["hwui_test_defaults"],
static_libs: ["libhwui"],
@@ -822,6 +824,7 @@ cc_benchmark {
cc_benchmark {
name: "hwuimicro",
+ test_config: "tests/microbench/AndroidTest.xml",
defaults: ["hwui_test_defaults"],
static_libs: ["libhwui_static"],
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 5d3bc89b40dd..d184f64b1c2c 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -101,6 +101,8 @@ float Properties::maxHdrHeadroomOn8bit = 5.f; // TODO: Refine this number
bool Properties::clipSurfaceViews = false;
bool Properties::hdr10bitPlus = false;
+int Properties::timeoutMultiplier = 1;
+
StretchEffectBehavior Properties::stretchEffectBehavior = StretchEffectBehavior::ShaderHWUI;
DrawingEnabled Properties::drawingEnabled = DrawingEnabled::NotInitialized;
@@ -174,6 +176,8 @@ bool Properties::load() {
base::GetBoolProperty("debug.hwui.clip_surfaceviews", hwui_flags::clip_surfaceviews());
hdr10bitPlus = hwui_flags::hdr_10bit_plus();
+ timeoutMultiplier = android::base::GetIntProperty("ro.hw_timeout_multiplier", 1);
+
return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
}
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index d3176f6879d2..e2646422030e 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -343,6 +343,8 @@ public:
static bool clipSurfaceViews;
static bool hdr10bitPlus;
+ static int timeoutMultiplier;
+
static StretchEffectBehavior getStretchEffectBehavior() {
return stretchEffectBehavior;
}
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index afe4c3896ed2..2f15722a23e0 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -91,8 +91,10 @@ void Readback::copySurfaceInto(ANativeWindow* window, const std::shared_ptr<Copy
{
ATRACE_NAME("sync_wait");
- if (sourceFence != -1 && sync_wait(sourceFence.get(), 500 /* ms */) != NO_ERROR) {
- ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt");
+ int syncWaitTimeoutMs = 500 * Properties::timeoutMultiplier;
+ if (sourceFence != -1 && sync_wait(sourceFence.get(), syncWaitTimeoutMs) != NO_ERROR) {
+ ALOGE("Timeout (%dms) exceeded waiting for buffer fence, abandoning readback attempt",
+ syncWaitTimeoutMs);
return request->onCopyFinished(CopyResult::Timeout);
}
}
@@ -109,9 +111,8 @@ void Readback::copySurfaceInto(ANativeWindow* window, const std::shared_ptr<Copy
sk_sp<SkColorSpace> colorSpace =
DataSpaceToColorSpace(static_cast<android_dataspace>(dataspace));
- sk_sp<SkImage> image =
- SkImages::DeferredFromAHardwareBuffer(sourceBuffer.get(), kPremul_SkAlphaType,
- colorSpace);
+ sk_sp<SkImage> image = SkImages::DeferredFromAHardwareBuffer(sourceBuffer.get(),
+ kPremul_SkAlphaType, colorSpace);
if (!image.get()) {
return request->onCopyFinished(CopyResult::UnknownError);
diff --git a/libs/hwui/tests/macrobench/AndroidTest.xml b/libs/hwui/tests/macrobench/AndroidTest.xml
new file mode 100644
index 000000000000..5b8576d444cd
--- /dev/null
+++ b/libs/hwui/tests/macrobench/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2024 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.
+-->
+<configuration description="Config for hwuimacro">
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="hwuimacro->/data/local/tmp/benchmarktest/hwuimacro" />
+ </target_preparer>
+ <option name="test-suite-tag" value="apct" />
+ <option name="not-shardable" value="true" />
+ <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
+ <option name="native-benchmark-device-path" value="/data/local/tmp/benchmarktest" />
+ <option name="benchmark-module-name" value="hwuimacro" />
+ <option name="file-exclusion-filter-regex" value=".*\.config$" />
+ </test>
+</configuration>
diff --git a/libs/hwui/tests/macrobench/how_to_run.txt b/libs/hwui/tests/macrobench/how_to_run.txt
index 3c3d36a8977f..59ef25a3aacc 100644
--- a/libs/hwui/tests/macrobench/how_to_run.txt
+++ b/libs/hwui/tests/macrobench/how_to_run.txt
@@ -3,3 +3,7 @@ adb push $OUT/data/benchmarktest/hwuimacro/hwuimacro /data/benchmarktest/hwuimac
adb shell /data/benchmarktest/hwuimacro/hwuimacro shadowgrid2 --onscreen
Pass --help to get help
+
+OR (if you don't need to pass arguments)
+
+atest hwuimacro
diff --git a/libs/hwui/AndroidTest.xml b/libs/hwui/tests/microbench/AndroidTest.xml
index 75f61f5f7f9d..d67305dfa323 100644
--- a/libs/hwui/AndroidTest.xml
+++ b/libs/hwui/tests/microbench/AndroidTest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright 2024 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.
@@ -16,24 +16,13 @@
<configuration description="Config for hwuimicro">
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
- <option name="push" value="hwui_unit_tests->/data/local/tmp/nativetest/hwui_unit_tests" />
<option name="push" value="hwuimicro->/data/local/tmp/benchmarktest/hwuimicro" />
- <option name="push" value="hwuimacro->/data/local/tmp/benchmarktest/hwuimacro" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="not-shardable" value="true" />
- <test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
- <option name="module-name" value="hwui_unit_tests" />
- </test>
<test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
<option name="native-benchmark-device-path" value="/data/local/tmp/benchmarktest" />
<option name="benchmark-module-name" value="hwuimicro" />
<option name="file-exclusion-filter-regex" value=".*\.config$" />
</test>
- <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
- <option name="native-benchmark-device-path" value="/data/local/tmp/benchmarktest" />
- <option name="benchmark-module-name" value="hwuimacro" />
- <option name="file-exclusion-filter-regex" value=".*\.config$" />
- </test>
</configuration>
diff --git a/libs/hwui/tests/microbench/how_to_run.txt b/libs/hwui/tests/microbench/how_to_run.txt
index 915fe5d959f9..c7ddc1a70cd7 100755
--- a/libs/hwui/tests/microbench/how_to_run.txt
+++ b/libs/hwui/tests/microbench/how_to_run.txt
@@ -1,3 +1,7 @@
mmm -j8 frameworks/base/libs/hwui &&
adb push $OUT/data/benchmarktest/hwuimicro/hwuimicro /data/benchmarktest/hwuimicro/hwuimicro &&
adb shell /data/benchmarktest/hwuimicro/hwuimicro
+
+OR
+
+atest hwuimicro
diff --git a/libs/hwui/tests/unit/AndroidTest.xml b/libs/hwui/tests/unit/AndroidTest.xml
new file mode 100644
index 000000000000..dc586c9b740c
--- /dev/null
+++ b/libs/hwui/tests/unit/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2024 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.
+-->
+<configuration description="Config for hwui_unit_tests">
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="hwui_unit_tests->/data/local/tmp/nativetest/hwui_unit_tests" />
+ </target_preparer>
+ <option name="test-suite-tag" value="apct" />
+ <option name="not-shardable" value="true" />
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="module-name" value="hwui_unit_tests" />
+ </test>
+</configuration>
diff --git a/libs/hwui/tests/unit/how_to_run.txt b/libs/hwui/tests/unit/how_to_run.txt
index c11d6eb33358..1a35adf6b11b 100755
--- a/libs/hwui/tests/unit/how_to_run.txt
+++ b/libs/hwui/tests/unit/how_to_run.txt
@@ -2,3 +2,11 @@ mmm -j8 frameworks/base/libs/hwui &&
adb push $ANDROID_PRODUCT_OUT/data/nativetest/hwui_unit_tests/hwui_unit_tests \
/data/nativetest/hwui_unit_tests/hwui_unit_tests &&
adb shell /data/nativetest/hwui_unit_tests/hwui_unit_tests
+
+OR
+
+atest hwui_unit_tests
+
+OR, if you need arguments, they can be passed as native-test-flags, as in:
+
+atest hwui_unit_tests -- --test-arg com.android.tradefed.testtype.GTest:native-test-flag:"--renderer=skiavk"
diff --git a/libs/hwui/tests/unit/main.cpp b/libs/hwui/tests/unit/main.cpp
index 76cbc8abc808..3fd15c4c9c51 100644
--- a/libs/hwui/tests/unit/main.cpp
+++ b/libs/hwui/tests/unit/main.cpp
@@ -15,6 +15,7 @@
*/
#include <getopt.h>
+#include <log/log.h>
#include <signal.h>
#include "Properties.h"
@@ -65,6 +66,19 @@ static RenderPipelineType parseRenderer(const char* renderer) {
return RenderPipelineType::SkiaGL;
}
+static constexpr const char* renderPipelineTypeName(const RenderPipelineType renderPipelineType) {
+ switch (renderPipelineType) {
+ case RenderPipelineType::SkiaGL:
+ return "SkiaGL";
+ case RenderPipelineType::SkiaVulkan:
+ return "SkiaVulkan";
+ case RenderPipelineType::SkiaCpu:
+ return "SkiaCpu";
+ case RenderPipelineType::NotInitialized:
+ return "NotInitialized";
+ }
+}
+
struct Options {
RenderPipelineType renderer = RenderPipelineType::SkiaGL;
};
@@ -118,6 +132,7 @@ int main(int argc, char* argv[]) {
auto opts = parseOptions(argc, argv);
Properties::overrideRenderPipelineType(opts.renderer);
+ ALOGI("Starting HWUI unit tests with %s pipeline", renderPipelineTypeName(opts.renderer));
// Run the tests
testing::InitGoogleTest(&argc, argv);