Merge "Fix user category priority issue" into main
diff --git a/core/java/android/app/admin/SystemUpdatePolicy.java b/core/java/android/app/admin/SystemUpdatePolicy.java
index 7320cea..dede5b5 100644
--- a/core/java/android/app/admin/SystemUpdatePolicy.java
+++ b/core/java/android/app/admin/SystemUpdatePolicy.java
@@ -78,6 +78,11 @@
*
* <h3>Developer guide</h3>
* To learn more, read <a href="{@docRoot}work/dpc/system-updates">Manage system updates</a>.
+ * <p><strong>Note:</strong> <a href="https://source.android.com/docs/core/ota/modular-system">
+ * Google Play system updates</a> (also called Mainline updates) are automatically downloaded
+ * but require a device reboot to be installed. Refer to the mainline section in
+ * <a href="{@docRoot}work/dpc/system-updates#mainline">Manage system
+ * updates</a> for further details.</p>
*
* @see DevicePolicyManager#setSystemUpdatePolicy
* @see DevicePolicyManager#getSystemUpdatePolicy
diff --git a/core/java/android/view/ImeBackAnimationController.java b/core/java/android/view/ImeBackAnimationController.java
index 1afedc1..4530157 100644
--- a/core/java/android/view/ImeBackAnimationController.java
+++ b/core/java/android/view/ImeBackAnimationController.java
@@ -134,7 +134,9 @@
@Override
public void onBackInvoked() {
- if (!isBackAnimationAllowed()) {
+ if (!isBackAnimationAllowed() || !mIsPreCommitAnimationInProgress) {
+ // play regular hide animation if back-animation is not allowed or if insets control has
+ // been cancelled by the system (this can happen in split screen for example)
mInsetsController.hide(ime());
return;
}
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index 5c113f8..461eab6 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -18,6 +18,7 @@
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
@@ -93,6 +94,19 @@
@TaskFragmentTransitionType
public static final int TASK_FRAGMENT_TRANSIT_CHANGE = TRANSIT_CHANGE;
+
+ /**
+ * The task fragment drag resize transition used by activity embedding.
+ *
+ * This value is also used in Transitions.TRANSIT_TASK_FRAGMENT_DRAG_RESIZE and must not
+ * conflict with other predefined transition types.
+ *
+ * @hide
+ */
+ @WindowManager.TransitionType
+ @TaskFragmentTransitionType
+ public static final int TASK_FRAGMENT_TRANSIT_DRAG_RESIZE = TRANSIT_FIRST_CUSTOM + 17;
+
/**
* Introduced a sub set of {@link WindowManager.TransitionType} for the types that are used for
* TaskFragment transition.
@@ -106,6 +120,7 @@
TASK_FRAGMENT_TRANSIT_OPEN,
TASK_FRAGMENT_TRANSIT_CLOSE,
TASK_FRAGMENT_TRANSIT_CHANGE,
+ TASK_FRAGMENT_TRANSIT_DRAG_RESIZE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TaskFragmentTransitionType {}
diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
index f2d2c1b..6ffa826 100644
--- a/core/java/com/android/internal/jank/Cuj.java
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -134,10 +134,12 @@
public static final int CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK = 99;
public static final int CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK = 100;
public static final int CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK = 101;
+ public static final int CUJ_LAUNCHER_PRIVATE_SPACE_LOCK = 102;
+ public static final int CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK = 103;
// When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
@VisibleForTesting
- static final int LAST_CUJ = CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK;
+ static final int LAST_CUJ = CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK;
/** @hide */
@IntDef({
@@ -230,7 +232,9 @@
CUJ_LAUNCHER_TASKBAR_ALL_APPS_SEARCH_BACK,
CUJ_LAUNCHER_WIDGET_PICKER_CLOSE_BACK,
CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK,
- CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK
+ CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK,
+ CUJ_LAUNCHER_PRIVATE_SPACE_LOCK,
+ CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {
@@ -335,6 +339,8 @@
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WIDGET_PICKER_SEARCH_BACK;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_PRIVATE_SPACE_LOCK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_PRIVATE_SPACE_LOCK;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_PRIVATE_SPACE_UNLOCK;
}
private Cuj() {
@@ -533,6 +539,10 @@
return "LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK";
case CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK:
return "LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK";
+ case CUJ_LAUNCHER_PRIVATE_SPACE_LOCK:
+ return "LAUNCHER_PRIVATE_SPACE_LOCK";
+ case CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK:
+ return "LAUNCHER_PRIVATE_SPACE_UNLOCK";
}
return "UNKNOWN";
}
diff --git a/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java b/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
index c00ebe4..57bbb1c 100644
--- a/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
+++ b/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
@@ -241,6 +241,23 @@
});
}
+ @Test
+ public void testOnBackInvokedHidesImeEvenIfInsetsControlCancelled() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ // start back gesture
+ WindowInsetsAnimationControlListener animationControlListener = startBackGesture();
+
+ // simulate ImeBackAnimationController not receiving control (e.g. due to split screen)
+ animationControlListener.onCancelled(mWindowInsetsAnimationController);
+
+ // commit back gesture
+ mBackAnimationController.onBackInvoked();
+
+ // verify that InsetsController#hide is called
+ verify(mInsetsController, times(1)).hide(ime());
+ });
+ }
+
private WindowInsetsAnimationControlListener startBackGesture() {
// start back gesture
mBackAnimationController.onBackStarted(new BackEvent(0f, 0f, 0f, EDGE_LEFT));
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 f3113a7..14388a6 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -28,6 +28,7 @@
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO;
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_THROWABLE;
import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CLOSE;
+import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_DRAG_RESIZE;
import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_OPEN;
import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENTED_TO_TASK;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED;
@@ -3251,6 +3252,7 @@
synchronized (mLock) {
final TransactionRecord transactionRecord =
mTransactionManager.startNewTransaction();
+ transactionRecord.setOriginType(TASK_FRAGMENT_TRANSIT_DRAG_RESIZE);
final WindowContainerTransaction wct = transactionRecord.getTransaction();
final TaskContainer taskContainer = mTaskContainers.get(taskId);
if (taskContainer != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index d44033c..a426b20 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -26,6 +26,7 @@
import static com.android.wm.shell.transition.TransitionAnimationHelper.addBackgroundToTransition;
import static com.android.wm.shell.transition.TransitionAnimationHelper.edgeExtendWindow;
import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_TASK_FRAGMENT_DRAG_RESIZE;
import android.animation.Animator;
import android.animation.ValueAnimator;
@@ -190,6 +191,10 @@
@NonNull
private List<ActivityEmbeddingAnimationAdapter> createAnimationAdapters(
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction) {
+ if (info.getType() == TRANSIT_TASK_FRAGMENT_DRAG_RESIZE) {
+ // Jump cut for AE drag resizing because the content is veiled.
+ return new ArrayList<>();
+ }
boolean isChangeTransition = false;
for (TransitionInfo.Change change : info.getChanges()) {
if (change.hasFlags(FLAG_IS_BEHIND_STARTING_WINDOW)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
index 1f9358e..d6b9d34 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
@@ -22,6 +22,7 @@
import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
import static com.android.wm.shell.transition.DefaultTransitionHandler.isSupportedOverrideAnimation;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_TASK_FRAGMENT_DRAG_RESIZE;
import static java.util.Objects.requireNonNull;
@@ -90,6 +91,12 @@
/** Whether ActivityEmbeddingController should animate this transition. */
public boolean shouldAnimate(@NonNull TransitionInfo info) {
+ if (info.getType() == TRANSIT_TASK_FRAGMENT_DRAG_RESIZE) {
+ // The TRANSIT_TASK_FRAGMENT_DRAG_RESIZE type happens when the user drags the
+ // interactive divider to resize the split containers. The content is veiled, so we will
+ // handle the transition with a jump cut.
+ return true;
+ }
boolean containsEmbeddingChange = false;
for (TransitionInfo.Change change : info.getChanges()) {
if (!change.hasFlags(FLAG_FILLS_TASK) && change.hasFlags(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java
index cf3ad42..713d04bc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java
@@ -194,6 +194,10 @@
return mHideSizeCompatRestartButtonTolerance;
}
+ int getDefaultHideRestartButtonTolerance() {
+ return MAX_PERCENTAGE_VAL;
+ }
+
boolean getHasSeenLetterboxEducation(int userId) {
return mLetterboxEduSharedPreferences
.getBoolean(dontShowLetterboxEduKey(userId), /* default= */ 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 4e5c2fa..f195f95 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
@@ -20,11 +20,11 @@
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;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.AppCompatTaskInfo;
import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.content.Context;
@@ -219,14 +219,30 @@
@VisibleForTesting
boolean shouldShowSizeCompatRestartButton(@NonNull TaskInfo taskInfo) {
- if (!Flags.allowHideScmButton()) {
+ // Always show button if display is phone sized.
+ if (!Flags.allowHideScmButton() || taskInfo.configuration.smallestScreenWidthDp
+ < LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP) {
return true;
}
- final AppCompatTaskInfo appCompatTaskInfo = taskInfo.appCompatTaskInfo;
- final Rect taskBounds = taskInfo.configuration.windowConfiguration.getBounds();
- final int letterboxArea = computeArea(appCompatTaskInfo.topActivityLetterboxWidth,
- appCompatTaskInfo.topActivityLetterboxHeight);
- final int taskArea = computeArea(taskBounds.width(), taskBounds.height());
+
+ final int letterboxWidth = taskInfo.appCompatTaskInfo.topActivityLetterboxWidth;
+ final int letterboxHeight = taskInfo.appCompatTaskInfo.topActivityLetterboxHeight;
+ final Rect stableBounds = getTaskStableBounds();
+ final int appWidth = stableBounds.width();
+ final int appHeight = stableBounds.height();
+ // App is floating, should always show restart button.
+ if (appWidth > letterboxWidth && appHeight > letterboxHeight) {
+ return true;
+ }
+ // If app fills the width of the display, don't show restart button (for landscape apps)
+ // if device has a custom tolerance value.
+ if (mHideScmTolerance != mCompatUIConfiguration.getDefaultHideRestartButtonTolerance()
+ && appWidth == letterboxWidth) {
+ return false;
+ }
+
+ final int letterboxArea = letterboxWidth * letterboxHeight;
+ final int taskArea = appWidth * appHeight;
if (letterboxArea == 0 || taskArea == 0) {
return false;
}
@@ -234,13 +250,6 @@
return percentageAreaOfLetterboxInTask < mHideScmTolerance;
}
- private int computeArea(int width, int height) {
- if (width == 0 || height == 0) {
- return 0;
- }
- return width * height;
- }
-
private void updateVisibilityOfViews() {
if (mLayout == null) {
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index 9b2922d..4d3c763 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -61,6 +61,7 @@
import android.view.WindowManager;
import android.window.ITransitionPlayer;
import android.window.RemoteTransition;
+import android.window.TaskFragmentOrganizer;
import android.window.TransitionFilter;
import android.window.TransitionInfo;
import android.window.TransitionMetrics;
@@ -183,6 +184,13 @@
/** Transition to resize PiP task. */
public static final int TRANSIT_RESIZE_PIP = TRANSIT_FIRST_CUSTOM + 16;
+ /**
+ * The task fragment drag resize transition used by activity embedding.
+ */
+ public static final int TRANSIT_TASK_FRAGMENT_DRAG_RESIZE =
+ // TRANSIT_FIRST_CUSTOM + 17
+ TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_DRAG_RESIZE;
+
private final ShellTaskOrganizer mOrganizer;
private final Context mContext;
private final ShellExecutor mMainExecutor;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
index 2ac72af..ea522cd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
@@ -20,6 +20,8 @@
import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_TASK_FRAGMENT_DRAG_RESIZE;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -100,6 +102,20 @@
}
@Test
+ public void testTransitionTypeDragResize() {
+ final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TASK_FRAGMENT_DRAG_RESIZE, 0)
+ .addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY))
+ .build();
+ final Animator animator = mAnimRunner.createAnimator(
+ info, mStartTransaction, mFinishTransaction,
+ () -> mFinishCallback.onTransitionFinished(null /* wct */),
+ new ArrayList());
+
+ // The animation should be empty when it is a jump cut for drag resize.
+ assertEquals(0, animator.getDuration());
+ }
+
+ @Test
public void testInvalidCustomAnimation() {
final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
.addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY))
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 5209d0e..41a81c1 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
@@ -22,6 +22,7 @@
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;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -98,14 +99,28 @@
private CompatUIWindowManager mWindowManager;
private TaskInfo mTaskInfo;
+ private DisplayLayout mDisplayLayout;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
doReturn(100).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
mTaskInfo = createTaskInfo(/* hasSizeCompat= */ false, CAMERA_COMPAT_CONTROL_HIDDEN);
+
+ final DisplayInfo displayInfo = new DisplayInfo();
+ displayInfo.logicalWidth = TASK_WIDTH;
+ displayInfo.logicalHeight = TASK_HEIGHT;
+ mDisplayLayout = new DisplayLayout(displayInfo,
+ mContext.getResources(), /* hasNavigationBar= */ true, /* hasStatusBar= */ false);
+ final InsetsState insetsState = new InsetsState();
+ insetsState.setDisplayFrame(new Rect(0, 0, TASK_WIDTH, TASK_HEIGHT));
+ final InsetsSource insetsSource = new InsetsSource(
+ InsetsSource.createId(null, 0, navigationBars()), navigationBars());
+ insetsSource.setFrame(0, TASK_HEIGHT - 200, TASK_WIDTH, TASK_HEIGHT);
+ insetsState.addSource(insetsSource);
+ mDisplayLayout.setInsets(mContext.getResources(), insetsState);
mWindowManager = new CompatUIWindowManager(mContext, mTaskInfo, mSyncTransactionQueue,
- mCallback, mTaskListener, new DisplayLayout(), new CompatUIHintsState(),
+ mCallback, mTaskListener, mDisplayLayout, new CompatUIHintsState(),
mCompatUIConfiguration, mOnRestartButtonClicked);
spyOn(mWindowManager);
@@ -363,9 +378,9 @@
// Update if the insets change on the existing display layout
clearInvocations(mWindowManager);
- InsetsState insetsState = new InsetsState();
+ final InsetsState insetsState = new InsetsState();
insetsState.setDisplayFrame(new Rect(0, 0, 1000, 2000));
- InsetsSource insetsSource = new InsetsSource(
+ final InsetsSource insetsSource = new InsetsSource(
InsetsSource.createId(null, 0, navigationBars()), navigationBars());
insetsSource.setFrame(0, 1800, 1000, 2000);
insetsState.addSource(insetsSource);
@@ -493,16 +508,14 @@
@Test
public void testShouldShowSizeCompatRestartButton() {
mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_HIDE_SCM_BUTTON);
-
- doReturn(86).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
+ doReturn(85).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
mWindowManager = new CompatUIWindowManager(mContext, mTaskInfo, mSyncTransactionQueue,
- mCallback, mTaskListener, new DisplayLayout(), new CompatUIHintsState(),
+ mCallback, mTaskListener, mDisplayLayout, new CompatUIHintsState(),
mCompatUIConfiguration, mOnRestartButtonClicked);
// Simulate rotation of activity in square display
TaskInfo taskInfo = createTaskInfo(true, CAMERA_COMPAT_CONTROL_HIDDEN);
- taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 2000, 2000));
- taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 2000;
+ taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = TASK_HEIGHT;
taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1850;
assertFalse(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));
@@ -512,11 +525,21 @@
assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));
// Simulate folding
- taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 1000, 2000));
- assertFalse(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));
+ final InsetsState insetsState = new InsetsState();
+ insetsState.setDisplayFrame(new Rect(0, 0, 1000, TASK_HEIGHT));
+ final InsetsSource insetsSource = new InsetsSource(
+ InsetsSource.createId(null, 0, navigationBars()), navigationBars());
+ insetsSource.setFrame(0, TASK_HEIGHT - 200, 1000, TASK_HEIGHT);
+ insetsState.addSource(insetsSource);
+ mDisplayLayout.setInsets(mContext.getResources(), insetsState);
+ mWindowManager.updateDisplayLayout(mDisplayLayout);
+ taskInfo.configuration.smallestScreenWidthDp = LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP - 100;
+ assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));
- taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000;
- taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 500;
+ // Simulate floating app with 90& area, more than tolerance
+ taskInfo.configuration.smallestScreenWidthDp = LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
+ taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 950;
+ taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 1900;
assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));
}
@@ -529,10 +552,10 @@
cameraCompatControlState;
taskInfo.configuration.uiMode &= ~Configuration.UI_MODE_TYPE_DESK;
// Letterboxed activity that takes half the screen should show size compat restart button
- taskInfo.configuration.windowConfiguration.setBounds(
- new Rect(0, 0, TASK_WIDTH, TASK_HEIGHT));
taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 1000;
taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000;
+ // Screen width dp larger than a normal phone.
+ taskInfo.configuration.smallestScreenWidthDp = LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
return taskInfo;
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index a7b7da5..30bec77 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -649,6 +649,9 @@
for (CachedBluetoothDevice cbd : mMemberDevices) {
cbd.setName(name);
}
+ if (mSubDevice != null) {
+ mSubDevice.setName(name);
+ }
}
/**
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
index 9bf42f9..ed964a9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
@@ -100,6 +100,7 @@
// device.
if (hearingAidDevice != null) {
hearingAidDevice.setSubDevice(newDevice);
+ newDevice.setName(hearingAidDevice.getName());
return true;
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index b356f54..b4bd482 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -1703,6 +1703,30 @@
}
@Test
+ public void setName_memberDeviceNameIsSet() {
+ when(mDevice.getAlias()).thenReturn(DEVICE_NAME);
+ when(mSubDevice.getAlias()).thenReturn(DEVICE_NAME);
+
+ mCachedDevice.addMemberDevice(mSubCachedDevice);
+ mCachedDevice.setName(DEVICE_ALIAS);
+
+ verify(mDevice).setAlias(DEVICE_ALIAS);
+ verify(mSubDevice).setAlias(DEVICE_ALIAS);
+ }
+
+ @Test
+ public void setName_subDeviceNameIsSet() {
+ when(mDevice.getAlias()).thenReturn(DEVICE_NAME);
+ when(mSubDevice.getAlias()).thenReturn(DEVICE_NAME);
+
+ mCachedDevice.setSubDevice(mSubCachedDevice);
+ mCachedDevice.setName(DEVICE_ALIAS);
+
+ verify(mDevice).setAlias(DEVICE_ALIAS);
+ verify(mSubDevice).setAlias(DEVICE_ALIAS);
+ }
+
+ @Test
public void getProfileConnectionState_nullProfile_returnDisconnected() {
assertThat(mCachedDevice.getProfileConnectionState(null)).isEqualTo(
BluetoothProfile.STATE_DISCONNECTED);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
index 1f0da90..4188d2e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
@@ -299,6 +299,7 @@
mHearingAidDeviceManager.setSubDeviceIfNeeded(mCachedDevice2);
assertThat(mCachedDevice1.getSubDevice()).isEqualTo(mCachedDevice2);
+ verify(mDevice2).setAlias(DEVICE_ALIAS_1);
}
/**
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index 7f94f0d..4e3a032 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -117,6 +117,9 @@
coroutineScope: CoroutineScope,
transitionKey: TransitionKey? = null,
): TransitionState.Transition?
+
+ /** Immediately snap to the given [scene]. */
+ fun snapToScene(scene: SceneKey)
}
/**
@@ -745,6 +748,17 @@
override fun CoroutineScope.onChangeScene(scene: SceneKey) {
setTargetScene(scene, coroutineScope = this)
}
+
+ override fun snapToScene(scene: SceneKey) {
+ // Force finish all transitions.
+ while (currentTransitions.isNotEmpty()) {
+ val transition = transitionStates[0] as TransitionState.Transition
+ finishTransition(transition, transition.currentScene)
+ }
+
+ check(transitionStates.size == 1)
+ transitionStates[0] = TransitionState.Idle(scene)
+ }
}
private const val TAG = "SceneTransitionLayoutState"
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
index f29d0a7..d2c8bd6 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
@@ -635,4 +635,19 @@
Log.setWtfHandler(originalHandler)
}
}
+
+ @Test
+ fun snapToScene() = runMonotonicClockTest {
+ val state = MutableSceneTransitionLayoutState(SceneA)
+
+ // Transition to B.
+ state.setTargetScene(SceneB, coroutineScope = this)
+ val transition = assertThat(state.transitionState).isTransition()
+ assertThat(transition).hasCurrentScene(SceneB)
+
+ // Snap to C.
+ state.snapToScene(SceneC)
+ assertThat(state.transitionState).isIdle()
+ assertThat(state.transitionState).hasCurrentScene(SceneC)
+ }
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 5f13672..a9c47b8 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -6888,7 +6888,7 @@
mIsBoosted = isBoosted;
// The client transaction will be applied together with the next assignLayer.
if (clientTransaction != null) {
- mDecorSurfaceContainer.mPendingClientTransactions.add(clientTransaction);
+ mPendingClientTransactions.add(clientTransaction);
}
}