summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/proto/wm_shell_transition_trace.proto3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java34
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogWindowManager.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt81
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java42
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java9
-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/TaskViewTaskController.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java48
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Tracer.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt74
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java10
-rw-r--r--libs/WindowManager/Shell/tests/OWNERS1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java67
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java97
-rw-r--r--libs/input/PointerController.cpp5
-rw-r--r--libs/input/PointerController.h4
-rw-r--r--libs/input/tests/PointerController_test.cpp2
37 files changed, 533 insertions, 204 deletions
diff --git a/libs/WindowManager/Shell/proto/wm_shell_transition_trace.proto b/libs/WindowManager/Shell/proto/wm_shell_transition_trace.proto
index 6e0110193a05..c82a70c9a44e 100644
--- a/libs/WindowManager/Shell/proto/wm_shell_transition_trace.proto
+++ b/libs/WindowManager/Shell/proto/wm_shell_transition_trace.proto
@@ -37,6 +37,9 @@ message WmShellTransitionTraceProto {
required fixed64 magic_number = 1;
repeated Transition transitions = 2;
repeated HandlerMapping handlerMappings = 3;
+ /* offset between real-time clock and elapsed time clock in nanoseconds.
+ Calculated as: 1000000 * System.currentTimeMillis() - SystemClock.elapsedRealtimeNanos() */
+ optional fixed64 real_to_elapsed_time_offset_nanos = 4;
}
message Transition {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index 19eff0e43169..1793a3d0feb4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -255,7 +255,7 @@ class ActivityEmbeddingAnimationSpec {
private boolean shouldShowBackdrop(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change) {
final Animation a = loadAttributeAnimation(info, change, WALLPAPER_TRANSITION_NONE,
- mTransitionAnimation);
+ mTransitionAnimation, false);
return a != null && a.getShowBackdrop();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index e8014af463bd..adc0c9c4322a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -479,7 +479,7 @@ public class BubbleExpandedView extends LinearLayout {
void applyThemeAttrs() {
final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
android.R.attr.dialogCornerRadius,
- android.R.attr.colorBackgroundFloating});
+ com.android.internal.R.attr.materialColorSurfaceBright});
boolean supportsRoundedCorners = ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
mContext.getResources());
mCornerRadius = supportsRoundedCorners ? ta.getDimensionPixelSize(0, 0) : 0;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index e7dede757578..2832c553c20c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -412,7 +412,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
/** Releases and re-inflates {@link DividerView} on the root surface. */
public void update(SurfaceControl.Transaction t) {
- if (!mInitialized) return;
+ if (!mInitialized) {
+ init();
+ return;
+ }
mSplitWindowManager.release(t);
mImePositionProcessor.reset();
mSplitWindowManager.init(this, mInsetsState);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index 838e37a905db..2bbd870f024d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -47,6 +47,8 @@ import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
+import dagger.Lazy;
+
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
@@ -55,8 +57,6 @@ import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
-import dagger.Lazy;
-
/**
* Controller to show/update compat UI components on Tasks based on whether the foreground
* activities are in compatibility mode.
@@ -284,13 +284,18 @@ public class CompatUIController implements OnDisplaysChangedListener,
ShellTaskOrganizer.TaskListener taskListener) {
CompatUIWindowManager layout = mActiveCompatLayouts.get(taskInfo.taskId);
if (layout != null) {
- // UI already exists, update the UI layout.
- if (!layout.updateCompatInfo(taskInfo, taskListener,
- showOnDisplay(layout.getDisplayId()))) {
- // The layout is no longer eligible to be shown, remove from active layouts.
+ if (layout.needsToBeRecreated(taskInfo, taskListener)) {
mActiveCompatLayouts.remove(taskInfo.taskId);
+ layout.release();
+ } else {
+ // UI already exists, update the UI layout.
+ if (!layout.updateCompatInfo(taskInfo, taskListener,
+ showOnDisplay(layout.getDisplayId()))) {
+ // The layout is no longer eligible to be shown, remove from active layouts.
+ mActiveCompatLayouts.remove(taskInfo.taskId);
+ }
+ return;
}
- return;
}
// Create a new UI layout.
@@ -433,13 +438,18 @@ public class CompatUIController implements OnDisplaysChangedListener,
private void createOrUpdateReachabilityEduLayout(TaskInfo taskInfo,
ShellTaskOrganizer.TaskListener taskListener) {
if (mActiveReachabilityEduLayout != null) {
- // UI already exists, update the UI layout.
- if (!mActiveReachabilityEduLayout.updateCompatInfo(taskInfo, taskListener,
- showOnDisplay(mActiveReachabilityEduLayout.getDisplayId()))) {
- // The layout is no longer eligible to be shown, remove from active layouts.
+ if (mActiveReachabilityEduLayout.needsToBeRecreated(taskInfo, taskListener)) {
+ mActiveReachabilityEduLayout.release();
mActiveReachabilityEduLayout = null;
+ } else {
+ // UI already exists, update the UI layout.
+ if (!mActiveReachabilityEduLayout.updateCompatInfo(taskInfo, taskListener,
+ showOnDisplay(mActiveReachabilityEduLayout.getDisplayId()))) {
+ // The layout is no longer eligible to be shown, remove from active layouts.
+ mActiveReachabilityEduLayout = null;
+ }
+ return;
}
- return;
}
// Create a new UI layout.
final Context context = getOrCreateDisplayContext(taskInfo.displayId);
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 659229228a57..d4778fa7a58a 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
@@ -22,7 +22,6 @@ import static android.app.TaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
import static android.app.TaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
import static android.window.TaskConstants.TASK_CHILD_LAYER_COMPAT_UI;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.TaskInfo;
import android.app.TaskInfo.CameraCompatControlState;
@@ -53,9 +52,6 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
private final Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnRestartButtonClicked;
- @NonNull
- private TaskInfo mTaskInfo;
-
// Remember the last reported states in case visibility changes due to keyguard or IME updates.
@VisibleForTesting
boolean mHasSizeCompat;
@@ -77,7 +73,6 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
CompatUIHintsState compatUIHintsState, CompatUIConfiguration compatUIConfiguration,
Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> onRestartButtonClicked) {
super(context, taskInfo, syncQueue, taskListener, displayLayout);
- mTaskInfo = taskInfo;
mCallback = callback;
mHasSizeCompat = taskInfo.topActivityInSizeCompat;
mCameraCompatControlState = taskInfo.cameraCompatControlState;
@@ -129,7 +124,6 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
@Override
public boolean updateCompatInfo(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener,
boolean canShow) {
- mTaskInfo = taskInfo;
final boolean prevHasSizeCompat = mHasSizeCompat;
final int prevCameraCompatControlState = mCameraCompatControlState;
mHasSizeCompat = taskInfo.topActivityInSizeCompat;
@@ -149,7 +143,7 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
/** Called when the restart button is clicked. */
void onRestartButtonClicked() {
- mOnRestartButtonClicked.accept(Pair.create(mTaskInfo, getTaskListener()));
+ mOnRestartButtonClicked.accept(Pair.create(getLastTaskInfo(), getTaskListener()));
}
/** Called when the camera treatment button is clicked. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java
index 9c4e79cd631b..180498c50c78 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java
@@ -26,6 +26,7 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PROTECTED;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.TaskInfo;
import android.content.Context;
@@ -65,6 +66,9 @@ public abstract class CompatUIWindowManagerAbstract extends WindowlessWindowMana
private DisplayLayout mDisplayLayout;
private final Rect mStableBounds;
+ @NonNull
+ private TaskInfo mTaskInfo;
+
/**
* Utility class for adding and releasing a View hierarchy for this {@link
* WindowlessWindowManager} to {@code mLeash}.
@@ -83,6 +87,7 @@ public abstract class CompatUIWindowManagerAbstract extends WindowlessWindowMana
SyncTransactionQueue syncQueue, ShellTaskOrganizer.TaskListener taskListener,
DisplayLayout displayLayout) {
super(taskInfo.configuration, null /* rootSurface */, null /* hostInputToken */);
+ mTaskInfo = taskInfo;
mContext = context;
mSyncQueue = syncQueue;
mTaskConfig = taskInfo.configuration;
@@ -95,6 +100,17 @@ public abstract class CompatUIWindowManagerAbstract extends WindowlessWindowMana
}
/**
+ * @return {@code true} if the instance of the specific {@link CompatUIWindowManagerAbstract}
+ * for the current task id needs to be recreated loading the related resources. This happens
+ * if the user switches between Light/Dark mode, if the device is docked/undocked or if the
+ * user switches between multi-window mode to fullscreen where the
+ * {@link ShellTaskOrganizer.TaskListener} implementation is different.
+ */
+ boolean needsToBeRecreated(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener) {
+ return hasUiModeChanged(mTaskInfo, taskInfo) || hasTaskListenerChanged(taskListener);
+ }
+
+ /**
* Returns the z-order of this window which will be passed to the {@link SurfaceControl} once
* {@link #attachToParentSurface} is called.
*
@@ -195,6 +211,7 @@ public abstract class CompatUIWindowManagerAbstract extends WindowlessWindowMana
@VisibleForTesting(visibility = PROTECTED)
public boolean updateCompatInfo(TaskInfo taskInfo,
ShellTaskOrganizer.TaskListener taskListener, boolean canShow) {
+ mTaskInfo = taskInfo;
final Configuration prevTaskConfig = mTaskConfig;
final ShellTaskOrganizer.TaskListener prevTaskListener = mTaskListener;
mTaskConfig = taskInfo.configuration;
@@ -315,6 +332,11 @@ public abstract class CompatUIWindowManagerAbstract extends WindowlessWindowMana
updateSurfacePosition();
}
+ @Nullable
+ protected TaskInfo getLastTaskInfo() {
+ return mTaskInfo;
+ }
+
/**
* Called following a change in the task bounds, display layout stable bounds, or the layout
* direction.
@@ -402,4 +424,12 @@ public abstract class CompatUIWindowManagerAbstract extends WindowlessWindowMana
protected final String getTag() {
return getClass().getSimpleName();
}
+
+ protected boolean hasTaskListenerChanged(ShellTaskOrganizer.TaskListener newTaskListener) {
+ return !mTaskListener.equals(newTaskListener);
+ }
+
+ protected static boolean hasUiModeChanged(TaskInfo currentTaskInfo, TaskInfo newTaskInfo) {
+ return currentTaskInfo.configuration.uiMode != newTaskInfo.configuration.uiMode;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
index 959c50d5c640..9a67258ded2e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
@@ -19,7 +19,6 @@ package com.android.wm.shell.compatui;
import static android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING;
import static android.window.TaskConstants.TASK_CHILD_LAYER_COMPAT_UI;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.TaskInfo;
import android.content.Context;
@@ -69,9 +68,6 @@ class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
@VisibleForTesting
LetterboxEduDialogLayout mLayout;
- @NonNull
- private TaskInfo mTaskInfo;
-
/**
* The vertical margin between the dialog container and the task stable bounds (excluding
* insets).
@@ -99,7 +95,6 @@ class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
DialogAnimationController<LetterboxEduDialogLayout> animationController,
DockStateReader dockStateReader, CompatUIConfiguration compatUIConfiguration) {
super(context, taskInfo, syncQueue, taskListener, displayLayout);
- mTaskInfo = taskInfo;
mTransitions = transitions;
mOnDismissCallback = onDismissCallback;
mAnimationController = animationController;
@@ -197,7 +192,7 @@ class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
mLayout.setDismissOnClickListener(null);
mAnimationController.startExitAnimation(mLayout, () -> {
release();
- mOnDismissCallback.accept(Pair.create(mTaskInfo, getTaskListener()));
+ mOnDismissCallback.accept(Pair.create(getLastTaskInfo(), getTaskListener()));
});
}
@@ -210,7 +205,6 @@ class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
@Override
public boolean updateCompatInfo(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener,
boolean canShow) {
- mTaskInfo = taskInfo;
mEligibleForLetterboxEducation = taskInfo.topActivityEligibleForLetterboxEducation;
return super.updateCompatInfo(taskInfo, taskListener, canShow);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java
index a18ab9154e01..95bb1fe1c986 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java
@@ -20,7 +20,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.window.TaskConstants.TASK_CHILD_LAYER_COMPAT_UI;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.TaskInfo;
import android.content.Context;
@@ -52,9 +51,6 @@ class ReachabilityEduWindowManager extends CompatUIWindowManagerAbstract {
private final ShellExecutor mMainExecutor;
- @NonNull
- private TaskInfo mTaskInfo;
-
private boolean mIsActivityLetterboxed;
private int mLetterboxVerticalPosition;
@@ -86,7 +82,6 @@ class ReachabilityEduWindowManager extends CompatUIWindowManagerAbstract {
ShellTaskOrganizer.TaskListener taskListener, DisplayLayout displayLayout,
CompatUIConfiguration compatUIConfiguration, ShellExecutor mainExecutor) {
super(context, taskInfo, syncQueue, taskListener, displayLayout);
- mTaskInfo = taskInfo;
mIsActivityLetterboxed = taskInfo.isLetterboxDoubleTapEnabled;
mLetterboxVerticalPosition = taskInfo.topActivityLetterboxVerticalPosition;
mLetterboxHorizontalPosition = taskInfo.topActivityLetterboxHorizontalPosition;
@@ -136,7 +131,6 @@ class ReachabilityEduWindowManager extends CompatUIWindowManagerAbstract {
@Override
public boolean updateCompatInfo(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener,
boolean canShow) {
- mTaskInfo = taskInfo;
final boolean prevIsActivityLetterboxed = mIsActivityLetterboxed;
final int prevLetterboxVerticalPosition = mLetterboxVerticalPosition;
final int prevLetterboxHorizontalPosition = mLetterboxHorizontalPosition;
@@ -222,14 +216,14 @@ class ReachabilityEduWindowManager extends CompatUIWindowManagerAbstract {
if (mLayout == null) {
return;
}
-
+ final TaskInfo lastTaskInfo = getLastTaskInfo();
final boolean eligibleForDisplayHorizontalEducation = mForceUpdate
- || !mCompatUIConfiguration.hasSeenHorizontalReachabilityEducation(mTaskInfo)
+ || !mCompatUIConfiguration.hasSeenHorizontalReachabilityEducation(lastTaskInfo)
|| (mHasUserDoubleTapped
&& (mLetterboxHorizontalPosition == REACHABILITY_LEFT_OR_UP_POSITION
|| mLetterboxHorizontalPosition == REACHABILITY_RIGHT_OR_BOTTOM_POSITION));
final boolean eligibleForDisplayVerticalEducation = mForceUpdate
- || !mCompatUIConfiguration.hasSeenVerticalReachabilityEducation(mTaskInfo)
+ || !mCompatUIConfiguration.hasSeenVerticalReachabilityEducation(lastTaskInfo)
|| (mHasUserDoubleTapped
&& (mLetterboxVerticalPosition == REACHABILITY_LEFT_OR_UP_POSITION
|| mLetterboxVerticalPosition == REACHABILITY_RIGHT_OR_BOTTOM_POSITION));
@@ -241,7 +235,7 @@ class ReachabilityEduWindowManager extends CompatUIWindowManagerAbstract {
mLayout.handleVisibility(eligibleForDisplayHorizontalEducation,
eligibleForDisplayVerticalEducation,
mLetterboxVerticalPosition, mLetterboxHorizontalPosition, availableWidth,
- availableHeight, mCompatUIConfiguration, mTaskInfo);
+ availableHeight, mCompatUIConfiguration, lastTaskInfo);
if (!mHasLetterboxSizeChanged) {
updateHideTime();
mMainExecutor.executeDelayed(this::hideReachability, DISAPPEAR_DELAY_MS);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogWindowManager.java
index 51e5141a28af..a770da28fbd1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogWindowManager.java
@@ -19,7 +19,6 @@ package com.android.wm.shell.compatui;
import static android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING;
import static android.window.TaskConstants.TASK_CHILD_LAYER_COMPAT_UI;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.TaskInfo;
import android.content.Context;
@@ -67,9 +66,6 @@ class RestartDialogWindowManager extends CompatUIWindowManagerAbstract {
*/
private final int mDialogVerticalMargin;
- @NonNull
- private TaskInfo mTaskInfo;
-
@Nullable
@VisibleForTesting
RestartDialogLayout mLayout;
@@ -95,7 +91,6 @@ class RestartDialogWindowManager extends CompatUIWindowManagerAbstract {
DialogAnimationController<RestartDialogLayout> animationController,
CompatUIConfiguration compatUIConfiguration) {
super(context, taskInfo, syncQueue, taskListener, displayLayout);
- mTaskInfo = taskInfo;
mTransitions = transitions;
mOnDismissCallback = onDismissCallback;
mOnRestartCallback = onRestartCallback;
@@ -125,7 +120,7 @@ class RestartDialogWindowManager extends CompatUIWindowManagerAbstract {
protected boolean eligibleToShowLayout() {
// We don't show this dialog if the user has explicitly selected so clicking on a checkbox.
return mRequestRestartDialog && !isTaskbarEduShowing() && (mLayout != null
- || mCompatUIConfiguration.shouldShowRestartDialogAgain(mTaskInfo));
+ || mCompatUIConfiguration.shouldShowRestartDialogAgain(getLastTaskInfo()));
}
@Override
@@ -143,18 +138,6 @@ class RestartDialogWindowManager extends CompatUIWindowManagerAbstract {
mRequestRestartDialog = enabled;
}
- @Override
- public boolean updateCompatInfo(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener,
- boolean canShow) {
- mTaskInfo = taskInfo;
- return super.updateCompatInfo(taskInfo, taskListener, canShow);
- }
-
- boolean needsToBeRecreated(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener) {
- return taskInfo.configuration.uiMode != mTaskInfo.configuration.uiMode
- || !getTaskListener().equals(taskListener);
- }
-
private void updateDialogMargins() {
if (mLayout == null) {
return;
@@ -191,6 +174,7 @@ class RestartDialogWindowManager extends CompatUIWindowManagerAbstract {
// Dialog has already been released.
return;
}
+ final TaskInfo lastTaskInfo = getLastTaskInfo();
mLayout.setDismissOnClickListener(this::onDismiss);
mLayout.setRestartOnClickListener(dontShowAgain -> {
if (mLayout != null) {
@@ -200,9 +184,9 @@ class RestartDialogWindowManager extends CompatUIWindowManagerAbstract {
});
}
if (dontShowAgain) {
- mCompatUIConfiguration.setDontShowRestartDialogAgain(mTaskInfo);
+ mCompatUIConfiguration.setDontShowRestartDialogAgain(lastTaskInfo);
}
- mOnRestartCallback.accept(Pair.create(mTaskInfo, getTaskListener()));
+ mOnRestartCallback.accept(Pair.create(lastTaskInfo, getTaskListener()));
});
// Focus on the dialog title for accessibility.
mLayout.getDialogTitle().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
@@ -216,7 +200,7 @@ class RestartDialogWindowManager extends CompatUIWindowManagerAbstract {
mLayout.setDismissOnClickListener(null);
mAnimationController.startExitAnimation(mLayout, () -> {
release();
- mOnDismissCallback.accept(Pair.create(mTaskInfo, getTaskListener()));
+ mOnDismissCallback.accept(Pair.create(getLastTaskInfo(), getTaskListener()));
});
}
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 00cc57f0b99c..3ab175d3b68a 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
@@ -23,6 +23,8 @@ import android.util.SparseArray
import androidx.core.util.forEach
import androidx.core.util.keyIterator
import androidx.core.util.valueIterator
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+import com.android.wm.shell.util.KtProtoLog
import java.util.concurrent.Executor
import java.util.function.Consumer
@@ -140,6 +142,12 @@ class DesktopModeTaskRepository {
val added = displayData.getOrCreate(displayId).activeTasks.add(taskId)
if (added) {
+ KtProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTaskRepo: add active task=%d displayId=%d",
+ taskId,
+ displayId
+ )
activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) }
}
return added
@@ -158,6 +166,9 @@ class DesktopModeTaskRepository {
result = true
}
}
+ if (result) {
+ KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove active task=%d", taskId)
+ }
return result
}
@@ -221,6 +232,17 @@ class DesktopModeTaskRepository {
displayData[displayId]?.visibleTasks?.remove(taskId)
}
val newCount = getVisibleTaskCount(displayId)
+
+ if (prevCount != newCount) {
+ KtProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTaskRepo: update task visibility taskId=%d visible=%b displayId=%d",
+ taskId,
+ visible,
+ displayId
+ )
+ }
+
// Check if count changed and if there was no tasks or this is the first task
if (prevCount != newCount && (prevCount == 0 || newCount == 0)) {
notifyVisibleTaskListeners(displayId, newCount > 0)
@@ -244,6 +266,11 @@ class DesktopModeTaskRepository {
* Add (or move if it already exists) the task to the top of the ordered list.
*/
fun addOrMoveFreeformTaskToTop(taskId: Int) {
+ KtProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTaskRepo: add or move task to top taskId=%d",
+ taskId
+ )
if (freeformTasksInZOrder.contains(taskId)) {
freeformTasksInZOrder.remove(taskId)
}
@@ -254,6 +281,11 @@ class DesktopModeTaskRepository {
* Remove the task from the ordered list.
*/
fun removeFreeformTask(taskId: Int) {
+ KtProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTaskRepo: remove freeform task from ordered list taskId=%d",
+ taskId
+ )
freeformTasksInZOrder.remove(taskId)
}
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 b3109388da2c..91bb155d9d01 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
@@ -39,7 +39,6 @@ import android.window.TransitionRequestInfo
import android.window.WindowContainerToken
import android.window.WindowContainerTransaction
import androidx.annotation.BinderThread
-import com.android.internal.protolog.common.ProtoLog
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.common.DisplayController
@@ -56,6 +55,7 @@ import com.android.wm.shell.sysui.ShellController
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.sysui.ShellSharedConstants
import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.util.KtProtoLog
import java.util.concurrent.Executor
import java.util.function.Consumer
@@ -91,7 +91,7 @@ class DesktopTasksController(
}
private fun onInit() {
- ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
+ KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
shellController.addExternalInterface(
ShellSharedConstants.KEY_EXTRA_SHELL_DESKTOP_MODE,
{ createExternalInterface() },
@@ -102,7 +102,7 @@ class DesktopTasksController(
/** Show all tasks, that are part of the desktop, on top of launcher */
fun showDesktopApps(displayId: Int) {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps")
+ KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: showDesktopApps")
val wct = WindowContainerTransaction()
// TODO(b/278084491): pass in display id
bringDesktopAppsToFront(displayId, wct)
@@ -130,8 +130,11 @@ class DesktopTasksController(
/** Move a task to desktop */
fun moveToDesktop(task: RunningTaskInfo) {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToDesktop: %d", task.taskId)
-
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: moveToDesktop taskId=%d",
+ task.taskId
+ )
val wct = WindowContainerTransaction()
// Bring other apps to front first
bringDesktopAppsToFront(task.displayId, wct)
@@ -147,10 +150,12 @@ class DesktopTasksController(
* Moves a single task to freeform and sets the taskBounds to the passed in bounds,
* startBounds
*/
- fun moveToFreeform(
- taskInfo: RunningTaskInfo,
- startBounds: Rect
- ) {
+ fun moveToFreeform(taskInfo: RunningTaskInfo, startBounds: Rect) {
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: moveToFreeform with bounds taskId=%d",
+ taskInfo.taskId
+ )
val wct = WindowContainerTransaction()
moveHomeTaskToFront(wct)
addMoveToDesktopChanges(wct, taskInfo.getToken())
@@ -165,10 +170,12 @@ class DesktopTasksController(
}
/** Brings apps to front and sets freeform task bounds */
- private fun moveToDesktopWithAnimation(
- taskInfo: RunningTaskInfo,
- freeformBounds: Rect
- ) {
+ private fun moveToDesktopWithAnimation(taskInfo: RunningTaskInfo, freeformBounds: Rect) {
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: moveToDesktop with animation taskId=%d",
+ taskInfo.taskId
+ )
val wct = WindowContainerTransaction()
bringDesktopAppsToFront(taskInfo.displayId, wct)
addMoveToDesktopChanges(wct, taskInfo.getToken())
@@ -190,7 +197,11 @@ class DesktopTasksController(
/** Move a task to fullscreen */
fun moveToFullscreen(task: RunningTaskInfo) {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToFullscreen: %d", task.taskId)
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: moveToFullscreen taskId=%d",
+ task.taskId
+ )
val wct = WindowContainerTransaction()
addMoveToFullscreenChanges(wct, task.token)
@@ -206,6 +217,11 @@ class DesktopTasksController(
* status bar area
*/
fun cancelMoveToFreeform(task: RunningTaskInfo, position: Point) {
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: cancelMoveToFreeform taskId=%d",
+ task.taskId
+ )
val wct = WindowContainerTransaction()
addMoveToFullscreenChanges(wct, task.token)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
@@ -218,6 +234,11 @@ class DesktopTasksController(
}
private fun moveToFullscreenWithAnimation(task: RunningTaskInfo, position: Point) {
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: moveToFullscreen with animation taskId=%d",
+ task.taskId
+ )
val wct = WindowContainerTransaction()
addMoveToFullscreenChanges(wct, task.token)
@@ -230,8 +251,14 @@ class DesktopTasksController(
}
}
- /** Move a task to the front **/
+ /** Move a task to the front */
fun moveTaskToFront(taskInfo: RunningTaskInfo) {
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: moveTaskToFront taskId=%d",
+ taskInfo.taskId
+ )
+
val wct = WindowContainerTransaction()
wct.reorder(taskInfo.token, true)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
@@ -255,10 +282,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)
+ KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: taskId=%d not found", taskId)
return
}
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: taskId=%d taskDisplayId=%d",
+ KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: taskId=%d taskDisplayId=%d",
taskId, task.displayId)
val displayIds = rootTaskDisplayAreaOrganizer.displayIds.sorted()
@@ -269,7 +296,7 @@ class DesktopTasksController(
newDisplayId = displayIds.firstOrNull { displayId -> displayId < task.displayId }
}
if (newDisplayId == null) {
- ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: next display not found")
+ KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: next display not found")
return
}
moveToDisplay(task, newDisplayId)
@@ -281,17 +308,17 @@ 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",
+ KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToDisplay: taskId=%d displayId=%d",
task.taskId, displayId)
if (task.displayId == displayId) {
- ProtoLog.d(WM_SHELL_DESKTOP_MODE, "moveToDisplay: task already on display")
+ KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "moveToDisplay: task already on display")
return
}
val displayAreaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)
if (displayAreaInfo == null) {
- ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToDisplay: display not found")
+ KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToDisplay: display not found")
return
}
@@ -316,7 +343,7 @@ class DesktopTasksController(
}
private fun bringDesktopAppsToFront(displayId: Int, wct: WindowContainerTransaction) {
- ProtoLog.v(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront")
+ KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: bringDesktopAppsToFront")
val activeTasks = desktopModeTaskRepository.getActiveTasks(displayId)
// First move home to front and then other tasks on top of it
@@ -397,9 +424,9 @@ class DesktopTasksController(
if (task.windowingMode == WINDOWING_MODE_FULLSCREEN) {
// If there are any visible desktop tasks, switch the task to freeform
if (activeTasks.any { desktopModeTaskRepository.isVisibleTask(it) }) {
- ProtoLog.d(
+ KtProtoLog.d(
WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController#handleRequest: switch fullscreen task to freeform," +
+ "DesktopTasksController: switch fullscreen task to freeform on transition" +
" taskId=%d",
task.taskId
)
@@ -414,9 +441,9 @@ class DesktopTasksController(
// If no visible desktop tasks, switch this task to freeform as the transition came
// outside of this controller
if (activeTasks.none { desktopModeTaskRepository.isVisibleTask(it) }) {
- ProtoLog.d(
+ KtProtoLog.d(
WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController#handleRequest: switch freeform task to fullscreen," +
+ "DesktopTasksController: switch freeform task to fullscreen oon transition" +
" taskId=%d",
task.taskId
)
@@ -627,8 +654,6 @@ class DesktopTasksController(
}
}
-
-
/** The interface for calls from outside the host process. */
@BinderThread
private class IDesktopModeImpl(private var controller: DesktopTasksController?) :
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS
index ccbb9cf298a2..a3803ed82844 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS
@@ -1,3 +1,4 @@
# WM shell sub-module freeform owners
atsjenk@google.com
+jorgegil@google.com
madym@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
index 24d0b996a3cb..f51eb5299dd9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
@@ -180,6 +180,35 @@ public class PipBoundsAlgorithm {
return null;
}
+
+ /**
+ * Returns the source hint rect if it is valid (if provided and is contained by the current
+ * task bounds, while not smaller than the destination bounds).
+ */
+ @Nullable
+ public static Rect getValidSourceHintRect(PictureInPictureParams params, Rect sourceBounds,
+ Rect destinationBounds) {
+ Rect sourceRectHint = getValidSourceHintRect(params, sourceBounds);
+ if (!isSourceRectHintValidForEnterPip(sourceRectHint, destinationBounds)) {
+ sourceRectHint = null;
+ }
+ return sourceRectHint;
+ }
+
+ /**
+ * This is a situation in which the source rect hint on at least one axis is smaller
+ * than the destination bounds, which represents a problem because we would have to scale
+ * up that axis to fit the bounds. So instead, just fallback to the non-source hint
+ * animation in this case.
+ *
+ * @return {@code false} if the given source is too small to use for the entering animation.
+ */
+ static boolean isSourceRectHintValidForEnterPip(Rect sourceRectHint, Rect destinationBounds) {
+ return sourceRectHint != null
+ && sourceRectHint.width() > destinationBounds.width()
+ && sourceRectHint.height() > destinationBounds.height();
+ }
+
public float getDefaultAspectRatio() {
return mDefaultAspectRatio;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 6cedcf534f3b..363d6759f8d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -1657,8 +1657,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
"%s: Abort animation, invalid leash", TAG);
return null;
}
- if (isInPipDirection(direction)
- && !isSourceRectHintValidForEnterPip(sourceHintRect, destinationBounds)) {
+ if (isInPipDirection(direction) && !PipBoundsAlgorithm
+ .isSourceRectHintValidForEnterPip(sourceHintRect, destinationBounds)) {
// The given source rect hint is too small for enter PiP animation, reset it to null.
sourceHintRect = null;
}
@@ -1757,20 +1757,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
}
/**
- * This is a situation in which the source rect hint on at least one axis is smaller
- * than the destination bounds, which represents a problem because we would have to scale
- * up that axis to fit the bounds. So instead, just fallback to the non-source hint
- * animation in this case.
- *
- * @return {@code false} if the given source is too small to use for the entering animation.
- */
- private boolean isSourceRectHintValidForEnterPip(Rect sourceRectHint, Rect destinationBounds) {
- return sourceRectHint != null
- && sourceRectHint.width() > destinationBounds.width()
- && sourceRectHint.height() > destinationBounds.height();
- }
-
- /**
* Sync with {@link SplitScreenController} on destination bounds if PiP is going to
* split screen.
*
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 98db707d1105..046d6fce443b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -470,6 +470,7 @@ public class PipTransition extends PipTransitionController {
@NonNull Transitions.TransitionFinishCallback finishCallback,
@NonNull TaskInfo taskInfo, @Nullable TransitionInfo.Change pipTaskChange) {
TransitionInfo.Change pipChange = pipTaskChange;
+ SurfaceControl activitySc = null;
if (mCurrentPipTaskToken == null) {
ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: There is no existing PiP Task for TRANSIT_EXIT_PIP", TAG);
@@ -482,6 +483,7 @@ public class PipTransition extends PipTransitionController {
if (mCurrentPipTaskToken.equals(change.getLastParent())) {
// Find the activity that is exiting PiP.
pipChange = change;
+ activitySc = change.getLeash();
break;
}
}
@@ -498,17 +500,36 @@ public class PipTransition extends PipTransitionController {
// case it may not be in the screen coordinate.
// Reparent the pip leash to the root with max layer so that we can animate it outside of
// parent crop, and make sure it is not covered by other windows.
- final SurfaceControl pipLeash = pipChange.getLeash();
- final int rootIdx = TransitionUtil.rootIndexFor(pipChange, info);
- startTransaction.reparent(pipLeash, info.getRoot(rootIdx).getLeash());
+ final TransitionInfo.Root root = TransitionUtil.getRootFor(pipChange, info);
+ final SurfaceControl pipLeash;
+ if (activitySc != null) {
+ // Use a local leash to animate activity in case the activity has letterbox which may
+ // be broken by PiP animation, e.g. always end at 0,0 in parent and unable to include
+ // letterbox area in crop bounds.
+ final SurfaceControl activitySurface = pipChange.getLeash();
+ pipLeash = new SurfaceControl.Builder()
+ .setName(activitySc + "_pip-leash")
+ .setContainerLayer()
+ .setHidden(false)
+ .setParent(root.getLeash())
+ .build();
+ startTransaction.reparent(activitySurface, pipLeash);
+ // Put the activity at local position with offset in case it is letterboxed.
+ final Point activityOffset = pipChange.getEndRelOffset();
+ startTransaction.setPosition(activitySc, activityOffset.x, activityOffset.y);
+ } else {
+ pipLeash = pipChange.getLeash();
+ startTransaction.reparent(pipLeash, root.getLeash());
+ }
startTransaction.setLayer(pipLeash, Integer.MAX_VALUE);
// Note: because of this, the bounds to animate should be translated to the root coordinate.
- final Point offset = info.getRoot(rootIdx).getOffset();
+ final Point offset = root.getOffset();
final Rect currentBounds = mPipBoundsState.getBounds();
currentBounds.offset(-offset.x, -offset.y);
startTransaction.setPosition(pipLeash, currentBounds.left, currentBounds.top);
final WindowContainerToken pipTaskToken = pipChange.getContainer();
+ final boolean useLocalLeash = activitySc != null;
final boolean toFullscreen = pipChange.getEndAbsBounds().equals(
mPipBoundsState.getDisplayBounds());
mFinishCallback = (wct, wctCB) -> {
@@ -518,6 +539,14 @@ public class PipTransition extends PipTransitionController {
wct.setBounds(pipTaskToken, null);
mPipOrganizer.applyWindowingModeChangeOnExit(wct, TRANSITION_DIRECTION_LEAVE_PIP);
}
+ if (useLocalLeash) {
+ if (mPipAnimationController.isAnimating()) {
+ mPipAnimationController.getCurrentAnimator().end();
+ }
+ // Make sure the animator don't use the released leash, e.g. mergeAnimation.
+ mPipAnimationController.resetAnimatorState();
+ finishTransaction.remove(pipLeash);
+ }
finishCallback.onTransitionFinished(wct, wctCB);
};
mFinishTransaction = finishTransaction;
@@ -545,7 +574,8 @@ public class PipTransition extends PipTransitionController {
// Set the initial frame as scaling the end to the start.
final Rect destinationBounds = new Rect(pipChange.getEndAbsBounds());
destinationBounds.offset(-offset.x, -offset.y);
- startTransaction.setWindowCrop(pipLeash, destinationBounds);
+ startTransaction.setWindowCrop(pipLeash, destinationBounds.width(),
+ destinationBounds.height());
mSurfaceTransactionHelper.scale(startTransaction, pipLeash, destinationBounds,
currentBounds);
startTransaction.apply();
@@ -764,7 +794,7 @@ public class PipTransition extends PipTransitionController {
final Rect currentBounds = taskInfo.configuration.windowConfiguration.getBounds();
int rotationDelta = deltaRotation(startRotation, endRotation);
Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect(
- taskInfo.pictureInPictureParams, currentBounds);
+ taskInfo.pictureInPictureParams, currentBounds, destinationBounds);
if (rotationDelta != Surface.ROTATION_0 && mInFixedRotation) {
// Need to get the bounds of new rotation in old rotation for fixed rotation,
computeEnterPipRotatedBounds(rotationDelta, startRotation, endRotation, taskInfo,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index af52350f5b48..c654c1b0d431 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -337,6 +337,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return isTaskInSplitScreen(taskId) && isSplitScreenVisible();
}
+ /** Check whether the task is the single-top root or the root of one of the stages. */
+ public boolean isTaskRootOrStageRoot(int taskId) {
+ return mStageCoordinator.isRootOrStageRoot(taskId);
+ }
+
public @SplitPosition int getSplitPosition(int taskId) {
return mStageCoordinator.getSplitPosition(taskId);
}
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 5c2f1438c08e..749549d1ca55 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
@@ -377,6 +377,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return STAGE_TYPE_UNDEFINED;
}
+ boolean isRootOrStageRoot(int taskId) {
+ if (mRootTaskInfo != null && mRootTaskInfo.taskId == taskId) {
+ return true;
+ }
+ return mMainStage.isRootTaskId(taskId) || mSideStage.isRootTaskId(taskId);
+ }
+
boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition,
WindowContainerTransaction wct) {
prepareEnterSplitScreen(wct, task, stagePosition);
@@ -1538,7 +1545,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
void finishEnterSplitScreen(SurfaceControl.Transaction t) {
- mSplitLayout.init();
+ mSplitLayout.update(t);
setDividerVisibility(true, t);
// Ensure divider surface are re-parented back into the hierarchy at the end of the
// transition. See Transition#buildFinishTransaction for more detail.
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 18b09b090794..e2e9270cd6cc 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
@@ -286,6 +286,10 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
}
}
+ boolean isRootTaskId(int taskId) {
+ return mRootTaskInfo != null && mRootTaskInfo.taskId == taskId;
+ }
+
void onResizing(Rect newBounds, Rect sideBounds, SurfaceControl.Transaction t, int offsetX,
int offsetY, boolean immediately) {
if (mSplitDecorManager != null && mRootTaskInfo != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index 94190c74f3e9..d27933e2f800 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -453,7 +453,7 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
return;
}
- finishTransaction.reparent(mTaskLeash, null).apply();
+ finishTransaction.reparent(mTaskLeash, null);
if (mListener != null) {
final int taskId = mTaskInfo.taskId;
@@ -490,13 +490,11 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
if (mSurfaceCreated) {
// Surface is ready, so just reparent the task to this surface control
startTransaction.reparent(mTaskLeash, mSurfaceControl)
- .show(mTaskLeash)
- .apply();
+ .show(mTaskLeash);
// Also reparent on finishTransaction since the finishTransaction will reparent back
// to its "original" parent by default.
finishTransaction.reparent(mTaskLeash, mSurfaceControl)
- .setPosition(mTaskLeash, 0, 0)
- .apply();
+ .setPosition(mTaskLeash, 0, 0);
mTaskViewTransitions.updateBoundsState(this, mTaskViewBase.getCurrentBoundsOnScreen());
mTaskViewTransitions.updateVisibilityState(this, true /* visible */);
wct.setBounds(mTaskToken, mTaskViewBase.getCurrentBoundsOnScreen());
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 689f9e1a3eda..fe2faaf79a1a 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
@@ -363,7 +363,8 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
continue;
}
startTransaction.reparent(chg.getLeash(), tv.getSurfaceControl());
- finishTransaction.reparent(chg.getLeash(), tv.getSurfaceControl());
+ finishTransaction.reparent(chg.getLeash(), tv.getSurfaceControl())
+ .setPosition(chg.getLeash(), 0, 0);
changesHandled++;
}
}
@@ -377,7 +378,6 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
}
// No animation, just show it immediately.
startTransaction.apply();
- finishTransaction.apply();
finishCallback.onTransitionFinished(wct, null /* wctCB */);
startNextTransition();
return true;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 1ee52ae00645..21dca95d056a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -24,6 +24,7 @@ import static android.app.ActivityOptions.ANIM_SCALE_UP;
import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE;
@@ -36,12 +37,8 @@ import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_CHANGE;
-import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
-import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_RELAUNCH;
-import static android.view.WindowManager.TRANSIT_TO_BACK;
-import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_OWNER_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_WORK_THUMBNAIL;
@@ -92,7 +89,6 @@ import android.view.Choreographer;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.WindowManager;
-import android.view.WindowManager.TransitionType;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Transformation;
@@ -329,6 +325,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
@ColorInt int backgroundColorForTransition = 0;
final int wallpaperTransit = getWallpaperTransitType(info);
boolean isDisplayRotationAnimationStarted = false;
+ final boolean isDreamTransition = isDreamTransition(info);
+
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
if (change.hasAllFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY
@@ -343,9 +341,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
continue;
}
final boolean isTask = change.getTaskInfo() != null;
+ final int mode = change.getMode();
boolean isSeamlessDisplayChange = false;
- if (change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
+ if (mode == TRANSIT_CHANGE && change.hasFlags(FLAG_IS_DISPLAY)) {
if (info.getType() == TRANSIT_CHANGE) {
final int anim = getRotationAnimationHint(change, info, mDisplayController);
isSeamlessDisplayChange = anim == ROTATION_ANIMATION_SEAMLESS;
@@ -361,7 +360,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
}
- if (change.getMode() == TRANSIT_CHANGE) {
+ if (mode == TRANSIT_CHANGE) {
// If task is child task, only set position in parent and update crop when needed.
if (isTask && change.getParent() != null
&& info.getChange(change.getParent()).getTaskInfo() != null) {
@@ -410,8 +409,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// Hide the invisible surface directly without animating it if there is a display
// rotation animation playing.
- if (isDisplayRotationAnimationStarted && TransitionUtil.isClosingType(
- change.getMode())) {
+ if (isDisplayRotationAnimationStarted && TransitionUtil.isClosingType(mode)) {
startTransaction.hide(change.getLeash());
continue;
}
@@ -424,16 +422,12 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// Don't animate anything that isn't independent.
if (!TransitionInfo.isIndependent(change, info)) continue;
- Animation a = loadAnimation(info, change, wallpaperTransit);
+ Animation a = loadAnimation(info, change, wallpaperTransit, isDreamTransition);
if (a != null) {
if (isTask) {
- final @TransitionType int type = info.getType();
- final boolean isOpenOrCloseTransition = type == TRANSIT_OPEN
- || type == TRANSIT_CLOSE
- || type == TRANSIT_TO_FRONT
- || type == TRANSIT_TO_BACK;
final boolean isTranslucent = (change.getFlags() & FLAG_TRANSLUCENT) != 0;
- if (isOpenOrCloseTransition && !isTranslucent
+ if (!isTranslucent && TransitionUtil.isOpenOrCloseMode(mode)
+ && TransitionUtil.isOpenOrCloseMode(info.getType())
&& wallpaperTransit == WALLPAPER_TRANSITION_NONE) {
// Use the overview background as the background for the animation
final Context uiContext = ActivityThread.currentActivityThread()
@@ -458,7 +452,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
backgroundColorForTransition);
if (!isTask && a.hasExtension()) {
- if (!TransitionUtil.isOpeningType(change.getMode())) {
+ if (!TransitionUtil.isOpeningType(mode)) {
// Can screenshot now (before startTransaction is applied)
edgeExtendWindow(change, a, startTransaction, finishTransaction);
} else {
@@ -469,7 +463,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
}
- final Rect clipRect = TransitionUtil.isClosingType(change.getMode())
+ final Rect clipRect = TransitionUtil.isClosingType(mode)
? new Rect(mRotator.getEndBoundsInStartRotation(change))
: new Rect(change.getEndAbsBounds());
clipRect.offsetTo(0, 0);
@@ -519,6 +513,18 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
return true;
}
+ private static boolean isDreamTransition(@NonNull TransitionInfo info) {
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if (change.getTaskInfo() != null
+ && change.getTaskInfo().topActivityType == ACTIVITY_TYPE_DREAM) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@@ -572,7 +578,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
@Nullable
private Animation loadAnimation(@NonNull TransitionInfo info,
- @NonNull TransitionInfo.Change change, int wallpaperTransit) {
+ @NonNull TransitionInfo.Change change, int wallpaperTransit,
+ boolean isDreamTransition) {
Animation a;
final int type = info.getType();
@@ -630,7 +637,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// If there's a scene-transition, then jump-cut.
return null;
} else {
- a = loadAttributeAnimation(info, change, wallpaperTransit, mTransitionAnimation);
+ a = loadAttributeAnimation(
+ info, change, wallpaperTransit, mTransitionAnimation, isDreamTransition);
}
if (a != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Tracer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Tracer.java
index 0cede902f034..e27e4f990407 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Tracer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Tracer.java
@@ -28,7 +28,6 @@ import android.os.Trace;
import android.util.Log;
import com.android.internal.util.TraceBuffer;
-import com.android.wm.shell.nano.HandlerMapping;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.google.protobuf.nano.MessageNano;
@@ -41,6 +40,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
+import java.util.concurrent.TimeUnit;
/**
* Helper class to collect and dump transition traces.
@@ -241,6 +241,10 @@ public class Tracer implements ShellCommandHandler.ShellCommandActionHandler {
new com.android.wm.shell.nano.WmShellTransitionTraceProto();
proto.magicNumber = MAGIC_NUMBER_VALUE;
writeHandlerMappingToProto(proto);
+ long timeOffsetNs =
+ TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis())
+ - SystemClock.elapsedRealtimeNanos();
+ proto.realToElapsedTimeOffsetNanos = timeOffsetNs;
int pid = android.os.Process.myPid();
LogAndPrintln.i(pw, "Writing file to " + file.getAbsolutePath()
+ " from process " + pid);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index 0f4645c0fdab..19d8384ace41 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -18,7 +18,6 @@ package com.android.wm.shell.transition;
import static android.app.ActivityOptions.ANIM_FROM_STYLE;
import static android.app.ActivityOptions.ANIM_NONE;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
@@ -63,7 +62,7 @@ public class TransitionAnimationHelper {
@Nullable
public static Animation loadAttributeAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, int wallpaperTransit,
- @NonNull TransitionAnimation transitionAnimation) {
+ @NonNull TransitionAnimation transitionAnimation, boolean isDreamTransition) {
final int type = info.getType();
final int changeMode = change.getMode();
final int changeFlags = change.getFlags();
@@ -71,11 +70,9 @@ public class TransitionAnimationHelper {
final boolean isTask = change.getTaskInfo() != null;
final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
final int overrideType = options != null ? options.getType() : ANIM_NONE;
- final boolean isDream =
- isTask && change.getTaskInfo().topActivityType == ACTIVITY_TYPE_DREAM;
int animAttr = 0;
boolean translucent = false;
- if (isDream) {
+ if (isDreamTransition) {
if (type == TRANSIT_OPEN) {
animAttr = enter
? R.styleable.WindowAnimation_dreamActivityOpenEnterAnimation
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 fda943d7dc02..ab27c55f20dc 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
@@ -501,7 +501,9 @@ public class Transitions implements RemoteCallable<Transitions>,
*/
private static void setupAnimHierarchy(@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) {
- boolean isOpening = isOpeningType(info.getType());
+ final int type = info.getType();
+ final boolean isOpening = isOpeningType(type);
+ final boolean isClosing = isClosingType(type);
for (int i = 0; i < info.getRootCount(); ++i) {
t.show(info.getRoot(i).getLeash());
}
@@ -554,7 +556,13 @@ public class Transitions implements RemoteCallable<Transitions>,
layer = zSplitLine + numChanges - i;
}
} else { // CHANGE or other
- layer = zSplitLine + numChanges - i;
+ if (isClosing) {
+ // Put below CLOSE mode.
+ layer = zSplitLine - i;
+ } else {
+ // Put above CLOSE mode.
+ layer = zSplitLine + numChanges - i;
+ }
}
t.setLayer(leash, layer);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt
new file mode 100644
index 000000000000..9b48a542720c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 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.util
+
+import android.util.Log
+import com.android.internal.protolog.common.IProtoLogGroup
+import com.android.wm.shell.protolog.ShellProtoLogImpl
+
+/**
+ * Log messages using an API similar to [com.android.internal.protolog.common.ProtoLog]. Useful for
+ * logging from Kotlin classes as ProtoLog does not have support for Kotlin.
+ *
+ * All messages are logged to logcat if logging is enabled for that [IProtoLogGroup].
+ */
+// TODO(b/168581922): remove once ProtoLog adds support for Kotlin
+class KtProtoLog {
+ companion object {
+ /** @see [com.android.internal.protolog.common.ProtoLog.d] */
+ fun d(group: IProtoLogGroup, messageString: String, vararg args: Any) {
+ if (ShellProtoLogImpl.isEnabled(group)) {
+ Log.d(group.tag, String.format(messageString, *args))
+ }
+ }
+
+ /** @see [com.android.internal.protolog.common.ProtoLog.v] */
+ fun v(group: IProtoLogGroup, messageString: String, vararg args: Any) {
+ if (ShellProtoLogImpl.isEnabled(group)) {
+ Log.v(group.tag, String.format(messageString, *args))
+ }
+ }
+
+ /** @see [com.android.internal.protolog.common.ProtoLog.i] */
+ fun i(group: IProtoLogGroup, messageString: String, vararg args: Any) {
+ if (ShellProtoLogImpl.isEnabled(group)) {
+ Log.i(group.tag, String.format(messageString, *args))
+ }
+ }
+
+ /** @see [com.android.internal.protolog.common.ProtoLog.w] */
+ fun w(group: IProtoLogGroup, messageString: String, vararg args: Any) {
+ if (ShellProtoLogImpl.isEnabled(group)) {
+ Log.w(group.tag, String.format(messageString, *args))
+ }
+ }
+
+ /** @see [com.android.internal.protolog.common.ProtoLog.e] */
+ fun e(group: IProtoLogGroup, messageString: String, vararg args: Any) {
+ if (ShellProtoLogImpl.isEnabled(group)) {
+ Log.e(group.tag, String.format(messageString, *args))
+ }
+ }
+
+ /** @see [com.android.internal.protolog.common.ProtoLog.wtf] */
+ fun wtf(group: IProtoLogGroup, messageString: String, vararg args: Any) {
+ if (ShellProtoLogImpl.isEnabled(group)) {
+ Log.wtf(group.tag, String.format(messageString, *args))
+ }
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
index 7d05c0e62e13..402b0ce7c87c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
@@ -68,6 +68,12 @@ public class TransitionUtil {
return type == TRANSIT_CLOSE || type == TRANSIT_TO_BACK;
}
+ /** Returns {@code true} if the transition is opening or closing mode. */
+ public static boolean isOpenOrCloseMode(@TransitionInfo.TransitionMode int mode) {
+ return mode == TRANSIT_OPEN || mode == TRANSIT_CLOSE
+ || mode == TRANSIT_TO_FRONT || mode == TRANSIT_TO_BACK;
+ }
+
/** Returns {@code true} if the transition has a display change. */
public static boolean hasDisplayChange(@NonNull TransitionInfo info) {
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
@@ -311,7 +317,7 @@ public class TransitionUtil {
private static RemoteAnimationTarget getDividerTarget(TransitionInfo.Change change,
SurfaceControl leash) {
- return new RemoteAnimationTarget(-1 /* taskId */, -1 /* mode */,
+ return new RemoteAnimationTarget(-1 /* taskId */, newModeToLegacyMode(change.getMode()),
leash, false /* isTranslucent */, null /* clipRect */,
null /* contentInsets */, Integer.MAX_VALUE /* prefixOrderIndex */,
new android.graphics.Point(0, 0) /* position */, change.getStartAbsBounds(),
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 2bb3cceb257f..39fb7936747e 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
@@ -22,7 +22,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
-import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.util.SparseArray;
@@ -186,8 +185,9 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
mSyncQueue);
mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
- final DragPositioningCallback dragPositioningCallback = createDragPositioningCallback(
- windowDecoration, taskInfo);
+ final DragPositioningCallback dragPositioningCallback =
+ new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController,
+ null /* disallowedAreaForEndBounds */);
final CaptionTouchEventListener touchEventListener =
new CaptionTouchEventListener(taskInfo, dragPositioningCallback);
windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
@@ -198,17 +198,6 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
setupCaptionColor(taskInfo, windowDecoration);
}
- private FluidResizeTaskPositioner createDragPositioningCallback(
- CaptionWindowDecoration windowDecoration, RunningTaskInfo taskInfo) {
- final int screenWidth = mDisplayController.getDisplayLayout(taskInfo.displayId).width();
- final int statusBarHeight = mDisplayController.getDisplayLayout(taskInfo.displayId)
- .stableInsets().top;
- final Rect disallowedAreaForEndBounds = new Rect(0, 0, screenWidth,
- statusBarHeight);
- return new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration,
- mDisplayController, disallowedAreaForEndBounds);
- }
-
private class CaptionTouchEventListener implements
View.OnClickListener, View.OnTouchListener, DragDetector.MotionEventHandler {
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 0b821844e46c..54babce13205 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
@@ -760,6 +760,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) return true;
+ if (mSplitScreenController.isPresent()
+ && mSplitScreenController.get().isTaskRootOrStageRoot(taskInfo.taskId)) {
+ return false;
+ }
return DesktopModeStatus.isProto2Enabled()
&& taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD
&& mDisplayController.getDisplayContext(taskInfo.displayId)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
index 9bcb77f03abd..9f79d212a7b9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
@@ -21,6 +21,8 @@ import android.graphics.Rect;
import android.view.SurfaceControl;
import android.window.WindowContainerTransaction;
+import androidx.annotation.Nullable;
+
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -42,24 +44,24 @@ class FluidResizeTaskPositioner implements DragPositioningCallback {
private final Rect mRepositionTaskBounds = new Rect();
// If a task move (not resize) finishes in this region, the positioner will not attempt to
// finalize the bounds there using WCT#setBounds
- private final Rect mDisallowedAreaForEndBounds = new Rect();
+ private final Rect mDisallowedAreaForEndBounds;
private boolean mHasDragResized;
private int mCtrlType;
FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
- DisplayController displayController, Rect disallowedAreaForEndBounds) {
+ DisplayController displayController, @Nullable Rect disallowedAreaForEndBounds) {
this(taskOrganizer, windowDecoration, displayController, disallowedAreaForEndBounds,
dragStartListener -> {}, SurfaceControl.Transaction::new);
}
FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
- DisplayController displayController, Rect disallowedAreaForEndBounds,
+ DisplayController displayController, @Nullable Rect disallowedAreaForEndBounds,
DragPositioningCallbackUtility.DragStartListener dragStartListener,
Supplier<SurfaceControl.Transaction> supplier) {
mTaskOrganizer = taskOrganizer;
mWindowDecoration = windowDecoration;
mDisplayController = displayController;
- mDisallowedAreaForEndBounds.set(disallowedAreaForEndBounds);
+ mDisallowedAreaForEndBounds = new Rect(disallowedAreaForEndBounds);
mDragStartListener = dragStartListener;
mTransactionSupplier = supplier;
}
diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS
index 64dfc3ef845d..deebad545c5e 100644
--- a/libs/WindowManager/Shell/tests/OWNERS
+++ b/libs/WindowManager/Shell/tests/OWNERS
@@ -8,3 +8,4 @@ madym@google.com
hwwang@google.com
chenghsiuchang@google.com
atsjenk@google.com
+jorgegil@google.com
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 4de529885565..55781f1b4d6f 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
@@ -37,6 +37,7 @@ import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
import android.app.TaskInfo;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import android.util.Pair;
@@ -455,12 +456,21 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
verify(mLayout).setCameraCompatHintVisibility(/* show= */ true);
}
+ @Test
+ public void testWhenDockedStateHasChanged_needsToBeRecreated() {
+ ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
+ newTaskInfo.configuration.uiMode |= Configuration.UI_MODE_TYPE_DESK;
+
+ Assert.assertTrue(mWindowManager.needsToBeRecreated(newTaskInfo, mTaskListener));
+ }
+
private static TaskInfo createTaskInfo(boolean hasSizeCompat,
@TaskInfo.CameraCompatControlState int cameraCompatControlState) {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = TASK_ID;
taskInfo.topActivityInSizeCompat = hasSizeCompat;
taskInfo.cameraCompatControlState = cameraCompatControlState;
+ taskInfo.configuration.uiMode &= ~Configuration.UI_MODE_TYPE_DESK;
return taskInfo;
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
index 5bcc72e73cb9..973a99c269ea 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertNull;
import android.app.ActivityManager;
import android.app.TaskInfo;
+import android.content.res.Configuration;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
@@ -31,6 +32,8 @@ import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
+import junit.framework.Assert;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -46,63 +49,61 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidTestingRunner.class)
@SmallTest
public class ReachabilityEduWindowManagerTest extends ShellTestCase {
-
- private static final int USER_ID = 1;
- private static final int TASK_ID = 1;
-
@Mock
private SyncTransactionQueue mSyncTransactionQueue;
@Mock
private ShellTaskOrganizer.TaskListener mTaskListener;
@Mock
- private CompatUIController.CompatUICallback mCallback;
- @Mock
private CompatUIConfiguration mCompatUIConfiguration;
@Mock
private DisplayLayout mDisplayLayout;
-
private TestShellExecutor mExecutor;
+ private TaskInfo mTaskInfo;
+ private ReachabilityEduWindowManager mWindowManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mExecutor = new TestShellExecutor();
+ mTaskInfo = new ActivityManager.RunningTaskInfo();
+ mTaskInfo.configuration.uiMode =
+ (mTaskInfo.configuration.uiMode & ~Configuration.UI_MODE_NIGHT_MASK)
+ | Configuration.UI_MODE_NIGHT_NO;
+ mTaskInfo.configuration.uiMode =
+ (mTaskInfo.configuration.uiMode & ~Configuration.UI_MODE_TYPE_MASK)
+ | Configuration.UI_MODE_TYPE_NORMAL;
+ mWindowManager = createReachabilityEduWindowManager(mTaskInfo);
}
@Test
public void testCreateLayout_notEligible_doesNotCreateLayout() {
- final ReachabilityEduWindowManager windowManager = createReachabilityEduWindowManager(
- createTaskInfo(/* userId= */ USER_ID, /*isLetterboxDoubleTapEnabled */ false));
-
- assertFalse(windowManager.createLayout(/* canShow= */ true));
+ assertFalse(mWindowManager.createLayout(/* canShow= */ true));
- assertNull(windowManager.mLayout);
+ assertNull(mWindowManager.mLayout);
}
- private ReachabilityEduWindowManager createReachabilityEduWindowManager(TaskInfo taskInfo) {
- return new ReachabilityEduWindowManager(mContext, taskInfo, mSyncTransactionQueue,
- mTaskListener, mDisplayLayout, mCompatUIConfiguration, mExecutor);
+ @Test
+ public void testWhenDockedStateHasChanged_needsToBeRecreated() {
+ ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
+ newTaskInfo.configuration.uiMode =
+ (newTaskInfo.configuration.uiMode & ~Configuration.UI_MODE_TYPE_MASK)
+ | Configuration.UI_MODE_TYPE_DESK;
+
+ Assert.assertTrue(mWindowManager.needsToBeRecreated(newTaskInfo, mTaskListener));
}
- private static TaskInfo createTaskInfo(int userId, boolean isLetterboxDoubleTapEnabled) {
- return createTaskInfo(userId, /* isLetterboxDoubleTapEnabled */ isLetterboxDoubleTapEnabled,
- /* topActivityLetterboxVerticalPosition */ -1,
- /* topActivityLetterboxHorizontalPosition */ -1,
- /* topActivityLetterboxWidth */ -1,
- /* topActivityLetterboxHeight */ -1);
+ @Test
+ public void testWhenDarkLightThemeHasChanged_needsToBeRecreated() {
+ ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
+ mTaskInfo.configuration.uiMode =
+ (mTaskInfo.configuration.uiMode & ~Configuration.UI_MODE_NIGHT_MASK)
+ | Configuration.UI_MODE_NIGHT_YES;
+
+ Assert.assertTrue(mWindowManager.needsToBeRecreated(newTaskInfo, mTaskListener));
}
- private static TaskInfo createTaskInfo(int userId, boolean isLetterboxDoubleTapEnabled,
- int topActivityLetterboxVerticalPosition, int topActivityLetterboxHorizontalPosition,
- int topActivityLetterboxWidth, int topActivityLetterboxHeight) {
- ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
- taskInfo.userId = userId;
- taskInfo.taskId = TASK_ID;
- taskInfo.isLetterboxDoubleTapEnabled = isLetterboxDoubleTapEnabled;
- taskInfo.topActivityLetterboxVerticalPosition = topActivityLetterboxVerticalPosition;
- taskInfo.topActivityLetterboxHorizontalPosition = topActivityLetterboxHorizontalPosition;
- taskInfo.topActivityLetterboxWidth = topActivityLetterboxWidth;
- taskInfo.topActivityLetterboxHeight = topActivityLetterboxHeight;
- return taskInfo;
+ private ReachabilityEduWindowManager createReachabilityEduWindowManager(TaskInfo taskInfo) {
+ return new ReachabilityEduWindowManager(mContext, taskInfo, mSyncTransactionQueue,
+ mTaskListener, mDisplayLayout, mCompatUIConfiguration, mExecutor);
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java
new file mode 100644
index 000000000000..9f109a1d0f50
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 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.compatui;
+
+import android.app.ActivityManager;
+import android.app.TaskInfo;
+import android.content.res.Configuration;
+import android.testing.AndroidTestingRunner;
+import android.util.Pair;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.transition.Transitions;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.function.Consumer;
+
+/**
+ * Tests for {@link RestartDialogWindowManager}.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:RestartDialogWindowManagerTest
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class RestartDialogWindowManagerTest extends ShellTestCase {
+
+ @Mock
+ private SyncTransactionQueue mSyncTransactionQueue;
+ @Mock private ShellTaskOrganizer.TaskListener mTaskListener;
+ @Mock private CompatUIConfiguration mCompatUIConfiguration;
+ @Mock private Transitions mTransitions;
+ @Mock private Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnRestartCallback;
+ @Mock private Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnDismissCallback;
+ private RestartDialogWindowManager mWindowManager;
+ private TaskInfo mTaskInfo;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mTaskInfo = new ActivityManager.RunningTaskInfo();
+ mTaskInfo.configuration.uiMode =
+ (mTaskInfo.configuration.uiMode & ~Configuration.UI_MODE_NIGHT_MASK)
+ | Configuration.UI_MODE_NIGHT_NO;
+ mTaskInfo.configuration.uiMode =
+ (mTaskInfo.configuration.uiMode & ~Configuration.UI_MODE_TYPE_MASK)
+ | Configuration.UI_MODE_TYPE_NORMAL;
+ mWindowManager = new RestartDialogWindowManager(mContext, mTaskInfo, mSyncTransactionQueue,
+ mTaskListener, new DisplayLayout(), mTransitions, mOnRestartCallback,
+ mOnDismissCallback, mCompatUIConfiguration);
+ }
+
+ @Test
+ public void testWhenDockedStateHasChanged_needsToBeRecreated() {
+ ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
+ newTaskInfo.configuration.uiMode =
+ (newTaskInfo.configuration.uiMode & ~Configuration.UI_MODE_TYPE_MASK)
+ | Configuration.UI_MODE_TYPE_DESK;
+
+ Assert.assertTrue(mWindowManager.needsToBeRecreated(newTaskInfo, mTaskListener));
+ }
+
+ @Test
+ public void testWhenDarkLightThemeHasChanged_needsToBeRecreated() {
+ ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
+ mTaskInfo.configuration.uiMode =
+ (mTaskInfo.configuration.uiMode & ~Configuration.UI_MODE_NIGHT_MASK)
+ | Configuration.UI_MODE_NIGHT_YES;
+
+ Assert.assertTrue(mWindowManager.needsToBeRecreated(newTaskInfo, mTaskListener));
+ }
+}
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 88e351963148..e21d6fb2fe14 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -45,14 +45,13 @@ const ui::Transform kIdentityTransform;
// --- PointerController::DisplayInfoListener ---
void PointerController::DisplayInfoListener::onWindowInfosChanged(
- const std::vector<android::gui::WindowInfo>&,
- const std::vector<android::gui::DisplayInfo>& displayInfos) {
+ const gui::WindowInfosUpdate& update) {
std::scoped_lock lock(mLock);
if (mPointerController == nullptr) return;
// PointerController uses DisplayInfoListener's lock.
base::ScopedLockAssertion assumeLocked(mPointerController->getLock());
- mPointerController->onDisplayInfosChangedLocked(displayInfos);
+ mPointerController->onDisplayInfosChangedLocked(update.displayInfos);
}
void PointerController::DisplayInfoListener::onPointerControllerDestroyed() {
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index ca14b6e9bfdc..62ee74331302 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -19,6 +19,7 @@
#include <PointerControllerInterface.h>
#include <gui/DisplayEventReceiver.h>
+#include <gui/WindowInfosUpdate.h>
#include <input/DisplayViewport.h>
#include <input/Input.h>
#include <utils/BitSet.h>
@@ -114,8 +115,7 @@ private:
class DisplayInfoListener : public gui::WindowInfosListener {
public:
explicit DisplayInfoListener(PointerController* pc) : mPointerController(pc){};
- void onWindowInfosChanged(const std::vector<android::gui::WindowInfo>&,
- const std::vector<android::gui::DisplayInfo>&) override;
+ void onWindowInfosChanged(const gui::WindowInfosUpdate&) override;
void onPointerControllerDestroyed();
// This lock is also used by PointerController. See PointerController::getLock().
diff --git a/libs/input/tests/PointerController_test.cpp b/libs/input/tests/PointerController_test.cpp
index 2378d42793a1..85747514aa03 100644
--- a/libs/input/tests/PointerController_test.cpp
+++ b/libs/input/tests/PointerController_test.cpp
@@ -343,7 +343,7 @@ TEST_F(PointerControllerWindowInfoListenerTest,
localListenerCopy = registeredListener;
}
EXPECT_EQ(nullptr, registeredListener) << "WindowInfosListener was not unregistered";
- localListenerCopy->onWindowInfosChanged({}, {});
+ localListenerCopy->onWindowInfosChanged({{}, {}, 0, 0});
}
} // namespace android