diff options
Diffstat (limited to 'libs')
15 files changed, 309 insertions, 286 deletions
diff --git a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json index 02bf38504725..3f6ca0fc5246 100644 --- a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json +++ b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json @@ -31,12 +31,6 @@ "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, - "-1312360667": { - "message": "createRootTask() displayId=%d winMode=%d listener=%s", - "level": "VERBOSE", - "group": "WM_SHELL_TASK_ORG", - "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" - }, "-880817403": { "message": "Task vanished taskId=%d", "level": "VERBOSE", diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java index 4cb5fd139259..5bd693a9311e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java @@ -20,7 +20,9 @@ import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCR import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString; import android.app.ActivityManager; -import android.util.ArraySet; +import android.content.res.Configuration; +import android.graphics.Rect; +import android.util.ArrayMap; import android.util.Slog; import android.view.SurfaceControl; @@ -37,7 +39,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { private final SyncTransactionQueue mSyncQueue; - private final ArraySet<Integer> mTasks = new ArraySet<>(); + private final ArrayMap<Integer, SurfaceControl> mTasks = new ArrayMap<>(); FullscreenTaskListener(SyncTransactionQueue syncQueue) { mSyncQueue = syncQueue; @@ -46,16 +48,16 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { synchronized (mTasks) { - if (mTasks.contains(taskInfo.taskId)) { + if (mTasks.containsKey(taskInfo.taskId)) { throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId); } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d", taskInfo.taskId); - mTasks.add(taskInfo.taskId); + mTasks.put(taskInfo.taskId, leash); mSyncQueue.runInSync(t -> { // Reset several properties back to fullscreen (PiP, for example, leaves all these // properties in a bad state). - t.setPosition(leash, 0, 0); + updateSurfacePosition(t, taskInfo, leash); t.setWindowCrop(leash, null); // TODO(shell-transitions): Eventually set everything in transition so there's no // SF Transaction here. @@ -71,7 +73,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { @Override public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { synchronized (mTasks) { - if (!mTasks.remove(taskInfo.taskId)) { + if (mTasks.remove(taskInfo.taskId) == null) { Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId); return; } @@ -81,6 +83,23 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { } @Override + public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { + synchronized (mTasks) { + if (!mTasks.containsKey(taskInfo.taskId)) { + Slog.e(TAG, "Changed Task wasn't appeared or already vanished: #" + + taskInfo.taskId); + return; + } + final SurfaceControl leash = mTasks.get(taskInfo.taskId); + mSyncQueue.runInSync(t -> { + // Reposition the task in case the bounds has been changed (such as Task level + // letterboxing). + updateSurfacePosition(t, taskInfo, leash); + }); + } + } + + @Override public void dump(@NonNull PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; final String childPrefix = innerPrefix + " "; @@ -92,4 +111,13 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { public String toString() { return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN); } + + /** Places the Task surface to the latest position. */ + private static void updateSurfacePosition(SurfaceControl.Transaction t, + ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { + // TODO(170725334) drop this after ag/12876439 + final Configuration config = taskInfo.getConfiguration(); + final Rect bounds = config.windowConfiguration.getBounds(); + t.setPosition(leash, bounds.left, bounds.top); + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java index 8bd7193843f7..cbc1c8d6d310 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -105,6 +105,8 @@ public class ShellTaskOrganizer extends TaskOrganizer { // TODO(shell-transitions): move to a more "global" Shell location as this isn't only for Tasks private final Transitions mTransitions; + private final Object mLock = new Object(); + public ShellTaskOrganizer(SyncTransactionQueue syncQueue, TransactionPool transactionPool, ShellExecutor mainExecutor, ShellExecutor animExecutor) { this(null, syncQueue, transactionPool, mainExecutor, animExecutor); @@ -114,7 +116,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController, SyncTransactionQueue syncQueue, TransactionPool transactionPool, ShellExecutor mainExecutor, ShellExecutor animExecutor) { - super(taskOrganizerController); + super(taskOrganizerController, mainExecutor); addListenerForType(new FullscreenTaskListener(syncQueue), TASK_LISTENER_TYPE_FULLSCREEN); mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor); if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions); @@ -122,68 +124,62 @@ public class ShellTaskOrganizer extends TaskOrganizer { @Override public List<TaskAppearedInfo> registerOrganizer() { - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Registering organizer"); - final List<TaskAppearedInfo> taskInfos = super.registerOrganizer(); - for (int i = 0; i < taskInfos.size(); i++) { - final TaskAppearedInfo info = taskInfos.get(i); - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Existing task: id=%d component=%s", - info.getTaskInfo().taskId, info.getTaskInfo().baseIntent); - onTaskAppeared(info); + synchronized (mLock) { + ProtoLog.v(WM_SHELL_TASK_ORG, "Registering organizer"); + final List<TaskAppearedInfo> taskInfos = super.registerOrganizer(); + for (int i = 0; i < taskInfos.size(); i++) { + final TaskAppearedInfo info = taskInfos.get(i); + ProtoLog.v(WM_SHELL_TASK_ORG, "Existing task: id=%d component=%s", + info.getTaskInfo().taskId, info.getTaskInfo().baseIntent); + onTaskAppeared(info); + } + return taskInfos; } - return taskInfos; - } - - public TaskAppearedInfo createRootTask( - int displayId, int windowingMode, TaskListener listener) { - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, - "createRootTask() displayId=%d winMode=%d listener=%s", - displayId, windowingMode, listener.toString()); - final TaskAppearedInfo info = super.createRootTask(displayId, windowingMode); - - // Add the listener and send the task appeared signal - mTaskListeners.put(info.getTaskInfo().taskId, listener); - onTaskAppeared(info); - return info; } /** * Adds a listener for a specific task id. */ public void addListenerForTaskId(TaskListener listener, int taskId) { - ProtoLog.v(WM_SHELL_TASK_ORG, "addListenerForTaskId taskId=%s", taskId); - if (mTaskListeners.get(taskId) != null) { - throw new IllegalArgumentException("Listener for taskId=" + taskId + " already exists"); - } + synchronized (mLock) { + ProtoLog.v(WM_SHELL_TASK_ORG, "addListenerForTaskId taskId=%s", taskId); + if (mTaskListeners.get(taskId) != null) { + throw new IllegalArgumentException( + "Listener for taskId=" + taskId + " already exists"); + } - final TaskAppearedInfo info = mTasks.get(taskId); - if (info == null) { - throw new IllegalArgumentException("addListenerForTaskId unknown taskId=" + taskId); - } + final TaskAppearedInfo info = mTasks.get(taskId); + if (info == null) { + throw new IllegalArgumentException("addListenerForTaskId unknown taskId=" + taskId); + } - final TaskListener oldListener = getTaskListener(info.getTaskInfo()); - mTaskListeners.put(taskId, listener); - updateTaskListenerIfNeeded(info.getTaskInfo(), info.getLeash(), oldListener, listener); + final TaskListener oldListener = getTaskListener(info.getTaskInfo()); + mTaskListeners.put(taskId, listener); + updateTaskListenerIfNeeded(info.getTaskInfo(), info.getLeash(), oldListener, listener); + } } /** * Adds a listener for tasks with given types. */ public void addListenerForType(TaskListener listener, @TaskListenerType int... listenerTypes) { - ProtoLog.v(WM_SHELL_TASK_ORG, "addListenerForType types=%s listener=%s", - Arrays.toString(listenerTypes), listener); - for (int listenerType : listenerTypes) { - if (mTaskListeners.get(listenerType) != null) { - throw new IllegalArgumentException("Listener for listenerType=" + listenerType - + " already exists"); - } - mTaskListeners.put(listenerType, listener); - - // Notify the listener of all existing tasks with the given type. - for (int i = mTasks.size() - 1; i >= 0; --i) { - final TaskAppearedInfo data = mTasks.valueAt(i); - final TaskListener taskListener = getTaskListener(data.getTaskInfo()); - if (taskListener != listener) continue; - listener.onTaskAppeared(data.getTaskInfo(), data.getLeash()); + synchronized (mLock) { + ProtoLog.v(WM_SHELL_TASK_ORG, "addListenerForType types=%s listener=%s", + Arrays.toString(listenerTypes), listener); + for (int listenerType : listenerTypes) { + if (mTaskListeners.get(listenerType) != null) { + throw new IllegalArgumentException("Listener for listenerType=" + listenerType + + " already exists"); + } + mTaskListeners.put(listenerType, listener); + + // Notify the listener of all existing tasks with the given type. + for (int i = mTasks.size() - 1; i >= 0; --i) { + final TaskAppearedInfo data = mTasks.valueAt(i); + final TaskListener taskListener = getTaskListener(data.getTaskInfo()); + if (taskListener != listener) continue; + listener.onTaskAppeared(data.getTaskInfo(), data.getLeash()); + } } } } @@ -192,30 +188,32 @@ public class ShellTaskOrganizer extends TaskOrganizer { * Removes a registered listener. */ public void removeListener(TaskListener listener) { - ProtoLog.v(WM_SHELL_TASK_ORG, "Remove listener=%s", listener); - final int index = mTaskListeners.indexOfValue(listener); - if (index == -1) { - Log.w(TAG, "No registered listener found"); - return; - } + synchronized (mLock) { + ProtoLog.v(WM_SHELL_TASK_ORG, "Remove listener=%s", listener); + final int index = mTaskListeners.indexOfValue(listener); + if (index == -1) { + Log.w(TAG, "No registered listener found"); + return; + } - // Collect tasks associated with the listener we are about to remove. - final ArrayList<TaskAppearedInfo> tasks = new ArrayList<>(); - for (int i = mTasks.size() - 1; i >= 0; --i) { - final TaskAppearedInfo data = mTasks.valueAt(i); - final TaskListener taskListener = getTaskListener(data.getTaskInfo()); - if (taskListener != listener) continue; - tasks.add(data); - } + // Collect tasks associated with the listener we are about to remove. + final ArrayList<TaskAppearedInfo> tasks = new ArrayList<>(); + for (int i = mTasks.size() - 1; i >= 0; --i) { + final TaskAppearedInfo data = mTasks.valueAt(i); + final TaskListener taskListener = getTaskListener(data.getTaskInfo()); + if (taskListener != listener) continue; + tasks.add(data); + } - // Remove listener - mTaskListeners.removeAt(index); + // Remove listener + mTaskListeners.removeAt(index); - // Associate tasks with new listeners if needed. - for (int i = tasks.size() - 1; i >= 0; --i) { - final TaskAppearedInfo data = tasks.get(i); - updateTaskListenerIfNeeded(data.getTaskInfo(), data.getLeash(), - null /* oldListener already removed*/, getTaskListener(data.getTaskInfo())); + // Associate tasks with new listeners if needed. + for (int i = tasks.size() - 1; i >= 0; --i) { + final TaskAppearedInfo data = tasks.get(i); + updateTaskListenerIfNeeded(data.getTaskInfo(), data.getLeash(), + null /* oldListener already removed*/, getTaskListener(data.getTaskInfo())); + } } } @@ -224,12 +222,16 @@ public class ShellTaskOrganizer extends TaskOrganizer { * appears. */ public void setPendingLaunchCookieListener(IBinder cookie, TaskListener listener) { - mLaunchCookieToListener.put(cookie, listener); + synchronized (mLock) { + mLaunchCookieToListener.put(cookie, listener); + } } @Override public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { - onTaskAppeared(new TaskAppearedInfo(taskInfo, leash)); + synchronized (mLock) { + onTaskAppeared(new TaskAppearedInfo(taskInfo, leash)); + } } private void onTaskAppeared(TaskAppearedInfo info) { @@ -245,35 +247,41 @@ public class ShellTaskOrganizer extends TaskOrganizer { @Override public void onTaskInfoChanged(RunningTaskInfo taskInfo) { - ProtoLog.v(WM_SHELL_TASK_ORG, "Task info changed taskId=%d", taskInfo.taskId); - final TaskAppearedInfo data = mTasks.get(taskInfo.taskId); - final TaskListener oldListener = getTaskListener(data.getTaskInfo()); - final TaskListener newListener = getTaskListener(taskInfo); - mTasks.put(taskInfo.taskId, new TaskAppearedInfo(taskInfo, data.getLeash())); - final boolean updated = updateTaskListenerIfNeeded( - taskInfo, data.getLeash(), oldListener, newListener); - if (!updated && newListener != null) { - newListener.onTaskInfoChanged(taskInfo); + synchronized (mLock) { + ProtoLog.v(WM_SHELL_TASK_ORG, "Task info changed taskId=%d", taskInfo.taskId); + final TaskAppearedInfo data = mTasks.get(taskInfo.taskId); + final TaskListener oldListener = getTaskListener(data.getTaskInfo()); + final TaskListener newListener = getTaskListener(taskInfo); + mTasks.put(taskInfo.taskId, new TaskAppearedInfo(taskInfo, data.getLeash())); + final boolean updated = updateTaskListenerIfNeeded( + taskInfo, data.getLeash(), oldListener, newListener); + if (!updated && newListener != null) { + newListener.onTaskInfoChanged(taskInfo); + } } } @Override public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { - ProtoLog.v(WM_SHELL_TASK_ORG, "Task root back pressed taskId=%d", taskInfo.taskId); - final TaskListener listener = getTaskListener(taskInfo); - if (listener != null) { - listener.onBackPressedOnTaskRoot(taskInfo); + synchronized (mLock) { + ProtoLog.v(WM_SHELL_TASK_ORG, "Task root back pressed taskId=%d", taskInfo.taskId); + final TaskListener listener = getTaskListener(taskInfo); + if (listener != null) { + listener.onBackPressedOnTaskRoot(taskInfo); + } } } @Override public void onTaskVanished(RunningTaskInfo taskInfo) { - ProtoLog.v(WM_SHELL_TASK_ORG, "Task vanished taskId=%d", taskInfo.taskId); - final int taskId = taskInfo.taskId; - final TaskListener listener = getTaskListener(mTasks.get(taskId).getTaskInfo()); - mTasks.remove(taskId); - if (listener != null) { - listener.onTaskVanished(taskInfo); + synchronized (mLock) { + ProtoLog.v(WM_SHELL_TASK_ORG, "Task vanished taskId=%d", taskInfo.taskId); + final int taskId = taskInfo.taskId; + final TaskListener listener = getTaskListener(mTasks.get(taskId).getTaskInfo()); + mTasks.remove(taskId); + if (listener != null) { + listener.onTaskVanished(taskInfo); + } } } @@ -368,32 +376,34 @@ public class ShellTaskOrganizer extends TaskOrganizer { } public void dump(@NonNull PrintWriter pw, String prefix) { - final String innerPrefix = prefix + " "; - final String childPrefix = innerPrefix + " "; - pw.println(prefix + TAG); - pw.println(innerPrefix + mTaskListeners.size() + " Listeners"); - for (int i = mTaskListeners.size() - 1; i >= 0; --i) { - final int key = mTaskListeners.keyAt(i); - final TaskListener listener = mTaskListeners.valueAt(i); - pw.println(innerPrefix + "#" + i + " " + taskListenerTypeToString(key)); - listener.dump(pw, childPrefix); - } + synchronized (mLock) { + final String innerPrefix = prefix + " "; + final String childPrefix = innerPrefix + " "; + pw.println(prefix + TAG); + pw.println(innerPrefix + mTaskListeners.size() + " Listeners"); + for (int i = mTaskListeners.size() - 1; i >= 0; --i) { + final int key = mTaskListeners.keyAt(i); + final TaskListener listener = mTaskListeners.valueAt(i); + pw.println(innerPrefix + "#" + i + " " + taskListenerTypeToString(key)); + listener.dump(pw, childPrefix); + } - pw.println(); - pw.println(innerPrefix + mTasks.size() + " Tasks"); - for (int i = mTasks.size() - 1; i >= 0; --i) { - final int key = mTasks.keyAt(i); - final TaskAppearedInfo info = mTasks.valueAt(i); - final TaskListener listener = getTaskListener(info.getTaskInfo()); - pw.println(innerPrefix + "#" + i + " task=" + key + " listener=" + listener); - } + pw.println(); + pw.println(innerPrefix + mTasks.size() + " Tasks"); + for (int i = mTasks.size() - 1; i >= 0; --i) { + final int key = mTasks.keyAt(i); + final TaskAppearedInfo info = mTasks.valueAt(i); + final TaskListener listener = getTaskListener(info.getTaskInfo()); + pw.println(innerPrefix + "#" + i + " task=" + key + " listener=" + listener); + } - pw.println(); - pw.println(innerPrefix + mLaunchCookieToListener.size() + " Launch Cookies"); - for (int i = mLaunchCookieToListener.size() - 1; i >= 0; --i) { - final IBinder key = mLaunchCookieToListener.keyAt(i); - final TaskListener listener = mLaunchCookieToListener.valueAt(i); - pw.println(innerPrefix + "#" + i + " cookie=" + key + " listener=" + listener); + pw.println(); + pw.println(innerPrefix + mLaunchCookieToListener.size() + " Launch Cookies"); + for (int i = mLaunchCookieToListener.size() - 1; i >= 0; --i) { + final IBinder key = mLaunchCookieToListener.keyAt(i); + final TaskListener listener = mLaunchCookieToListener.valueAt(i); + pw.println(innerPrefix + "#" + i + " cookie=" + key + " listener=" + listener); + } } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java index eaf5d7960aa9..24381d937e2f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java @@ -270,25 +270,6 @@ public class SystemWindows { mDisplayId = displayId; } - @Override - public int relayout(IWindow window, WindowManager.LayoutParams attrs, - int requestedWidth, int requestedHeight, int viewVisibility, int flags, - long frameNumber, ClientWindowFrames outFrames, - MergedConfiguration mergedConfiguration, - SurfaceControl outSurfaceControl, InsetsState outInsetsState, - InsetsSourceControl[] outActiveControls, Point outSurfaceSize) { - int res = super.relayout(window, attrs, requestedWidth, requestedHeight, - viewVisibility, flags, frameNumber, outFrames, - mergedConfiguration, outSurfaceControl, outInsetsState, - outActiveControls, outSurfaceSize); - if (res != 0) { - return res; - } - DisplayLayout dl = mDisplayController.getDisplayLayout(mDisplayId); - outFrames.stableInsets.set(dl.stableInsets()); - return 0; - } - void updateConfiguration(Configuration configuration) { setConfiguration(configuration); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java index 6d6cc204538a..08318186a105 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java @@ -60,7 +60,6 @@ public class PipBoundsHandler { private float mDefaultAspectRatio; private float mMinAspectRatio; private float mMaxAspectRatio; - private float mAspectRatio; private int mDefaultStackGravity; private int mDefaultMinSize; private Point mScreenEdgeInsets; @@ -80,7 +79,7 @@ public class PipBoundsHandler { // Initialize the aspect ratio to the default aspect ratio. Don't do this in reload // resources as it would clobber mAspectRatio when entering PiP from fullscreen which // triggers a configuration change and the resources to be reloaded. - mAspectRatio = mDefaultAspectRatio; + mPipBoundsState.setAspectRatio(mDefaultAspectRatio); } /** @@ -133,10 +132,6 @@ public class PipBoundsHandler { mCurrentMinSize = minEdgeSize; } - protected float getAspectRatio() { - return mAspectRatio; - } - /** * Sets both shelf visibility and its height if applicable. * @return {@code true} if the internal shelf state is changed, {@code false} otherwise. @@ -172,8 +167,8 @@ public class PipBoundsHandler { if (animatingBounds.isEmpty()) { animatingBounds.set(defaultBounds); } - if (isValidPictureInPictureAspectRatio(mAspectRatio)) { - transformBoundsToAspectRatio(normalBounds, mAspectRatio, + if (isValidPictureInPictureAspectRatio(mPipBoundsState.getAspectRatio())) { + transformBoundsToAspectRatio(normalBounds, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, false /* useCurrentSize */); } displayInfo.copyFrom(mDisplayInfo); @@ -212,27 +207,16 @@ public class PipBoundsHandler { } /** - * Responds to IPinnedStackListener on resetting aspect ratio for the pinned window. - * It will normally follow up with a - * {@link #onMovementBoundsChanged(Rect, Rect, Rect, DisplayInfo)} callback. - */ - public void onAspectRatioChanged(float aspectRatio) { - mAspectRatio = aspectRatio; - } - - /** - * See {@link #getDestinationBounds(float, Rect, Size, boolean)} + * See {@link #getDestinationBounds(Rect, Size, boolean)} */ - public Rect getDestinationBounds(float aspectRatio, Rect bounds, Size minimalSize) { - return getDestinationBounds(aspectRatio, bounds, minimalSize, - false /* useCurrentMinEdgeSize */); + public Rect getDestinationBounds(Rect bounds, Size minimalSize) { + return getDestinationBounds(bounds, minimalSize, false /* useCurrentMinEdgeSize */); } /** * @return {@link Rect} of the destination PiP window bounds. */ - public Rect getDestinationBounds(float aspectRatio, Rect bounds, - Size minimalSize, boolean useCurrentMinEdgeSize) { + public Rect getDestinationBounds(Rect bounds, Size minimalSize, boolean useCurrentMinEdgeSize) { boolean isReentryBounds = false; final Rect destinationBounds; if (bounds == null) { @@ -255,11 +239,10 @@ public class PipBoundsHandler { // Just adjusting bounds (e.g. on aspect ratio changed). destinationBounds = new Rect(bounds); } - if (isValidPictureInPictureAspectRatio(aspectRatio)) { - transformBoundsToAspectRatio(destinationBounds, aspectRatio, useCurrentMinEdgeSize, - isReentryBounds); + if (isValidPictureInPictureAspectRatio(mPipBoundsState.getAspectRatio())) { + transformBoundsToAspectRatio(destinationBounds, mPipBoundsState.getAspectRatio(), + useCurrentMinEdgeSize, isReentryBounds); } - mAspectRatio = aspectRatio; return destinationBounds; } @@ -368,8 +351,8 @@ public class PipBoundsHandler { * @param stackBounds */ public void transformBoundsToAspectRatio(Rect stackBounds) { - transformBoundsToAspectRatio(stackBounds, mAspectRatio, true /* useCurrentMinEdgeSize */, - true /* useCurrentSize */); + transformBoundsToAspectRatio(stackBounds, mPipBoundsState.getAspectRatio(), + true /* useCurrentMinEdgeSize */, true /* useCurrentSize */); } /** @@ -514,7 +497,6 @@ public class PipBoundsHandler { pw.println(innerPrefix + "mDefaultAspectRatio=" + mDefaultAspectRatio); pw.println(innerPrefix + "mMinAspectRatio=" + mMinAspectRatio); pw.println(innerPrefix + "mMaxAspectRatio=" + mMaxAspectRatio); - pw.println(innerPrefix + "mAspectRatio=" + mAspectRatio); pw.println(innerPrefix + "mDefaultStackGravity=" + mDefaultStackGravity); pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing); pw.println(innerPrefix + "mImeHeight=" + mImeHeight); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java index 2625f16fac46..aba2a3a29fe2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java @@ -34,6 +34,7 @@ public final class PipBoundsState { private static final String TAG = PipBoundsState.class.getSimpleName(); private final @NonNull Rect mBounds = new Rect(); + private float mAspectRatio; private PipReentryState mPipReentryState; private ComponentName mLastPipComponentName; @@ -46,6 +47,14 @@ public final class PipBoundsState { return new Rect(mBounds); } + public void setAspectRatio(float aspectRatio) { + mAspectRatio = aspectRatio; + } + + public float getAspectRatio() { + return mAspectRatio; + } + /** * Save the reentry state to restore to when re-entering PIP mode. * @@ -120,6 +129,7 @@ public final class PipBoundsState { pw.println(prefix + TAG); pw.println(innerPrefix + "mBounds=" + mBounds); pw.println(innerPrefix + "mLastPipComponentName=" + mLastPipComponentName); + pw.println(innerPrefix + "mAspectRatio=" + mAspectRatio); if (mPipReentryState == null) { pw.println(innerPrefix + "mPipReentryState=null"); } else { 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 cd5d35bf0c4c..a7bf9aea46bc 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 @@ -341,9 +341,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mShouldIgnoreEnteringPipTransition = true; mState = State.ENTERING_PIP; mPipBoundsState.setLastPipComponentName(componentName); - return mPipBoundsHandler.getDestinationBounds( - getAspectRatioOrDefault(pictureInPictureParams), - null /* bounds */, getMinimalSize(activityInfo)); + mPipBoundsState.setAspectRatio(getAspectRatioOrDefault(pictureInPictureParams)); + return mPipBoundsHandler.getDestinationBounds(null /* bounds */, + getMinimalSize(activityInfo)); } /** @@ -514,9 +514,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, return; } - final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( - getAspectRatioOrDefault(mPictureInPictureParams), - null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); + mPipBoundsState.setAspectRatio(getAspectRatioOrDefault(mPictureInPictureParams)); + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(null /* bounds */, + getMinimalSize(mTaskInfo.topActivityInfo)); Objects.requireNonNull(destinationBounds, "Missing destination bounds"); final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds(); @@ -717,8 +717,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams); return; } + // Aspect ratio changed, re-calculate destination bounds. final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( - getAspectRatioOrDefault(newParams), mPipBoundsState.getBounds(), getMinimalSize(info.topActivityInfo), true /* userCurrentMinEdgeSize */); Objects.requireNonNull(destinationBounds, "Missing destination bounds"); @@ -735,7 +735,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, public void onFixedRotationFinished(int displayId) { if (mShouldDeferEnteringPip && mState.isInPip()) { final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( - getAspectRatioOrDefault(mPictureInPictureParams), null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); // schedule a regular animation to ensure all the callbacks are still being sent enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */); @@ -808,9 +807,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, return; } - final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds( - getAspectRatioOrDefault(mPictureInPictureParams), - null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); + final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds(null /* bounds */, + getMinimalSize(mTaskInfo.topActivityInfo)); if (newDestinationBounds.equals(currentDestinationBounds)) return; if (animator.getAnimationType() == ANIM_TYPE_BOUNDS) { animator.updateEndValue(newDestinationBounds); @@ -831,7 +829,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, params.getAspectRatioRational()); mPictureInPictureParams = params; if (aspectRatioChanged) { - mPipBoundsHandler.onAspectRatioChanged(params.getAspectRatio()); + mPipBoundsState.setAspectRatio(params.getAspectRatio()); } return aspectRatioChanged; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index a08983740f9a..edc68e5221f1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -197,8 +197,10 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onAspectRatioChanged(float aspectRatio) { + // TODO(b/169373982): Remove this callback as it is redundant with PipTaskOrg params + // change. mHandler.post(() -> { - mPipBoundsHandler.onAspectRatioChanged(aspectRatio); + mPipBoundsState.setAspectRatio(aspectRatio); mTouchHandler.onAspectRatioChanged(); }); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java index 22c05fb8acd9..64e3758fd81a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java @@ -16,6 +16,7 @@ package com.android.wm.shell.pip.phone; +import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import android.app.IActivityManager; @@ -180,25 +181,25 @@ public class PipMediaController { mPauseAction = new RemoteAction(Icon.createWithResource(mContext, R.drawable.pip_ic_pause_white), pauseDescription, pauseDescription, PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PAUSE), - FLAG_UPDATE_CURRENT)); + FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); String playDescription = mContext.getString(R.string.pip_play); mPlayAction = new RemoteAction(Icon.createWithResource(mContext, R.drawable.pip_ic_play_arrow_white), playDescription, playDescription, PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PLAY), - FLAG_UPDATE_CURRENT)); + FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); String nextDescription = mContext.getString(R.string.pip_skip_to_next); mNextAction = new RemoteAction(Icon.createWithResource(mContext, R.drawable.pip_ic_skip_next_white), nextDescription, nextDescription, PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NEXT), - FLAG_UPDATE_CURRENT)); + FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); String prevDescription = mContext.getString(R.string.pip_skip_to_prev); mPrevAction = new RemoteAction(Icon.createWithResource(mContext, R.drawable.pip_ic_skip_previous_white), prevDescription, prevDescription, PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PREV), - FLAG_UPDATE_CURRENT)); + FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java index 8eac005425bc..4f2d4e50f76d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java @@ -19,6 +19,10 @@ package com.android.wm.shell.pip.tv; import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.content.Intent.ACTION_MEDIA_RESOURCE_GRANTED; + +import static com.android.wm.shell.pip.tv.PipNotification.ACTION_CLOSE; +import static com.android.wm.shell.pip.tv.PipNotification.ACTION_MENU; import android.app.ActivityManager; import android.app.ActivityTaskManager; @@ -140,17 +144,26 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intent.ACTION_MEDIA_RESOURCE_GRANTED.equals(action)) { - String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); - int resourceType = intent.getIntExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE, - INVALID_RESOURCE_TYPE); - if (packageNames != null && packageNames.length > 0 - && resourceType == Intent.EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC) { - handleMediaResourceGranted(packageNames); - } + if (DEBUG) { + Log.d(TAG, "mBroadcastReceiver, action: " + intent.getAction()); + } + switch (intent.getAction()) { + case ACTION_MENU: + showPictureInPictureMenu(); + break; + case ACTION_CLOSE: + closePip(); + break; + case ACTION_MEDIA_RESOURCE_GRANTED: + String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); + int resourceType = intent.getIntExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE, + INVALID_RESOURCE_TYPE); + if (packageNames != null && packageNames.length > 0 + && resourceType == Intent.EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC) { + handleMediaResourceGranted(packageNames); + } + break; } - } }; private final MediaSessionManager.OnActiveSessionsChangedListener mActiveMediaSessionListener = @@ -233,8 +246,11 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mPipTaskOrganizer = pipTaskOrganizer; mPipTaskOrganizer.registerPipTransitionCallback(this); mActivityTaskManager = ActivityTaskManager.getService(); - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED); + + final IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(ACTION_CLOSE); + intentFilter.addAction(ACTION_MENU); + intentFilter.addAction(ACTION_MEDIA_RESOURCE_GRANTED); mContext.registerReceiver(mBroadcastReceiver, intentFilter, UserHandle.USER_ALL); // Initialize the last orientation and apply the current configuration @@ -249,10 +265,10 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } catch (RemoteException e) { Log.e(TAG, "Failed to register pinned stack listener", e); } - } - // TODO(b/169395392) Refactor PipMenuActivity to PipMenuView - PipMenuActivity.setPipController(this); + // TODO(b/169395392) Refactor PipMenuActivity to PipMenuView + PipMenuActivity.setPipController(this); + } } private void loadConfigurationsAndApply(Configuration newConfig) { @@ -564,6 +580,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } catch (RemoteException e) { Log.e(TAG, "getRootTaskInfo failed", e); } + if (DEBUG) Log.d(TAG, "getPinnedTaskInfo(), taskInfo=" + taskInfo); return taskInfo; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java index 06d2408c95f4..e185a9604449 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java @@ -35,7 +35,7 @@ import java.util.Collections; */ public class PipMenuActivity extends Activity implements PipController.Listener { private static final String TAG = "PipMenuActivity"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private static final boolean DEBUG = PipController.DEBUG; static final String EXTRA_CUSTOM_ACTIONS = "custom_actions"; @@ -51,7 +51,7 @@ public class PipMenuActivity extends Activity implements PipController.Listener if (DEBUG) Log.d(TAG, "onCreate()"); super.onCreate(bundle); - if (sPipController == null || sPipController.isPipShown()) { + if (sPipController == null) { finish(); } setContentView(R.layout.tv_pip_menu); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java index 7433085e6fcb..f5bbd23fa1d6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java @@ -20,10 +20,8 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.RemoteAction; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; @@ -32,9 +30,7 @@ import android.graphics.Bitmap; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.PlaybackState; -import android.os.UserHandle; import android.text.TextUtils; -import android.util.Log; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.wm.shell.R; @@ -49,8 +45,8 @@ public class PipNotification { private static final String NOTIFICATION_TAG = PipNotification.class.getSimpleName(); private static final boolean DEBUG = PipController.DEBUG; - private static final String ACTION_MENU = "PipNotification.menu"; - private static final String ACTION_CLOSE = "PipNotification.close"; + static final String ACTION_MENU = "PipNotification.menu"; + static final String ACTION_CLOSE = "PipNotification.close"; public static final String NOTIFICATION_CHANNEL_TVPIP = "TPP"; @@ -147,23 +143,6 @@ public class PipNotification { } }; - private final BroadcastReceiver mEventReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (DEBUG) { - Log.d(TAG, "Received " + intent.getAction() + " from the notification UI"); - } - switch (intent.getAction()) { - case ACTION_MENU: - mPipController.showPictureInPictureMenu(); - break; - case ACTION_CLOSE: - mPipController.closePip(); - break; - } - } - }; - public PipNotification(Context context, PipController pipController) { mPackageManager = context.getPackageManager(); @@ -182,11 +161,6 @@ public class PipNotification { pipController.addListener(mPipListener); pipController.addMediaListener(mPipMediaListener); - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(ACTION_MENU); - intentFilter.addAction(ACTION_CLOSE); - context.registerReceiver(mEventReceiver, intentFilter, UserHandle.USER_ALL); - onConfigurationChanged(context); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java index 0a1aadc90a62..f763d6d714c4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java @@ -33,7 +33,6 @@ import android.util.Log; import android.view.Display; import android.view.SurfaceControl; import android.view.SurfaceSession; -import android.window.TaskAppearedInfo; import androidx.annotation.NonNull; @@ -69,15 +68,10 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener { void init() throws RemoteException { synchronized (this) { try { - final TaskAppearedInfo primary = mTaskOrganizer.createRootTask( - Display.DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, this); - final TaskAppearedInfo secondary = mTaskOrganizer.createRootTask( - Display.DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, this); - mPrimary = primary.getTaskInfo(); - mPrimarySurface = primary.getLeash(); - mSecondary = secondary.getTaskInfo(); - mSecondarySurface = secondary.getLeash(); - enableSplitScreenSupportIfNeeded(); + mPrimary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, + WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + mSecondary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, + WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); } catch (Exception e) { // teardown to prevent callbacks mTaskOrganizer.removeListener(this); @@ -98,29 +92,43 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener { mSplitScreenController.mTransactionPool.release(t); } - private void enableSplitScreenSupportIfNeeded() { - if (mSplitScreenSupported || mPrimarySurface == null || mSecondarySurface == null) return; - - mSplitScreenSupported = true; - - // Initialize dim surfaces: - mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession) - .setParent(mPrimarySurface).setColorLayer() - .setName("Primary Divider Dim") - .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared") - .build(); - mSecondaryDim = new SurfaceControl.Builder(mSurfaceSession) - .setParent(mSecondarySurface).setColorLayer() - .setName("Secondary Divider Dim") - .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared") - .build(); - SurfaceControl.Transaction t = getTransaction(); - t.setLayer(mPrimaryDim, Integer.MAX_VALUE); - t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f}); - t.setLayer(mSecondaryDim, Integer.MAX_VALUE); - t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f}); - t.apply(); - releaseTransaction(t); + @Override + public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { + synchronized (this) { + if (mPrimary == null || mSecondary == null) { + Log.w(TAG, "Received onTaskAppeared before creating root tasks " + taskInfo); + return; + } + + if (taskInfo.token.equals(mPrimary.token)) { + mPrimarySurface = leash; + } else if (taskInfo.token.equals(mSecondary.token)) { + mSecondarySurface = leash; + } + + if (!mSplitScreenSupported && mPrimarySurface != null && mSecondarySurface != null) { + mSplitScreenSupported = true; + + // Initialize dim surfaces: + mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession) + .setParent(mPrimarySurface).setColorLayer() + .setName("Primary Divider Dim") + .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared") + .build(); + mSecondaryDim = new SurfaceControl.Builder(mSurfaceSession) + .setParent(mSecondarySurface).setColorLayer() + .setName("Secondary Divider Dim") + .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared") + .build(); + SurfaceControl.Transaction t = getTransaction(); + t.setLayer(mPrimaryDim, Integer.MAX_VALUE); + t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f}); + t.setLayer(mSecondaryDim, Integer.MAX_VALUE); + t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f}); + t.apply(); + releaseTransaction(t); + } + } } @Override diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml index 3b66c58414e0..7f8321f3fa3d 100644 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml @@ -32,6 +32,10 @@ <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LEANBACK_LAUNCHER"/> + </intent-filter> </activity> <activity android:name=".ImeActivity" android:taskAffinity="com.android.wm.shell.flicker.testapp.ImeActivity" @@ -41,6 +45,10 @@ <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LEANBACK_LAUNCHER"/> + </intent-filter> </activity> </application> </manifest> diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java index e0ac8e24756d..39117bb5912b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java @@ -123,7 +123,8 @@ public class PipBoundsHandlerTest extends PipTestCase { (MAX_ASPECT_RATIO + DEFAULT_ASPECT_RATIO) / 2 }; for (float aspectRatio : aspectRatios) { - final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio, + mPipBoundsState.setAspectRatio(aspectRatio); + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); final float actualAspectRatio = destinationBounds.width() / (destinationBounds.height() * 1f); @@ -139,7 +140,8 @@ public class PipBoundsHandlerTest extends PipTestCase { MAX_ASPECT_RATIO * 2 }; for (float aspectRatio : invalidAspectRatios) { - final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio, + mPipBoundsState.setAspectRatio(aspectRatio); + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); final float actualAspectRatio = destinationBounds.width() / (destinationBounds.height() * 1f); @@ -155,8 +157,9 @@ public class PipBoundsHandlerTest extends PipTestCase { final Rect currentBounds = new Rect(0, 0, 0, 100); currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left; - final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio, - currentBounds, EMPTY_MINIMAL_SIZE); + mPipBoundsState.setAspectRatio(aspectRatio); + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(currentBounds, + EMPTY_MINIMAL_SIZE); final float actualAspectRatio = destinationBounds.width() / (destinationBounds.height() * 1f); @@ -179,7 +182,8 @@ public class PipBoundsHandlerTest extends PipTestCase { for (int i = 0; i < aspectRatios.length; i++) { final float aspectRatio = aspectRatios[i]; final Size minimalSize = minimalSizes[i]; - final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio, + mPipBoundsState.setAspectRatio(aspectRatio); + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, minimalSize); assertTrue("Destination bounds is no smaller than minimal requirement", (destinationBounds.width() == minimalSize.getWidth() @@ -200,7 +204,8 @@ public class PipBoundsHandlerTest extends PipTestCase { currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left; final Size minSize = new Size(currentBounds.width() / 2, currentBounds.height() / 2); - final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio, + mPipBoundsState.setAspectRatio(aspectRatio); + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( currentBounds, minSize); assertTrue("Destination bounds ignores minimal size", @@ -210,13 +215,14 @@ public class PipBoundsHandlerTest extends PipTestCase { @Test public void getDestinationBounds_reentryStateExists_restoreLastSize() { - final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO); + final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); reentryBounds.scale(1.25f); final float reentrySnapFraction = mPipBoundsHandler.getSnapFraction(reentryBounds); mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction); - final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); assertEquals(reentryBounds.width(), destinationBounds.width()); @@ -225,14 +231,15 @@ public class PipBoundsHandlerTest extends PipTestCase { @Test public void getDestinationBounds_reentryStateExists_restoreLastPosition() { - final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO); + final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); reentryBounds.offset(0, -100); final float reentrySnapFraction = mPipBoundsHandler.getSnapFraction(reentryBounds); mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction); - final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); assertBoundsInclusionWithMargin("restoreLastPosition", reentryBounds, destinationBounds); @@ -241,11 +248,12 @@ public class PipBoundsHandlerTest extends PipTestCase { @Test public void setShelfHeight_offsetBounds() { final int shelfHeight = 100; - final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO); + final Rect oldPosition = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); mPipBoundsHandler.setShelfHeight(true, shelfHeight); - final Rect newPosition = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + final Rect newPosition = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); oldPosition.offset(0, -shelfHeight); @@ -255,11 +263,12 @@ public class PipBoundsHandlerTest extends PipTestCase { @Test public void onImeVisibilityChanged_offsetBounds() { final int imeHeight = 100; - final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO); + final Rect oldPosition = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); mPipBoundsHandler.onImeVisibilityChanged(true, imeHeight); - final Rect newPosition = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + final Rect newPosition = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); oldPosition.offset(0, -imeHeight); @@ -268,12 +277,13 @@ public class PipBoundsHandlerTest extends PipTestCase { @Test public void getDestinationBounds_noReentryState_useDefaultBounds() { - final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO); + final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); mPipBoundsState.clearReentryState(); - final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO, + final Rect actualBounds = mPipBoundsHandler.getDestinationBounds( EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); assertBoundsInclusionWithMargin("useDefaultBounds", defaultBounds, actualBounds); |