diff options
14 files changed, 41 insertions, 1191 deletions
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index fe382a33a8c5..2da5e001a3e4 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -27,7 +27,6 @@ import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Point; -import android.graphics.Rect; import android.os.Build; import android.os.IBinder; import android.os.Parcel; @@ -187,22 +186,6 @@ public class TaskInfo { public boolean isResizeable; /** - * Activity bounds if this task or its top activity is presented in letterbox mode and - * {@code null} otherwise. - * @hide - */ - @Nullable - public Rect letterboxActivityBounds; - - /** - * Activity insets if this task or its top activity is presented in letterbox mode and - * {@code null} otherwise. - * @hide - */ - @Nullable - public Rect letterboxActivityInsets; - - /** * Relative position of the task's top left corner in the parent container. * @hide */ @@ -223,12 +206,6 @@ public class TaskInfo { public int parentTaskId; /** - * Parent bounds. - * @hide - */ - public Rect parentBounds; - - /** * Whether this task is focused. * @hide */ @@ -320,7 +297,6 @@ public class TaskInfo { return topActivityType == that.topActivityType && isResizeable == that.isResizeable && Objects.equals(positionInParent, that.positionInParent) - && equalsLetterboxParams(that) && Objects.equals(pictureInPictureParams, that.pictureInPictureParams) && getWindowingMode() == that.getWindowingMode() && Objects.equals(taskDescription, that.taskDescription) @@ -328,18 +304,6 @@ public class TaskInfo { && isVisible == that.isVisible; } - private boolean equalsLetterboxParams(TaskInfo that) { - return Objects.equals(letterboxActivityBounds, that.letterboxActivityBounds) - && Objects.equals( - getConfiguration().windowConfiguration.getBounds(), - that.getConfiguration().windowConfiguration.getBounds()) - && Objects.equals( - getConfiguration().windowConfiguration.getMaxBounds(), - that.getConfiguration().windowConfiguration.getMaxBounds()) - && Objects.equals(parentBounds, that.parentBounds) - && Objects.equals(letterboxActivityInsets, that.letterboxActivityInsets); - } - /** * Reads the TaskInfo from a parcel. */ @@ -368,13 +332,10 @@ public class TaskInfo { topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR); isResizeable = source.readBoolean(); source.readBinderList(launchCookies); - letterboxActivityBounds = source.readTypedObject(Rect.CREATOR); positionInParent = source.readTypedObject(Point.CREATOR); parentTaskId = source.readInt(); - parentBounds = source.readTypedObject(Rect.CREATOR); isFocused = source.readBoolean(); isVisible = source.readBoolean(); - letterboxActivityInsets = source.readTypedObject(Rect.CREATOR); } /** @@ -406,13 +367,10 @@ public class TaskInfo { dest.writeTypedObject(topActivityInfo, flags); dest.writeBoolean(isResizeable); dest.writeBinderList(launchCookies); - dest.writeTypedObject(letterboxActivityBounds, flags); dest.writeTypedObject(positionInParent, flags); dest.writeInt(parentTaskId); - dest.writeTypedObject(parentBounds, flags); dest.writeBoolean(isFocused); dest.writeBoolean(isVisible); - dest.writeTypedObject(letterboxActivityInsets, flags); } @Override @@ -433,13 +391,10 @@ public class TaskInfo { + " pictureInPictureParams=" + pictureInPictureParams + " topActivityInfo=" + topActivityInfo + " launchCookies=" + launchCookies - + " letterboxActivityBounds=" + letterboxActivityBounds + " positionInParent=" + positionInParent + " parentTaskId=" + parentTaskId - + " parentBounds=" + parentBounds + " isFocused=" + isFocused + " isVisible=" + isVisible - + " letterboxActivityInsets=" + letterboxActivityInsets + "}"; } } diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml index f0eae97b107e..807e5afae890 100644 --- a/libs/WindowManager/Shell/res/values/config.xml +++ b/libs/WindowManager/Shell/res/values/config.xml @@ -42,16 +42,4 @@ <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows, when the PIP menu is shown in center. --> <string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string> - - <!-- Gravity of letterboxed apps in portrait screen orientation. - Can be Gravity.TOP, Gravity.CENTER or Gravity.BOTTOM. - Any other value will result in runtime exception for a letterboxed activity. - Default is Gravity.TOP. --> - <integer name="config_letterboxPortraitGravity">0x00000030</integer> - - <!-- Gravity of letterboxed apps in landscape screen orientation. - Can be Gravity.LEFT, Gravity.CENTER or Gravity.RIGHT. - Any other value will result in runtime exception for a letterboxed activity. - Default is Gravity.CENTER. --> - <integer name="config_letterboxLandscapeGravity">0x00000011</integer> </resources> 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 4f13b83bc29d..63d31182a748 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java @@ -20,8 +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.graphics.Point; import android.util.Slog; +import android.util.SparseArray; import android.view.SurfaceControl; import androidx.annotation.NonNull; @@ -40,7 +41,7 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { private final SyncTransactionQueue mSyncQueue; - private final ArraySet<Integer> mTasks = new ArraySet<>(); + private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>(); public FullscreenTaskListener(SyncTransactionQueue syncQueue) { mSyncQueue = syncQueue; @@ -48,39 +49,44 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { - synchronized (mTasks) { - if (mTasks.contains(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); - mSyncQueue.runInSync(t -> { - // Reset several properties back to fullscreen (PiP, for example, leaves all these - // properties in a bad state). - t.setWindowCrop(leash, null); - t.setPosition(leash, 0, 0); - // TODO(shell-transitions): Eventually set everything in transition so there's no - // SF Transaction here. - if (!Transitions.ENABLE_SHELL_TRANSITIONS) { - t.setAlpha(leash, 1f); - t.setMatrix(leash, 1, 0, 0, 1); - t.show(leash); - } - }); + if (mLeashByTaskId.get(taskInfo.taskId) != null) { + throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId); } + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d", + taskInfo.taskId); + mLeashByTaskId.put(taskInfo.taskId, leash); + final Point positionInParent = taskInfo.positionInParent; + mSyncQueue.runInSync(t -> { + // Reset several properties back to fullscreen (PiP, for example, leaves all these + // properties in a bad state). + t.setWindowCrop(leash, null); + t.setPosition(leash, positionInParent.x, positionInParent.y); + // TODO(shell-transitions): Eventually set everything in transition so there's no + // SF Transaction here. + if (!Transitions.ENABLE_SHELL_TRANSITIONS) { + t.setAlpha(leash, 1f); + t.setMatrix(leash, 1, 0, 0, 1); + t.show(leash); + } + }); + } + + @Override + public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { + final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId); + final Point positionInParent = taskInfo.positionInParent; + mSyncQueue.runInSync(t -> t.setPosition(leash, positionInParent.x, positionInParent.y)); } @Override public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { - synchronized (mTasks) { - if (!mTasks.remove(taskInfo.taskId)) { - Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId); - return; - } - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d", - taskInfo.taskId); + if (mLeashByTaskId.get(taskInfo.taskId) == null) { + Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId); + return; } + mLeashByTaskId.remove(taskInfo.taskId); + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d", + taskInfo.taskId); } @Override @@ -88,7 +94,7 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { final String innerPrefix = prefix + " "; final String childPrefix = innerPrefix + " "; pw.println(prefix + this); - pw.println(innerPrefix + mTasks.size() + " Tasks"); + pw.println(innerPrefix + mLeashByTaskId.size() + " Tasks"); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java index 45948dd9e800..20850428d3bd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java @@ -16,12 +16,9 @@ package com.android.wm.shell; -import android.view.Gravity; - import com.android.wm.shell.apppairs.AppPairs; import com.android.wm.shell.common.annotations.ExternalThread; import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout; -import com.android.wm.shell.letterbox.LetterboxConfigController; import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.splitscreen.SplitScreen; @@ -42,7 +39,6 @@ public final class ShellCommandHandler { private final Optional<HideDisplayCutout> mHideDisplayCutout; private final ShellTaskOrganizer mShellTaskOrganizer; private final Optional<AppPairs> mAppPairsOptional; - private final LetterboxConfigController mLetterboxConfigController; public ShellCommandHandler( ShellTaskOrganizer shellTaskOrganizer, @@ -50,15 +46,13 @@ public final class ShellCommandHandler { Optional<Pip> pipOptional, Optional<OneHanded> oneHandedOptional, Optional<HideDisplayCutout> hideDisplayCutout, - Optional<AppPairs> appPairsOptional, - LetterboxConfigController letterboxConfigController) { + Optional<AppPairs> appPairsOptional) { mShellTaskOrganizer = shellTaskOrganizer; mSplitScreenOptional = splitScreenOptional; mPipOptional = pipOptional; mOneHandedOptional = oneHandedOptional; mHideDisplayCutout = hideDisplayCutout; mAppPairsOptional = appPairsOptional; - mLetterboxConfigController = letterboxConfigController; } /** Dumps WM Shell internal state. */ @@ -85,14 +79,6 @@ public final class ShellCommandHandler { return false; } switch (args[1]) { - case "set-letterbox-portrait-gravity": - return runSetLetterboxPortraitGravity(args, pw); - case "get-letterbox-portrait-gravity": - return runGetLetterboxPortraitGravity(pw); - case "set-letterbox-landscape-gravity": - return runSetLetterboxLandscapeGravity(args, pw); - case "get-letterbox-landscape-gravity": - return runGetLetterboxLandscapeGravity(pw); case "pair": return runPair(args, pw); case "unpair": @@ -104,92 +90,6 @@ public final class ShellCommandHandler { } } - private boolean runSetLetterboxPortraitGravity(String[] args, PrintWriter pw) { - if (args.length < 3) { - // First two arguments are "WMShell" and command name. - pw.println("Error: reset, TOP, CENTER or BOTTOM should be provided as an argument"); - return true; - } - switch (args[2]) { - case "reset": - mLetterboxConfigController.resetPortraitGravity(); - break; - case "TOP": - mLetterboxConfigController.setPortraitGravity(Gravity.TOP); - break; - case "CENTER": - mLetterboxConfigController.setPortraitGravity(Gravity.CENTER); - break; - case "BOTTOM": - mLetterboxConfigController.setPortraitGravity(Gravity.BOTTOM); - break; - default: - pw.println("Error: expected reset, TOP, CENTER or BOTTOM but got " + args[2]); - } - return true; - } - - private boolean runGetLetterboxPortraitGravity(PrintWriter pw) { - final int gravity = mLetterboxConfigController.getPortraitGravity(); - switch (gravity) { - case Gravity.TOP: - pw.println("TOP"); - break; - case Gravity.CENTER: - pw.println("CENTER"); - break; - case Gravity.BOTTOM: - pw.println("BOTTOM"); - break; - default: - throw new AssertionError("Unexpected gravity: " + gravity); - } - return true; - } - - private boolean runSetLetterboxLandscapeGravity(String[] args, PrintWriter pw) { - if (args.length < 3) { - // First two arguments are "WMShell" and command name. - pw.println("Error: reset, LEFT, CENTER or RIGHT should be provided as an argument"); - return false; - } - switch (args[2]) { - case "reset": - mLetterboxConfigController.resetLandscapeGravity(); - break; - case "LEFT": - mLetterboxConfigController.setLandscapeGravity(Gravity.LEFT); - break; - case "CENTER": - mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER); - break; - case "RIGHT": - mLetterboxConfigController.setLandscapeGravity(Gravity.RIGHT); - break; - default: - pw.println( - "Error: expected reset, LEFT, CENTER or RIGHT but got " + args[2]); - } - return true; - } - - private boolean runGetLetterboxLandscapeGravity(PrintWriter pw) { - final int gravity = mLetterboxConfigController.getLandscapeGravity(); - switch (gravity) { - case Gravity.LEFT: - pw.println("LEFT"); - break; - case Gravity.CENTER: - pw.println("CENTER"); - break; - case Gravity.RIGHT: - pw.println("RIGHT"); - break; - default: - throw new AssertionError("Unexpected gravity: " + gravity); - } - return true; - } private boolean runPair(String[] args, PrintWriter pw) { if (args.length < 4) { @@ -220,12 +120,6 @@ public final class ShellCommandHandler { pw.println(" Print this help text."); pw.println(" <no arguments provided>"); pw.println(" Dump Window Manager Shell internal state"); - pw.println(" set-letterbox-portrait-gravity [reset|TOP|CENTER|BOTTOM]"); - pw.println(" get-letterbox-portrait-gravity"); - pw.println(" Set, reset or print letterbox gravity for portrait screen mode."); - pw.println(" set-letterbox-landscape-gravity [reset|LEFT|CENTER|RIGHT]"); - pw.println(" get-letterbox-landscape-gravity"); - pw.println(" Set, reset or print letterbox gravity for landscape screen mode."); pw.println(" pair <taskId1> <taskId2>"); pw.println(" unpair <taskId>"); pw.println(" Pairs/unpairs tasks with given ids."); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java index 6c08079e586e..f8956030936c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java @@ -17,13 +17,11 @@ package com.android.wm.shell; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN; -import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_LETTERBOX; import com.android.wm.shell.apppairs.AppPairs; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.annotations.ExternalThread; import com.android.wm.shell.draganddrop.DragAndDropController; -import com.android.wm.shell.letterbox.LetterboxTaskListener; import com.android.wm.shell.splitscreen.SplitScreen; import java.util.Optional; @@ -38,7 +36,6 @@ public class ShellInit { private final ShellTaskOrganizer mShellTaskOrganizer; private final Optional<SplitScreen> mSplitScreenOptional; private final Optional<AppPairs> mAppPairsOptional; - private final LetterboxTaskListener mLetterboxTaskListener; private final FullscreenTaskListener mFullscreenTaskListener; private final Transitions mTransitions; @@ -47,7 +44,6 @@ public class ShellInit { ShellTaskOrganizer shellTaskOrganizer, Optional<SplitScreen> splitScreenOptional, Optional<AppPairs> appPairsOptional, - LetterboxTaskListener letterboxTaskListener, FullscreenTaskListener fullscreenTaskListener, Transitions transitions) { mDisplayImeController = displayImeController; @@ -55,7 +51,6 @@ public class ShellInit { mShellTaskOrganizer = shellTaskOrganizer; mSplitScreenOptional = splitScreenOptional; mAppPairsOptional = appPairsOptional; - mLetterboxTaskListener = letterboxTaskListener; mFullscreenTaskListener = fullscreenTaskListener; mTransitions = transitions; } @@ -66,8 +61,6 @@ public class ShellInit { mDisplayImeController.startMonitorDisplays(); mShellTaskOrganizer.addListenerForType( - mLetterboxTaskListener, TASK_LISTENER_TYPE_LETTERBOX); - mShellTaskOrganizer.addListenerForType( mFullscreenTaskListener, TASK_LISTENER_TYPE_FULLSCREEN); // Register the shell organizer mShellTaskOrganizer.registerOrganizer(); 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 62d265aab38f..10cec6d59cbe 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -62,14 +62,12 @@ public class ShellTaskOrganizer extends TaskOrganizer { public static final int TASK_LISTENER_TYPE_FULLSCREEN = -2; public static final int TASK_LISTENER_TYPE_MULTI_WINDOW = -3; public static final int TASK_LISTENER_TYPE_PIP = -4; - public static final int TASK_LISTENER_TYPE_LETTERBOX = -5; @IntDef(prefix = {"TASK_LISTENER_TYPE_"}, value = { TASK_LISTENER_TYPE_UNDEFINED, TASK_LISTENER_TYPE_FULLSCREEN, TASK_LISTENER_TYPE_MULTI_WINDOW, TASK_LISTENER_TYPE_PIP, - TASK_LISTENER_TYPE_LETTERBOX, }) public @interface TaskListenerType {} @@ -371,9 +369,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { static @TaskListenerType int taskInfoToTaskListenerType(RunningTaskInfo runningTaskInfo) { switch (runningTaskInfo.getWindowingMode()) { case WINDOWING_MODE_FULLSCREEN: - return runningTaskInfo.letterboxActivityBounds != null - ? TASK_LISTENER_TYPE_LETTERBOX - : TASK_LISTENER_TYPE_FULLSCREEN; + return TASK_LISTENER_TYPE_FULLSCREEN; case WINDOWING_MODE_MULTI_WINDOW: return TASK_LISTENER_TYPE_MULTI_WINDOW; case WINDOWING_MODE_PINNED: @@ -389,8 +385,6 @@ public class ShellTaskOrganizer extends TaskOrganizer { switch (type) { case TASK_LISTENER_TYPE_FULLSCREEN: return "TASK_LISTENER_TYPE_FULLSCREEN"; - case TASK_LISTENER_TYPE_LETTERBOX: - return "TASK_LISTENER_TYPE_LETTERBOX"; case TASK_LISTENER_TYPE_MULTI_WINDOW: return "TASK_LISTENER_TYPE_MULTI_WINDOW"; case TASK_LISTENER_TYPE_PIP: diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxConfigController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxConfigController.java deleted file mode 100644 index 0a549c6aa7d9..000000000000 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxConfigController.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2020 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.letterbox; - -import android.content.Context; -import android.view.Gravity; - -import com.android.wm.shell.R; - -/** - * Controls access to and overrides of resource config values used by {@link - * LetterboxTaskOrganizer}. - */ -public final class LetterboxConfigController { - - private final Context mContext; - - /** {@link Gravity} of letterboxed apps in portrait screen orientation. */ - private int mLetterboxPortraitGravity; - - /** {@link Gravity} of letterboxed apps in landscape screen orientation. */ - private int mLetterboxLandscapeGravity; - - public LetterboxConfigController(Context context) { - mContext = context; - mLetterboxPortraitGravity = - mContext.getResources().getInteger(R.integer.config_letterboxPortraitGravity); - mLetterboxLandscapeGravity = - mContext.getResources().getInteger(R.integer.config_letterboxLandscapeGravity); - } - - /** - * Overrides {@link Gravity} of letterboxed apps in portrait screen orientation. - * - * @throws IllegalArgumentException if gravity isn't equal to {@link Gravity#TOP}, {@link - * Gravity#CENTER} or {@link Gravity#BOTTOM}. - */ - public void setPortraitGravity(int gravity) { - if (gravity != Gravity.TOP && gravity != Gravity.CENTER && gravity != Gravity.BOTTOM) { - throw new IllegalArgumentException( - "Expected Gravity#TOP, Gravity#CENTER or Gravity#BOTTOM but got" - + gravity); - } - mLetterboxPortraitGravity = gravity; - } - - /** - * Resets {@link Gravity} of letterboxed apps in portrait screen orientation to {@link - * R.integer.config_letterboxPortraitGravity}. - */ - public void resetPortraitGravity() { - mLetterboxPortraitGravity = - mContext.getResources().getInteger(R.integer.config_letterboxPortraitGravity); - } - - /** - * Gets {@link Gravity} of letterboxed apps in portrait screen orientation. - */ - public int getPortraitGravity() { - return mLetterboxPortraitGravity; - } - - /** - * Overrides {@link Gravity} of letterboxed apps in landscape screen orientation. - * - * @throws IllegalArgumentException if gravity isn't equal to {@link Gravity#RIGHT}, {@link - * Gravity#CENTER} or {@link Gravity#LEFT}. - */ - public void setLandscapeGravity(int gravity) { - if (gravity != Gravity.LEFT && gravity != Gravity.CENTER && gravity != Gravity.RIGHT) { - throw new IllegalArgumentException( - "Expected Gravity#LEFT, Gravity#CENTER or Gravity#RIGHT but got" - + gravity); - } - mLetterboxLandscapeGravity = gravity; - } - - /** - * Resets {@link Gravity} of letterboxed apps in landscape screen orientation to {@link - * R.integer.config_letterboxLandscapeGravity}. - */ - public void resetLandscapeGravity() { - mLetterboxLandscapeGravity = - mContext.getResources().getInteger(R.integer.config_letterboxLandscapeGravity); - } - - /** - * Gets {@link Gravity} of letterboxed apps in landscape screen orientation. - */ - public int getLandscapeGravity() { - return mLetterboxLandscapeGravity; - } - -} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxTaskListener.java deleted file mode 100644 index 490ef3296be6..000000000000 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxTaskListener.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (C) 2020 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.letterbox; - -import android.app.ActivityManager; -import android.graphics.Insets; -import android.graphics.Point; -import android.graphics.Rect; -import android.util.Slog; -import android.util.SparseArray; -import android.view.Gravity; -import android.view.SurfaceControl; -import android.view.WindowInsets; -import android.view.WindowManager; - -import com.android.internal.protolog.common.ProtoLog; -import com.android.wm.shell.ShellTaskOrganizer; -import com.android.wm.shell.Transitions; -import com.android.wm.shell.common.SyncTransactionQueue; -import com.android.wm.shell.protolog.ShellProtoLogGroup; - -/** - * Organizes a task in {@link android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN} when - * it's presented in the letterbox mode either because orientations of a top activity and a device - * don't match or because a top activity is in a size compat mode. - */ -public class LetterboxTaskListener implements ShellTaskOrganizer.TaskListener { - private static final String TAG = "LetterboxTaskListener"; - - private final SyncTransactionQueue mSyncQueue; - private final LetterboxConfigController mLetterboxConfigController; - private final WindowManager mWindowManager; - private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>(); - - public LetterboxTaskListener( - SyncTransactionQueue syncQueue, - LetterboxConfigController letterboxConfigController, - WindowManager windowManager) { - mSyncQueue = syncQueue; - mLetterboxConfigController = letterboxConfigController; - mWindowManager = windowManager; - } - - @Override - public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { - if (mLeashByTaskId.get(taskInfo.taskId) != null) { - throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId); - } - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Appeared: #%d", - taskInfo.taskId); - mLeashByTaskId.put(taskInfo.taskId, leash); - Point positionInParent = new Point(); - Rect crop = new Rect(); - resolveTaskPositionAndCrop(taskInfo, positionInParent, crop); - mSyncQueue.runInSync(t -> { - setPositionAndWindowCrop(t, leash, positionInParent, crop); - if (!Transitions.ENABLE_SHELL_TRANSITIONS) { - t.setAlpha(leash, 1f); - t.setMatrix(leash, 1, 0, 0, 1); - t.show(leash); - } - }); - } - - @Override - public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { - if (mLeashByTaskId.get(taskInfo.taskId) == null) { - Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId); - return; - } - mLeashByTaskId.remove(taskInfo.taskId); - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Vanished: #%d", - taskInfo.taskId); - } - - @Override - public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Changed: #%d", - taskInfo.taskId); - final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId); - Point positionInParent = new Point(); - Rect crop = new Rect(); - resolveTaskPositionAndCrop(taskInfo, positionInParent, crop); - mSyncQueue.runInSync(t -> setPositionAndWindowCrop(t, leash, positionInParent, crop)); - } - - private static void setPositionAndWindowCrop( - SurfaceControl.Transaction transaction, - SurfaceControl leash, - final Point positionInParent, - final Rect crop) { - transaction.setPosition(leash, positionInParent.x, positionInParent.y); - transaction.setWindowCrop(leash, crop); - } - - // TODO(b/173440321): Correct presentation of letterboxed activities in One-handed mode. - private void resolveTaskPositionAndCrop( - ActivityManager.RunningTaskInfo taskInfo, - Point positionInParent, - Rect crop) { - // In screen coordinates - Rect parentBounds = new Rect(taskInfo.parentBounds); - // Intersect parent and max bounds. This is required for situations when parent bounds - // go beyond display bounds, for example, in One-handed mode. - final Rect maxBounds = taskInfo.getConfiguration().windowConfiguration.getMaxBounds(); - if (!parentBounds.intersect(maxBounds)) { - Slog.w(TAG, "Task parent and max bounds don't intersect: #" + taskInfo.taskId); - } - - // In screen coordinates - final Rect taskBounds = taskInfo.getConfiguration().windowConfiguration.getBounds(); - final Rect activityBounds = taskInfo.letterboxActivityBounds; - - Insets insets = getInsets(); - Rect displayBoundsWithInsets = - new Rect(mWindowManager.getMaximumWindowMetrics().getBounds()); - displayBoundsWithInsets.inset(insets); - - Rect taskBoundsWithInsets = new Rect(taskBounds); - taskBoundsWithInsets.intersect(displayBoundsWithInsets); - - Rect activityBoundsWithInsets = new Rect(activityBounds); - activityBoundsWithInsets.intersect(displayBoundsWithInsets); - - Rect parentBoundsWithInsets = new Rect(parentBounds); - parentBoundsWithInsets.intersect(displayBoundsWithInsets); - - // Crop need to be in the task coordinates. - crop.set(activityBoundsWithInsets); - crop.offset(-taskBounds.left, -taskBounds.top); - - // Account for insets since coordinates calculations below are done with them. - positionInParent.x = parentBoundsWithInsets.left - parentBounds.left - - (taskBoundsWithInsets.left - taskBounds.left); - positionInParent.y = parentBoundsWithInsets.top - parentBounds.top - - (taskBoundsWithInsets.top - taskBounds.top); - - // Calculating a position of task bounds (without insets) in parent coordinates (without - // insets) to align activity bounds (without insets) as requested in config. Activity - // accounts for insets that overlap with its bounds (this overlap can be partial) so - // ignoring overlap with insets when computing the position. Also, cropping unwanted insets - // while keeping the top one if the activity is aligned at the top of the window to show - // status bar decor view. - if (parentBounds.height() >= parentBounds.width()) { - final int gravity = mLetterboxConfigController.getPortraitGravity(); - // Center activity horizontally. - positionInParent.x += - (parentBoundsWithInsets.width() - activityBoundsWithInsets.width()) / 2 - + taskBoundsWithInsets.left - activityBoundsWithInsets.left; - switch (gravity) { - case Gravity.TOP: - positionInParent.y += taskBoundsWithInsets.top - activityBoundsWithInsets.top; - break; - case Gravity.CENTER: - positionInParent.y += - taskBoundsWithInsets.top - activityBoundsWithInsets.top - + (parentBoundsWithInsets.height() - - activityBoundsWithInsets.height()) / 2; - break; - case Gravity.BOTTOM: - positionInParent.y += - parentBoundsWithInsets.height() - activityBoundsWithInsets.bottom - + taskBoundsWithInsets.top; - break; - default: - throw new AssertionError( - "Unexpected portrait gravity " + gravity - + " for task: #" + taskInfo.taskId); - } - } else { - final int gravity = mLetterboxConfigController.getLandscapeGravity(); - // Align activity to the top. - positionInParent.y += taskBoundsWithInsets.top - activityBoundsWithInsets.top; - switch (gravity) { - case Gravity.LEFT: - positionInParent.x += taskBoundsWithInsets.left - activityBoundsWithInsets.left; - break; - case Gravity.CENTER: - positionInParent.x += - (parentBoundsWithInsets.width() - activityBoundsWithInsets.width()) / 2 - + taskBoundsWithInsets.left - activityBoundsWithInsets.left; - break; - case Gravity.RIGHT: - positionInParent.x += - parentBoundsWithInsets.width() - - activityBoundsWithInsets.right + taskBoundsWithInsets.left; - break; - default: - throw new AssertionError( - "Unexpected landscape gravity " + gravity - + " for task: #" + taskInfo.taskId); - } - } - - // New bounds of the activity after it's repositioned with required gravity. - Rect newActivityBounds = new Rect(activityBounds); - // Task's surfce will be repositioned to positionInParent together with the activity - // inside it so the new activity bounds are the original activity bounds offset by - // the task's offset. - newActivityBounds.offset( - positionInParent.x - taskBounds.left, positionInParent.y - taskBounds.top); - Rect newActivityBoundsWithInsets = new Rect(newActivityBounds); - newActivityBoundsWithInsets.intersect(displayBoundsWithInsets); - // Activity handles insets on its own (e.g. under status bar or navigation bar). - // crop that is calculated above crops all insets from an activity and below insets that - // can be shown are added back to the crop bounds (e.g. if activity is still shown at the - // top of the display then the top inset won't be cropped). - // After task's surface is repositioned, intersection between an activity and insets can - // change but if it doesn't, the activity should be shown under insets to maximize visible - // area. - // Also, an activity can use area under insets and insets shouldn't be cropped in this case - // regardless of a position on the screen. - final Rect activityInsetsFromCore = taskInfo.letterboxActivityInsets; - if (newActivityBounds.top - newActivityBoundsWithInsets.top - == activityBounds.top - activityBoundsWithInsets.top - // Check whether an activity is shown under inset. If it is, then the inset from - // WM Core and the inset computed here will be different because local insets - // doesn't take into account visibility of insets requested by the activity. - || activityBoundsWithInsets.top - activityBounds.top - != activityInsetsFromCore.top) { - crop.top -= activityBoundsWithInsets.top - activityBounds.top; - } - if (newActivityBounds.bottom - newActivityBoundsWithInsets.bottom - == activityBounds.bottom - activityBoundsWithInsets.bottom - || activityBounds.bottom - activityBoundsWithInsets.bottom - != activityInsetsFromCore.bottom) { - crop.bottom += activityBounds.bottom - activityBoundsWithInsets.bottom; - } - if (newActivityBounds.left - newActivityBoundsWithInsets.left - == activityBounds.left - activityBoundsWithInsets.left - || activityBoundsWithInsets.left - activityBounds.left - != activityInsetsFromCore.left) { - crop.left -= activityBoundsWithInsets.left - activityBounds.left; - } - if (newActivityBounds.right - newActivityBoundsWithInsets.right - == activityBounds.right - activityBoundsWithInsets.right - || activityBounds.right - activityBoundsWithInsets.right - != activityInsetsFromCore.right) { - crop.right += activityBounds.right - activityBoundsWithInsets.right; - } - } - - private Insets getInsets() { - return mWindowManager - .getMaximumWindowMetrics() - .getWindowInsets() - .getInsets( - WindowInsets.Type.navigationBars() - | WindowInsets.Type.statusBars() - | WindowInsets.Type.displayCutout()); - } - -} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java index 3ff750af7ec9..862776ec7df2 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java @@ -16,18 +16,14 @@ package com.android.wm.shell; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; -import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN; -import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_LETTERBOX; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -38,7 +34,6 @@ import static org.mockito.Mockito.verify; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.pm.ParceledListSlice; -import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; @@ -47,7 +42,6 @@ import android.window.ITaskOrganizer; import android.window.ITaskOrganizerController; import android.window.TaskAppearedInfo; -import androidx.annotation.Nullable; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; @@ -263,28 +257,6 @@ public class ShellTaskOrganizerTests { assertTrue(mwListener.appeared.contains(task2)); } - @Test - public void testTaskInfoToTaskListenerType_whenLetterboxBoundsPassed_returnsLetterboxType() { - RunningTaskInfo taskInfo = createTaskInfo( - /* taskId */ 1, - WINDOWING_MODE_FULLSCREEN, - /* letterboxActivityBounds */ new Rect(1, 1, 1, 1)); - - assertEquals( - ShellTaskOrganizer.taskInfoToTaskListenerType(taskInfo), - TASK_LISTENER_TYPE_LETTERBOX); - } - - @Test - public void testTaskInfoToTaskListenerType_whenLetterboxBoundsIsNull_returnsFullscreenType() { - RunningTaskInfo taskInfo = createTaskInfo( - /* taskId */ 1, WINDOWING_MODE_FULLSCREEN, /* letterboxActivityBounds */ null); - - assertEquals( - ShellTaskOrganizer.taskInfoToTaskListenerType(taskInfo), - TASK_LISTENER_TYPE_FULLSCREEN); - } - private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode) { RunningTaskInfo taskInfo = new RunningTaskInfo(); taskInfo.taskId = taskId; @@ -292,12 +264,4 @@ public class ShellTaskOrganizerTests { return taskInfo; } - private static RunningTaskInfo createTaskInfo( - int taskId, int windowingMode, @Nullable Rect letterboxActivityBounds) { - RunningTaskInfo taskInfo = new RunningTaskInfo(); - taskInfo.taskId = taskId; - taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode); - taskInfo.letterboxActivityBounds = Rect.copyOrNull(letterboxActivityBounds); - return taskInfo; - } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxConfigControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxConfigControllerTest.java deleted file mode 100644 index 29233366d4f3..000000000000 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxConfigControllerTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2020 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.letterbox; - -import static org.junit.Assert.assertEquals; - -import android.view.Gravity; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.wm.shell.R; -import com.android.wm.shell.ShellTestCase; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Tests for {@link LetterboxConfigController}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public final class LetterboxConfigControllerTest extends ShellTestCase { - - private LetterboxConfigController mLetterboxConfigController; - - @Before - public void setUp() { - mLetterboxConfigController = new LetterboxConfigController(getContext()); - } - - @Test - public void testGetPortraitGravity_noOverrides_returnConfigValue() { - assertEquals( - mLetterboxConfigController.getPortraitGravity(), - getContext().getResources().getInteger(R.integer.config_letterboxPortraitGravity)); - } - - @Test - public void testGetLandscapeGravity_noOverrides_returnConfigValue() { - assertEquals( - mLetterboxConfigController.getLandscapeGravity(), - getContext().getResources().getInteger(R.integer.config_letterboxLandscapeGravity)); - } - - @Test - public void testSetPortraitGravity_validValue_savesValue() { - mLetterboxConfigController.setPortraitGravity(Gravity.BOTTOM); - assertEquals(mLetterboxConfigController.getPortraitGravity(), Gravity.BOTTOM); - - mLetterboxConfigController.setPortraitGravity(Gravity.CENTER); - assertEquals(mLetterboxConfigController.getPortraitGravity(), Gravity.CENTER); - - mLetterboxConfigController.setPortraitGravity(Gravity.TOP); - assertEquals(mLetterboxConfigController.getPortraitGravity(), Gravity.TOP); - } - - @Test - public void testSetLandscapeGravity_validValue_savesValue() { - mLetterboxConfigController.setLandscapeGravity(Gravity.LEFT); - assertEquals(mLetterboxConfigController.getLandscapeGravity(), Gravity.LEFT); - - mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER); - assertEquals(mLetterboxConfigController.getLandscapeGravity(), Gravity.CENTER); - - mLetterboxConfigController.setLandscapeGravity(Gravity.RIGHT); - assertEquals(mLetterboxConfigController.getLandscapeGravity(), Gravity.RIGHT); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetPortraitGravity_invalidValue_throwsException() { - mLetterboxConfigController.setPortraitGravity(Gravity.RIGHT); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetLandscapeGravity_invalidValue_throwsException() { - mLetterboxConfigController.setLandscapeGravity(Gravity.TOP); - } - - @Test - public void testResetPortraitGravity() { - int defaultGravity = - getContext().getResources().getInteger(R.integer.config_letterboxPortraitGravity); - - mLetterboxConfigController.setPortraitGravity(Gravity.BOTTOM); - mLetterboxConfigController.resetPortraitGravity(); - assertEquals(mLetterboxConfigController.getPortraitGravity(), defaultGravity); - - mLetterboxConfigController.setPortraitGravity(Gravity.CENTER); - mLetterboxConfigController.resetPortraitGravity(); - assertEquals(mLetterboxConfigController.getPortraitGravity(), defaultGravity); - - mLetterboxConfigController.setPortraitGravity(Gravity.TOP); - mLetterboxConfigController.resetPortraitGravity(); - assertEquals(mLetterboxConfigController.getPortraitGravity(), defaultGravity); - } - - @Test - public void testResetLandscapeGravity() { - int defaultGravity = - getContext().getResources().getInteger(R.integer.config_letterboxLandscapeGravity); - - mLetterboxConfigController.setLandscapeGravity(Gravity.RIGHT); - mLetterboxConfigController.resetLandscapeGravity(); - assertEquals(mLetterboxConfigController.getLandscapeGravity(), defaultGravity); - - mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER); - mLetterboxConfigController.resetLandscapeGravity(); - assertEquals(mLetterboxConfigController.getLandscapeGravity(), defaultGravity); - - mLetterboxConfigController.setLandscapeGravity(Gravity.LEFT); - mLetterboxConfigController.resetLandscapeGravity(); - assertEquals(mLetterboxConfigController.getLandscapeGravity(), defaultGravity); - } - -} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxTaskListenerTest.java deleted file mode 100644 index 5cbc7d927d61..000000000000 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxTaskListenerTest.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) 2020 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.letterbox; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; - -import android.app.ActivityManager.RunningTaskInfo; -import android.graphics.Insets; -import android.graphics.Rect; -import android.os.Handler; -import android.os.Looper; -import android.view.Gravity; -import android.view.SurfaceControl; -import android.view.WindowInsets; -import android.view.WindowManager; -import android.view.WindowMetrics; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.wm.shell.ShellTestCase; -import com.android.wm.shell.common.SyncTransactionQueue; -import com.android.wm.shell.common.TransactionPool; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -/** - * Tests for {@link LetterboxTaskListener}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public final class LetterboxTaskListenerTest extends ShellTestCase { - - @Mock private SurfaceControl mLeash; - @Mock private SurfaceControl.Transaction mTransaction; - @Mock private WindowManager mWindowManager; - @Mock private WindowMetrics mWindowMetrics; - @Mock private WindowInsets mWindowInsets; - private LetterboxTaskListener mLetterboxTaskListener; - private LetterboxConfigController mLetterboxConfigController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mLetterboxConfigController = new LetterboxConfigController(getContext()); - mLetterboxTaskListener = new LetterboxTaskListener( - new SyncTransactionQueue( - new TransactionPool() { - @Override - public SurfaceControl.Transaction acquire() { - return mTransaction; - } - - @Override - public void release(SurfaceControl.Transaction t) { - } - }, - new Handler(Looper.getMainLooper())), - mLetterboxConfigController, - mWindowManager); - - when(mWindowManager.getMaximumWindowMetrics()).thenReturn(mWindowMetrics); - when(mWindowMetrics.getWindowInsets()).thenReturn(mWindowInsets); - } - - @Test - public void testOnTaskInfoChanged_updatesPositionAndCrop() { - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds - Insets.NONE); - - mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER); - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 200, 100), - /* activityBounds */ new Rect(75, 0, 125, 75), - /* taskBounds */ new Rect(50, 0, 125, 100), - /* activityInsets */ new Rect(0, 0, 0, 0)), - mLeash); - - // Task doesn't need to repositioned - verifySetPosition(50, 0); - // Should return activity coordinates offset by task coordinates - verifySetWindowCrop(new Rect(25, 0, 75, 75)); - - mLetterboxTaskListener.onTaskInfoChanged( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 200, 100), - // Activity is offset by 25 to the left - /* activityBounds */ new Rect(50, 0, 100, 75), - /* taskBounds */ new Rect(50, 0, 125, 100), - /* activityInsets */ new Rect(0, 0, 0, 0))); - - // Task needs to be repositioned by 25 to the left - verifySetPosition(75, 0); - // Should return activity coordinates offset by task coordinates - verifySetWindowCrop(new Rect(0, 0, 50, 75)); - } - - @Test - public void testOnTaskInfoAppeared_landscapeWithLeftGravity() { - mLetterboxConfigController.setLandscapeGravity(Gravity.LEFT); - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds - Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 10)); - - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 200, 100), - /* activityBounds */ new Rect(150, 0, 200, 75), - /* taskBounds */ new Rect(125, 0, 200, 100), - /* activityInsets */ new Rect(0, 10, 10, 0)), - mLeash); - - verifySetPosition(-15, 0); - // Should return activity coordinates offset by task coordinates minus unwanted right inset - verifySetWindowCrop(new Rect(25, 0, 65, 75)); - } - - @Test - public void testOnTaskInfoAppeared_landscapeWithCenterGravity() { - mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER); - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds - Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 10)); - - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 200, 100), - /* activityBounds */ new Rect(150, 0, 200, 75), - /* taskBounds */ new Rect(125, 0, 200, 100), - /* activityInsets */ new Rect(0, 10, 10, 0)), - mLeash); - - verifySetPosition(55, 0); - // Should return activity coordinates offset by task coordinates minus unwanted right inset - verifySetWindowCrop(new Rect(25, 0, 65, 75)); - } - - @Test - public void testOnTaskInfoAppeared_landscapeWithRightGravity() { - mLetterboxConfigController.setLandscapeGravity(Gravity.RIGHT); - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds - Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 10)); - - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 200, 100), - /* activityBounds */ new Rect(50, 0, 100, 75), - /* taskBounds */ new Rect(25, 0, 100, 100), - /* activityInsets */ new Rect(0, 10, 10, 0)), - mLeash); - - verifySetPosition(115, 0); - // Should return activity coordinates offset by task coordinates - verifySetWindowCrop(new Rect(25, 0, 75, 75)); - } - - @Test - public void testOnTaskInfoAppeared_portraitWithTopGravity() { - mLetterboxConfigController.setPortraitGravity(Gravity.TOP); - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds - Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 20)); - - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 100, 150), - /* activityBounds */ new Rect(0, 75, 50, 125), - /* taskBounds */ new Rect(0, 50, 100, 125), - /* activityInsets */ new Rect(10, 0, 0, 0)), - mLeash); - - verifySetPosition(20, -15); - // Should return activity coordinates offset by task coordinates minus unwanted left inset - verifySetWindowCrop(new Rect(10, 25, 50, 75)); - } - - @Test - public void testOnTaskInfoAppeared_portraitWithCenterGravity() { - mLetterboxConfigController.setPortraitGravity(Gravity.CENTER); - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds - Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 20)); - - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 100, 150), - /* activityBounds */ new Rect(0, 75, 50, 125), - /* taskBounds */ new Rect(0, 50, 100, 125), - /* activityInsets */ new Rect(10, 0, 0, 0)), - mLeash); - - verifySetPosition(20, 20); - // Should return activity coordinates offset by task coordinates minus unwanted left inset - verifySetWindowCrop(new Rect(10, 25, 50, 75)); - } - - @Test - public void testOnTaskInfoAppeared_portraitWithCenterGravity_visibleLeftInset() { - mLetterboxConfigController.setPortraitGravity(Gravity.CENTER); - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds - Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 20)); - - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 100, 150), - /* activityBounds */ new Rect(0, 75, 50, 125), - /* taskBounds */ new Rect(0, 50, 100, 125), - // Activity is drawn under the left inset. - /* activityInsets */ new Rect(0, 0, 0, 0)), - mLeash); - - verifySetPosition(20, 20); - // Should return activity coordinates offset by task coordinates - verifySetWindowCrop(new Rect(0, 25, 50, 75)); - } - - @Test - public void testOnTaskInfoAppeared_portraitWithBottomGravity() { - mLetterboxConfigController.setPortraitGravity(Gravity.BOTTOM); - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds - Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 20)); - - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 100, 150), - /* activityBounds */ new Rect(0, 75, 50, 125), - /* taskBounds */ new Rect(0, 50, 100, 125), - /* activityInsets */ new Rect(10, 0, 0, 0)), - mLeash); - - verifySetPosition(20, 55); - // Should return activity coordinates offset by task coordinates minus unwanted left inset - verifySetWindowCrop(new Rect(10, 25, 50, 75)); - } - - @Test - public void testOnTaskInfoAppeared_partlyOverlapsWithAllInsets() { - mLetterboxConfigController.setPortraitGravity(Gravity.TOP); - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 200, 125), // equal to parent bounds - Insets.of(/* left= */ 25, /* top= */ 25, /* right= */ 35, /* bottom= */ 15)); - - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 200, 125), // equal to parent bounds - /* parentBounds */ new Rect(0, 0, 200, 125), - /* activityBounds */ new Rect(15, 0, 175, 120), - /* taskBounds */ new Rect(0, 0, 200, 125), - /* activityInsets */ new Rect(10, 25, 10, 10)), // equal to parent bounds - mLeash); - - // Activity fully covers parent bounds with insets so doesn't need to be moved. - verifySetPosition(0, 0); - // Should return activity coordinates offset by task coordinates - verifySetWindowCrop(new Rect(15, 0, 175, 120)); - } - - @Test - public void testOnTaskInfoAppeared_parentShiftedLikeInOneHandedMode() { - mLetterboxConfigController.setPortraitGravity(Gravity.TOP); - setWindowBoundsAndInsets( - /* windowBounds= */ new Rect(0, 0, 100, 150), - Insets.of(/* left= */ 0, /* top= */ 10, /* right= */ 0, /* bottom= */ 0)); - - mLetterboxTaskListener.onTaskAppeared( - createTaskInfo( - /* taskId */ 1, - /* maxBounds= */ new Rect(0, 0, 100, 150), - /* parentBounds */ new Rect(0, 75, 100, 225), - /* activityBounds */ new Rect(25, 75, 75, 125), - /* taskBounds */ new Rect(0, 75, 100, 125), - /* activityInsets */ new Rect(10, 0, 0, 0)), - mLeash); - - verifySetPosition(0, 0); - verifySetWindowCrop(new Rect(25, 0, 75, 50)); - } - - @Test(expected = IllegalStateException.class) - public void testOnTaskAppeared_calledSecondTimeWithSameTaskId_throwsException() { - setWindowBoundsAndInsets(new Rect(), Insets.NONE); - RunningTaskInfo taskInfo = - createTaskInfo(/* taskId */ 1, new Rect(), new Rect(), new Rect(), new Rect(), - new Rect()); - mLetterboxTaskListener.onTaskAppeared(taskInfo, mLeash); - mLetterboxTaskListener.onTaskAppeared(taskInfo, mLeash); - } - - private void setWindowBoundsAndInsets(Rect windowBounds, Insets insets) { - when(mWindowMetrics.getBounds()).thenReturn(windowBounds); - when(mWindowInsets.getInsets(anyInt())).thenReturn(insets); - } - - private void verifySetPosition(int x, int y) { - verify(mTransaction).setPosition(eq(mLeash), eq((float) x), eq((float) y)); - } - - private void verifySetWindowCrop(final Rect crop) { - // Should return activty coordinates offset by task coordinates - verify(mTransaction).setWindowCrop(eq(mLeash), eq(crop)); - } - - private static RunningTaskInfo createTaskInfo( - int taskId, - final Rect maxBounds, - final Rect parentBounds, - final Rect activityBounds, - final Rect taskBounds, - final Rect activityInsets) { - RunningTaskInfo taskInfo = new RunningTaskInfo(); - taskInfo.taskId = taskId; - taskInfo.configuration.windowConfiguration.setMaxBounds(maxBounds); - taskInfo.parentBounds = parentBounds; - taskInfo.configuration.windowConfiguration.setBounds(taskBounds); - taskInfo.letterboxActivityBounds = Rect.copyOrNull(activityBounds); - taskInfo.letterboxActivityInsets = Rect.copyOrNull(activityInsets); - - return taskInfo; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index 654e92270c9a..ee58947a691c 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -57,8 +57,6 @@ import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout; import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController; -import com.android.wm.shell.letterbox.LetterboxConfigController; -import com.android.wm.shell.letterbox.LetterboxTaskListener; import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.pip.Pip; @@ -173,7 +171,6 @@ public abstract class WMShellBaseModule { ShellTaskOrganizer shellTaskOrganizer, Optional<SplitScreen> splitScreenOptional, Optional<AppPairs> appPairsOptional, - LetterboxTaskListener letterboxTaskListener, FullscreenTaskListener fullscreenTaskListener, Transitions transitions) { return new ShellInit(displayImeController, @@ -181,7 +178,6 @@ public abstract class WMShellBaseModule { shellTaskOrganizer, splitScreenOptional, appPairsOptional, - letterboxTaskListener, fullscreenTaskListener, transitions); } @@ -198,11 +194,9 @@ public abstract class WMShellBaseModule { Optional<Pip> pipOptional, Optional<OneHanded> oneHandedOptional, Optional<HideDisplayCutout> hideDisplayCutout, - Optional<AppPairs> appPairsOptional, - LetterboxConfigController letterboxConfigController) { + Optional<AppPairs> appPairsOptional) { return Optional.of(new ShellCommandHandler(shellTaskOrganizer, splitScreenOptional, - pipOptional, oneHandedOptional, hideDisplayCutout, appPairsOptional, - letterboxConfigController)); + pipOptional, oneHandedOptional, hideDisplayCutout, appPairsOptional)); } @WMSingleton @@ -338,21 +332,6 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides - static LetterboxTaskListener provideLetterboxTaskListener( - SyncTransactionQueue syncQueue, - LetterboxConfigController letterboxConfigController, - WindowManager windowManager) { - return new LetterboxTaskListener(syncQueue, letterboxConfigController, windowManager); - } - - @WMSingleton - @Provides - static LetterboxConfigController provideLetterboxConfigController(Context context) { - return new LetterboxConfigController(context); - } - - @WMSingleton - @Provides static Transitions provideTransitions(ShellTaskOrganizer organizer, TransactionPool pool, @ShellMainThread ShellExecutor mainExecutor, @ShellAnimationThread ShellExecutor animExecutor) { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 5daf1c4679be..4c18310df226 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1366,19 +1366,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } else if (mLetterbox != null) { mLetterbox.hide(); } - maybeUpdateLetterboxInTaskOrganizer(w); - } - - private void maybeUpdateLetterboxInTaskOrganizer(WindowState w) { - boolean isLetterboxed = w.isLetterboxedAppWindow() && fillsParent(); - if (!isLetterboxed) { - task.maybeUpdateLetterboxInTaskOrganizer( - this, /* activityBounds= */ null, /* activityInsets= */ null); - return; - } - final Rect insets = w.getInsetsStateWithVisibilityOverride().calculateInsets( - getBounds(), Type.systemBars(), false /* ignoreVisibility */); - task.maybeUpdateLetterboxInTaskOrganizer(this, getBounds(), insets); } void updateLetterboxSurface(WindowState winHint) { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index c4be680a1716..69723ff99d06 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -514,16 +514,6 @@ class Task extends WindowContainer<WindowContainer> { // {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag of the root activity. boolean mSupportsPictureInPicture; - // Activity bounds if this task or its top activity is presented in letterbox mode and - // {@code null} otherwise. - @Nullable - private Rect mLetterboxActivityBounds; - - // Activity insets if this task or its top activity is presented in letterbox mode and - // {@code null} otherwise. - @Nullable - private Rect mLetterboxActivityInsets; - // Whether the task is currently being drag-resized private boolean mDragResizing; private int mDragResizeMode; @@ -4116,14 +4106,8 @@ class Task extends WindowContainer<WindowContainer> { info.resizeMode = top != null ? top.mResizeMode : mResizeMode; info.topActivityType = top.getActivityType(); info.isResizeable = isResizeable(); - // Don't query getTopNonFinishingActivity().getBounds() directly because when fillTaskInfo - // is triggered for the first time after activities change, getBounds() may return non final - // bounds, e.g. fullscreen bounds instead of letterboxed bounds. To work around this, - // assigning bounds from ActivityRecord#layoutLetterbox when they are ready. - info.letterboxActivityBounds = Rect.copyOrNull(mLetterboxActivityBounds); - info.letterboxActivityInsets = Rect.copyOrNull(mLetterboxActivityInsets); + info.positionInParent = getRelativePosition(); - info.parentBounds = getParentBounds(); info.pictureInPictureParams = getPictureInPictureParams(top); info.topActivityInfo = mReuseActivitiesReport.top != null @@ -4152,27 +4136,6 @@ class Task extends WindowContainer<WindowContainer> { ? null : new PictureInPictureParams(rootActivity.pictureInPictureArgs); } - void maybeUpdateLetterboxInTaskOrganizer( - ActivityRecord activityRecord, - @Nullable Rect activityBounds, - @Nullable Rect activityInsets) { - if (isOrganized() - && mReuseActivitiesReport.top == activityRecord - // Want to force update only if letterbox bounds have changed. - && (!Objects.equals(mLetterboxActivityBounds, activityBounds) - || !Objects.equals(mLetterboxActivityInsets, activityInsets))) { - mLetterboxActivityBounds = Rect.copyOrNull(activityBounds); - mLetterboxActivityInsets = Rect.copyOrNull(activityInsets); - // Forcing update to reduce visual jank during the transition. - dispatchTaskInfoChangedIfNeeded(true /* force */); - } - } - - private Rect getParentBounds() { - final WindowContainer parent = getParent(); - return parent != null ? new Rect(parent.getBounds()) : new Rect(); - } - /** * Returns a {@link TaskInfo} with information from this task. */ |