Loading libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +34 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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. Loading @@ -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; } Loading @@ -80,6 +82,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 + " "; Loading @@ -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); } } services/core/java/com/android/server/wm/ActivityRecord.java +27 −13 Original line number Diff line number Diff line Loading @@ -6406,6 +6406,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLastReportedConfiguration.setConfiguration(global, override); } boolean hasCompatDisplayInsets() { return mCompatDisplayInsets != null; } /** * @return {@code true} if this activity is in size compatibility mode that uses the different * density than its parent or its bounds don't fit in parent naturally. Loading Loading @@ -6544,7 +6548,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mSizeCompatScale = 1f; mSizeCompatBounds = null; mCompatDisplayInsets = null; onRequestedOverrideConfigurationChanged(EMPTY); // Recompute from Task because letterbox can also happen on Task level. task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration()); } @Override Loading Loading @@ -6653,9 +6659,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ? requestedOrientation : newParentConfiguration.orientation; int rotation = newParentConfiguration.windowConfiguration.getRotation(); final boolean canChangeOrientation = handlesOrientationChangeFromDescendant(); if (canChangeOrientation && !mCompatDisplayInsets.mIsFloating) { // Use parent rotation because the original display can rotate by requested orientation. final boolean isFixedToUserRotation = mDisplayContent == null || mDisplayContent.getDisplayRotation().isFixedToUserRotation(); if (!isFixedToUserRotation && !mCompatDisplayInsets.mIsFloating) { // Use parent rotation because the original display can be rotated. resolvedConfig.windowConfiguration.setRotation(rotation); } else { final int overrideRotation = resolvedConfig.windowConfiguration.getRotation(); Loading @@ -6671,7 +6678,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final Rect containingAppBounds = new Rect(); final Rect containingBounds = mTmpBounds; mCompatDisplayInsets.getContainerBounds(containingAppBounds, containingBounds, rotation, orientation, orientationRequested, canChangeOrientation); orientation, orientationRequested, isFixedToUserRotation); resolvedBounds.set(containingBounds); // The size of floating task is fixed (only swap), so the aspect ratio is already correct. if (!mCompatDisplayInsets.mIsFloating) { Loading Loading @@ -7740,7 +7747,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final Rect[] mStableInsets = new Rect[4]; /** Constructs the environment to simulate the bounds behavior of the given container. */ CompatDisplayInsets(DisplayContent display, WindowContainer container) { CompatDisplayInsets(DisplayContent display, ActivityRecord container) { mIsFloating = container.getWindowConfiguration().tasksAreFloating(); if (mIsFloating) { final Rect containerBounds = container.getWindowConfiguration().getBounds(); Loading @@ -7756,16 +7763,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } // If the activity is not floating, assume it fills the display. if (container.getTask().isTaskLetterboxed()) { // For apps in Task letterbox, it should fill the task bounds. final Rect taskBounds = container.getTask().getBounds(); mWidth = taskBounds.width(); mHeight = taskBounds.height(); } else { // If the activity is not floating nor letterboxed, assume it fills the display. mWidth = display.mBaseDisplayWidth; mHeight = display.mBaseDisplayHeight; } final DisplayPolicy policy = display.getDisplayPolicy(); for (int rotation = 0; rotation < 4; rotation++) { mNonDecorInsets[rotation] = new Rect(); mStableInsets[rotation] = new Rect(); final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int dw = rotated ? mHeight : mWidth; final int dh = rotated ? mWidth : mHeight; final int dw = rotated ? display.mBaseDisplayHeight : display.mBaseDisplayWidth; final int dh = rotated ? display.mBaseDisplayWidth : display.mBaseDisplayHeight; final DisplayCutout cutout = display.calculateDisplayCutoutForRotation(rotation) .getDisplayCutout(); policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]); Loading @@ -7791,7 +7805,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** Gets the horizontal centered container bounds for size compatibility mode. */ void getContainerBounds(Rect outAppBounds, Rect outBounds, int rotation, int orientation, boolean orientationRequested, boolean canChangeOrientation) { boolean orientationRequested, boolean isFixedToUserRotation) { getFrameByOrientation(outBounds, orientation); if (mIsFloating) { outAppBounds.set(outBounds); Loading @@ -7804,7 +7818,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean isOrientationMismatched = ((outBounds.width() > outBounds.height()) != (dW > dH)); if (isOrientationMismatched && !canChangeOrientation && orientationRequested) { if (isOrientationMismatched && isFixedToUserRotation && orientationRequested) { // The orientation is mismatched but the display cannot rotate. The bounds will fit // to the short side of container. if (orientation == ORIENTATION_LANDSCAPE) { Loading services/core/java/com/android/server/wm/DisplayArea.java +5 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,11 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { return super.getOrientation(candidate); } @Override boolean handlesOrientationChangeFromDescendant() { return !mIgnoreOrientationRequest && super.handlesOrientationChangeFromDescendant(); } /** * Sets whether this {@link DisplayArea} should ignore fixed-orientation request from apps and * windows below it. Loading services/core/java/com/android/server/wm/DisplayContent.java +3 −4 Original line number Diff line number Diff line Loading @@ -109,7 +109,6 @@ import static com.android.server.wm.DisplayContentProto.OPENING_APPS; import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY; import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA; import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION; import static com.android.server.wm.DisplayContentProto.SINGLE_TASK_INSTANCE; import static com.android.server.wm.Task.ActivityState.RESUMED; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; Loading Loading @@ -1310,7 +1309,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // If display rotation class tells us that it doesn't consider app requested orientation, // this display won't rotate just because of an app changes its requested orientation. Thus // it indicates that this display chooses not to handle this request. final boolean handled = getDisplayRotation().respectAppRequestedOrientation(); final boolean handled = handlesOrientationChangeFromDescendant(); if (config == null) { return handled; } Loading @@ -1334,7 +1333,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override boolean handlesOrientationChangeFromDescendant() { return getDisplayRotation().respectAppRequestedOrientation(); return !mIgnoreOrientationRequest && !getDisplayRotation().isFixedToUserRotation(); } /** Loading Loading @@ -2346,7 +2345,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override int getOrientation() { mLastOrientationSource = null; if (mIgnoreOrientationRequest) { if (!handlesOrientationChangeFromDescendant()) { // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation ProtoLog.v(WM_DEBUG_ORIENTATION, "Display id=%d is ignoring all orientation requests, return %d", Loading services/core/java/com/android/server/wm/DisplayRotation.java +0 −9 Original line number Diff line number Diff line Loading @@ -857,15 +857,6 @@ public class DisplayRotation { return mFixedToUserRotation; } /** * Returns {@code true} if this display rotation takes app requested orientation into * consideration; {@code false} otherwise. For the time being the only case where this is {@code * false} is when {@link #isFixedToUserRotation()} is {@code true}. */ boolean respectAppRequestedOrientation() { return !isFixedToUserRotation(); } public int getLandscapeRotation() { return mLandscapeRotation; } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +34 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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. Loading @@ -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; } Loading @@ -80,6 +82,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 + " "; Loading @@ -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); } }
services/core/java/com/android/server/wm/ActivityRecord.java +27 −13 Original line number Diff line number Diff line Loading @@ -6406,6 +6406,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLastReportedConfiguration.setConfiguration(global, override); } boolean hasCompatDisplayInsets() { return mCompatDisplayInsets != null; } /** * @return {@code true} if this activity is in size compatibility mode that uses the different * density than its parent or its bounds don't fit in parent naturally. Loading Loading @@ -6544,7 +6548,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mSizeCompatScale = 1f; mSizeCompatBounds = null; mCompatDisplayInsets = null; onRequestedOverrideConfigurationChanged(EMPTY); // Recompute from Task because letterbox can also happen on Task level. task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration()); } @Override Loading Loading @@ -6653,9 +6659,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ? requestedOrientation : newParentConfiguration.orientation; int rotation = newParentConfiguration.windowConfiguration.getRotation(); final boolean canChangeOrientation = handlesOrientationChangeFromDescendant(); if (canChangeOrientation && !mCompatDisplayInsets.mIsFloating) { // Use parent rotation because the original display can rotate by requested orientation. final boolean isFixedToUserRotation = mDisplayContent == null || mDisplayContent.getDisplayRotation().isFixedToUserRotation(); if (!isFixedToUserRotation && !mCompatDisplayInsets.mIsFloating) { // Use parent rotation because the original display can be rotated. resolvedConfig.windowConfiguration.setRotation(rotation); } else { final int overrideRotation = resolvedConfig.windowConfiguration.getRotation(); Loading @@ -6671,7 +6678,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final Rect containingAppBounds = new Rect(); final Rect containingBounds = mTmpBounds; mCompatDisplayInsets.getContainerBounds(containingAppBounds, containingBounds, rotation, orientation, orientationRequested, canChangeOrientation); orientation, orientationRequested, isFixedToUserRotation); resolvedBounds.set(containingBounds); // The size of floating task is fixed (only swap), so the aspect ratio is already correct. if (!mCompatDisplayInsets.mIsFloating) { Loading Loading @@ -7740,7 +7747,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final Rect[] mStableInsets = new Rect[4]; /** Constructs the environment to simulate the bounds behavior of the given container. */ CompatDisplayInsets(DisplayContent display, WindowContainer container) { CompatDisplayInsets(DisplayContent display, ActivityRecord container) { mIsFloating = container.getWindowConfiguration().tasksAreFloating(); if (mIsFloating) { final Rect containerBounds = container.getWindowConfiguration().getBounds(); Loading @@ -7756,16 +7763,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } // If the activity is not floating, assume it fills the display. if (container.getTask().isTaskLetterboxed()) { // For apps in Task letterbox, it should fill the task bounds. final Rect taskBounds = container.getTask().getBounds(); mWidth = taskBounds.width(); mHeight = taskBounds.height(); } else { // If the activity is not floating nor letterboxed, assume it fills the display. mWidth = display.mBaseDisplayWidth; mHeight = display.mBaseDisplayHeight; } final DisplayPolicy policy = display.getDisplayPolicy(); for (int rotation = 0; rotation < 4; rotation++) { mNonDecorInsets[rotation] = new Rect(); mStableInsets[rotation] = new Rect(); final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int dw = rotated ? mHeight : mWidth; final int dh = rotated ? mWidth : mHeight; final int dw = rotated ? display.mBaseDisplayHeight : display.mBaseDisplayWidth; final int dh = rotated ? display.mBaseDisplayWidth : display.mBaseDisplayHeight; final DisplayCutout cutout = display.calculateDisplayCutoutForRotation(rotation) .getDisplayCutout(); policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]); Loading @@ -7791,7 +7805,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** Gets the horizontal centered container bounds for size compatibility mode. */ void getContainerBounds(Rect outAppBounds, Rect outBounds, int rotation, int orientation, boolean orientationRequested, boolean canChangeOrientation) { boolean orientationRequested, boolean isFixedToUserRotation) { getFrameByOrientation(outBounds, orientation); if (mIsFloating) { outAppBounds.set(outBounds); Loading @@ -7804,7 +7818,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean isOrientationMismatched = ((outBounds.width() > outBounds.height()) != (dW > dH)); if (isOrientationMismatched && !canChangeOrientation && orientationRequested) { if (isOrientationMismatched && isFixedToUserRotation && orientationRequested) { // The orientation is mismatched but the display cannot rotate. The bounds will fit // to the short side of container. if (orientation == ORIENTATION_LANDSCAPE) { Loading
services/core/java/com/android/server/wm/DisplayArea.java +5 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,11 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { return super.getOrientation(candidate); } @Override boolean handlesOrientationChangeFromDescendant() { return !mIgnoreOrientationRequest && super.handlesOrientationChangeFromDescendant(); } /** * Sets whether this {@link DisplayArea} should ignore fixed-orientation request from apps and * windows below it. Loading
services/core/java/com/android/server/wm/DisplayContent.java +3 −4 Original line number Diff line number Diff line Loading @@ -109,7 +109,6 @@ import static com.android.server.wm.DisplayContentProto.OPENING_APPS; import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY; import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA; import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION; import static com.android.server.wm.DisplayContentProto.SINGLE_TASK_INSTANCE; import static com.android.server.wm.Task.ActivityState.RESUMED; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; Loading Loading @@ -1310,7 +1309,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // If display rotation class tells us that it doesn't consider app requested orientation, // this display won't rotate just because of an app changes its requested orientation. Thus // it indicates that this display chooses not to handle this request. final boolean handled = getDisplayRotation().respectAppRequestedOrientation(); final boolean handled = handlesOrientationChangeFromDescendant(); if (config == null) { return handled; } Loading @@ -1334,7 +1333,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override boolean handlesOrientationChangeFromDescendant() { return getDisplayRotation().respectAppRequestedOrientation(); return !mIgnoreOrientationRequest && !getDisplayRotation().isFixedToUserRotation(); } /** Loading Loading @@ -2346,7 +2345,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override int getOrientation() { mLastOrientationSource = null; if (mIgnoreOrientationRequest) { if (!handlesOrientationChangeFromDescendant()) { // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation ProtoLog.v(WM_DEBUG_ORIENTATION, "Display id=%d is ignoring all orientation requests, return %d", Loading
services/core/java/com/android/server/wm/DisplayRotation.java +0 −9 Original line number Diff line number Diff line Loading @@ -857,15 +857,6 @@ public class DisplayRotation { return mFixedToUserRotation; } /** * Returns {@code true} if this display rotation takes app requested orientation into * consideration; {@code false} otherwise. For the time being the only case where this is {@code * false} is when {@link #isFixedToUserRotation()} is {@code true}. */ boolean respectAppRequestedOrientation() { return !isFixedToUserRotation(); } public int getLandscapeRotation() { return mLandscapeRotation; } Loading