Loading services/core/java/com/android/server/wm/ActivityStack.java +4 −32 Original line number Original line Diff line number Diff line Loading @@ -161,7 +161,6 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.List; import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.function.Consumer; Loading Loading @@ -610,7 +609,8 @@ class ActivityStack extends Task { // Update bounds if applicable // Update bounds if applicable boolean hasNewOverrideBounds = false; boolean hasNewOverrideBounds = false; // Use override windowing mode to prevent extra bounds changes if inheriting the mode. // Use override windowing mode to prevent extra bounds changes if inheriting the mode. if ((overrideWindowingMode != WINDOWING_MODE_PINNED) && !matchParentBounds()) { if ((overrideWindowingMode != WINDOWING_MODE_PINNED) && !getRequestedOverrideBounds().isEmpty()) { // If the parent (display) has rotated, rotate our bounds to best-fit where their // If the parent (display) has rotated, rotate our bounds to best-fit where their // bounds were on the pre-rotated display. // bounds were on the pre-rotated display. final int newRotation = getWindowConfiguration().getRotation(); final int newRotation = getWindowConfiguration().getRotation(); Loading Loading @@ -762,41 +762,12 @@ class ActivityStack extends Task { + " while there is already one isn't currently supported"); + " while there is already one isn't currently supported"); //return; //return; } } mTmpRect2.setEmpty(); if (windowingMode != WINDOWING_MODE_FULLSCREEN) { if (matchParentBounds()) { mTmpRect2.setEmpty(); } else { getRawBounds(mTmpRect2); } } if (!Objects.equals(getRequestedOverrideBounds(), mTmpRect2)) { resize(mTmpRect2, false /*preserveWindows*/, true /*deferResume*/); } } finally { } finally { mAtmService.continueWindowLayout(); mAtmService.continueWindowLayout(); } } mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); mRootWindowContainer.resumeFocusedStacksTopActivities(); mRootWindowContainer.resumeFocusedStacksTopActivities(); final boolean pinnedToFullscreen = currentMode == WINDOWING_MODE_PINNED && windowingMode == WINDOWING_MODE_FULLSCREEN; if (pinnedToFullscreen && topActivity != null && !isForceHidden()) { mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(true); try { // Report orientation as soon as possible so that the display can freeze earlier if // the display orientation will be changed. Because the surface bounds of activity // may have been set to fullscreen but the activity hasn't redrawn its content yet, // the rotation animation needs to capture snapshot earlier to avoid animating from // an intermediate state. topActivity.reportDescendantOrientationChangeIfNeeded(); } finally { mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(false); } } } } @Override @Override Loading Loading @@ -2900,7 +2871,8 @@ class ActivityStack extends Task { .isKeyguardOrAodShowing(displayId); .isKeyguardOrAodShowing(displayId); if (!mStackSupervisor.getLaunchParamsController() if (!mStackSupervisor.getLaunchParamsController() .layoutTask(task, info.windowLayout, activity, source, options) .layoutTask(task, info.windowLayout, activity, source, options) && !matchParentBounds() && task.isResizeable() && !isLockscreenShown) { && !getRequestedOverrideBounds().isEmpty() && task.isResizeable() && !isLockscreenShown) { task.setBounds(getRequestedOverrideBounds()); task.setBounds(getRequestedOverrideBounds()); } } Loading services/core/java/com/android/server/wm/ConfigurationContainer.java +7 −6 Original line number Original line Diff line number Diff line Loading @@ -203,15 +203,16 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { } } /** /** * Indicates whether this container has not requested any bounds different from its parent. In * Indicates whether this container chooses not to override any bounds from its parent, either * this case, it will inherit the bounds of the first ancestor which specifies a bounds subject * because it doesn't request to override them or the request is dropped during configuration * to policy constraints. * resolution. In this case, it will inherit the bounds of the first ancestor which specifies a * bounds subject to policy constraints. * * * @return {@code true} if no explicit bounds have been requested at this container level. * @return {@code true} if this container level uses bounds from parent level. {@code false} * {@code false} otherwise. * otherwise. */ */ public boolean matchParentBounds() { public boolean matchParentBounds() { return getRequestedOverrideBounds().isEmpty(); return getResolvedOverrideBounds().isEmpty(); } } /** /** Loading services/core/java/com/android/server/wm/Task.java +25 −19 Original line number Original line Diff line number Diff line Loading @@ -1902,12 +1902,14 @@ class Task extends WindowContainer<WindowContainer> { mTmpPrevBounds.set(getBounds()); mTmpPrevBounds.set(getBounds()); final boolean wasInMultiWindowMode = inMultiWindowMode(); final boolean wasInMultiWindowMode = inMultiWindowMode(); final boolean wasInPictureInPicture = inPinnedWindowingMode(); final boolean wasInPictureInPicture = inPinnedWindowingMode(); final int oldOrientation = getOrientation(); super.onConfigurationChanged(newParentConfig); super.onConfigurationChanged(newParentConfig); // Only need to update surface size here since the super method will handle updating // Only need to update surface size here since the super method will handle updating // surface position. // surface position. updateSurfaceSize(getSyncTransaction()); updateSurfaceSize(getSyncTransaction()); if (wasInPictureInPicture != inPinnedWindowingMode()) { final boolean pipChanging = wasInPictureInPicture != inPinnedWindowingMode(); if (pipChanging) { mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, getStack()); mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, getStack()); } else if (wasInMultiWindowMode != inMultiWindowMode()) { } else if (wasInMultiWindowMode != inMultiWindowMode()) { mStackSupervisor.scheduleUpdateMultiWindowMode(this); mStackSupervisor.scheduleUpdateMultiWindowMode(this); Loading @@ -1928,6 +1930,26 @@ class Task extends WindowContainer<WindowContainer> { } } } } if (pipChanging) { mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(true); } try { // We have 2 reasons why we need to report orientation change here. // 1. In some cases (e.g. freeform -> fullscreen) we don't have other ways of reporting. // 2. Report orientation as soon as possible so that the display can freeze earlier if // the display orientation will be changed. Because the surface bounds of activity // may have been set to fullscreen but the activity hasn't redrawn its content yet, // the rotation animation needs to capture snapshot earlier to avoid animating from // an intermediate state. if (oldOrientation != getOrientation()) { onDescendantOrientationChanged(null, this); } } finally { if (pipChanging) { mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(false); } } saveLaunchingStateIfNeeded(); saveLaunchingStateIfNeeded(); final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */); final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */); // If the task organizer has changed, then it will already be receiving taskAppeared with // If the task organizer has changed, then it will already be receiving taskAppeared with Loading Loading @@ -2518,20 +2540,7 @@ class Task extends WindowContainer<WindowContainer> { return; return; } } if (inStack.inFreeformWindowingMode()) { if (!inStack.inFreeformWindowingMode()) { if (!isResizeable()) { throw new IllegalArgumentException("Can not position non-resizeable task=" + this + " in stack=" + inStack); } if (!matchParentBounds()) { return; } if (mLastNonFullscreenBounds != null) { setBounds(mLastNonFullscreenBounds); } else { mStackSupervisor.getLaunchParamsController().layoutTask(this, null); } } else { setBounds(inStack.getRequestedOverrideBounds()); setBounds(inStack.getRequestedOverrideBounds()); } } } } Loading Loading @@ -3044,10 +3053,7 @@ class Task extends WindowContainer<WindowContainer> { if (displayContent == null) { if (displayContent == null) { return; return; } } if (matchParentBounds()) { if (getRequestedOverrideBounds().isEmpty()) { // TODO: Yeah...not sure if this works with WindowConfiguration, but shouldn't be a // problem once we move mBounds into WindowConfiguration. setBounds(null); return; return; } } final int displayId = displayContent.getDisplayId(); final int displayId = displayContent.getDisplayId(); Loading services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE; import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE; Loading Loading @@ -957,6 +958,23 @@ public class TaskRecordTests extends ActivityTestsBase { assertEquals(SCREEN_ORIENTATION_UNSET, taskDisplayArea.getOrientation()); assertEquals(SCREEN_ORIENTATION_UNSET, taskDisplayArea.getOrientation()); } } @Test public void testNotifyOrientationChangeCausedByConfigurationChange() { final Task task = getTestTask(); final ActivityRecord activity = task.getTopMostActivity(); final DisplayContent display = task.getDisplayContent(); display.setWindowingMode(WINDOWING_MODE_FREEFORM); activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); assertEquals(SCREEN_ORIENTATION_UNSET, task.getOrientation()); verify(display).onDescendantOrientationChanged(any(), same(task)); reset(display); display.setWindowingMode(WINDOWING_MODE_FULLSCREEN); assertEquals(SCREEN_ORIENTATION_LANDSCAPE, task.getOrientation()); verify(display).onDescendantOrientationChanged(any(), same(task)); } private Task getTestTask() { private Task getTestTask() { final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); return stack.getBottomMostTask(); return stack.getBottomMostTask(); Loading Loading
services/core/java/com/android/server/wm/ActivityStack.java +4 −32 Original line number Original line Diff line number Diff line Loading @@ -161,7 +161,6 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.List; import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.function.Consumer; Loading Loading @@ -610,7 +609,8 @@ class ActivityStack extends Task { // Update bounds if applicable // Update bounds if applicable boolean hasNewOverrideBounds = false; boolean hasNewOverrideBounds = false; // Use override windowing mode to prevent extra bounds changes if inheriting the mode. // Use override windowing mode to prevent extra bounds changes if inheriting the mode. if ((overrideWindowingMode != WINDOWING_MODE_PINNED) && !matchParentBounds()) { if ((overrideWindowingMode != WINDOWING_MODE_PINNED) && !getRequestedOverrideBounds().isEmpty()) { // If the parent (display) has rotated, rotate our bounds to best-fit where their // If the parent (display) has rotated, rotate our bounds to best-fit where their // bounds were on the pre-rotated display. // bounds were on the pre-rotated display. final int newRotation = getWindowConfiguration().getRotation(); final int newRotation = getWindowConfiguration().getRotation(); Loading Loading @@ -762,41 +762,12 @@ class ActivityStack extends Task { + " while there is already one isn't currently supported"); + " while there is already one isn't currently supported"); //return; //return; } } mTmpRect2.setEmpty(); if (windowingMode != WINDOWING_MODE_FULLSCREEN) { if (matchParentBounds()) { mTmpRect2.setEmpty(); } else { getRawBounds(mTmpRect2); } } if (!Objects.equals(getRequestedOverrideBounds(), mTmpRect2)) { resize(mTmpRect2, false /*preserveWindows*/, true /*deferResume*/); } } finally { } finally { mAtmService.continueWindowLayout(); mAtmService.continueWindowLayout(); } } mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); mRootWindowContainer.resumeFocusedStacksTopActivities(); mRootWindowContainer.resumeFocusedStacksTopActivities(); final boolean pinnedToFullscreen = currentMode == WINDOWING_MODE_PINNED && windowingMode == WINDOWING_MODE_FULLSCREEN; if (pinnedToFullscreen && topActivity != null && !isForceHidden()) { mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(true); try { // Report orientation as soon as possible so that the display can freeze earlier if // the display orientation will be changed. Because the surface bounds of activity // may have been set to fullscreen but the activity hasn't redrawn its content yet, // the rotation animation needs to capture snapshot earlier to avoid animating from // an intermediate state. topActivity.reportDescendantOrientationChangeIfNeeded(); } finally { mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(false); } } } } @Override @Override Loading Loading @@ -2900,7 +2871,8 @@ class ActivityStack extends Task { .isKeyguardOrAodShowing(displayId); .isKeyguardOrAodShowing(displayId); if (!mStackSupervisor.getLaunchParamsController() if (!mStackSupervisor.getLaunchParamsController() .layoutTask(task, info.windowLayout, activity, source, options) .layoutTask(task, info.windowLayout, activity, source, options) && !matchParentBounds() && task.isResizeable() && !isLockscreenShown) { && !getRequestedOverrideBounds().isEmpty() && task.isResizeable() && !isLockscreenShown) { task.setBounds(getRequestedOverrideBounds()); task.setBounds(getRequestedOverrideBounds()); } } Loading
services/core/java/com/android/server/wm/ConfigurationContainer.java +7 −6 Original line number Original line Diff line number Diff line Loading @@ -203,15 +203,16 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { } } /** /** * Indicates whether this container has not requested any bounds different from its parent. In * Indicates whether this container chooses not to override any bounds from its parent, either * this case, it will inherit the bounds of the first ancestor which specifies a bounds subject * because it doesn't request to override them or the request is dropped during configuration * to policy constraints. * resolution. In this case, it will inherit the bounds of the first ancestor which specifies a * bounds subject to policy constraints. * * * @return {@code true} if no explicit bounds have been requested at this container level. * @return {@code true} if this container level uses bounds from parent level. {@code false} * {@code false} otherwise. * otherwise. */ */ public boolean matchParentBounds() { public boolean matchParentBounds() { return getRequestedOverrideBounds().isEmpty(); return getResolvedOverrideBounds().isEmpty(); } } /** /** Loading
services/core/java/com/android/server/wm/Task.java +25 −19 Original line number Original line Diff line number Diff line Loading @@ -1902,12 +1902,14 @@ class Task extends WindowContainer<WindowContainer> { mTmpPrevBounds.set(getBounds()); mTmpPrevBounds.set(getBounds()); final boolean wasInMultiWindowMode = inMultiWindowMode(); final boolean wasInMultiWindowMode = inMultiWindowMode(); final boolean wasInPictureInPicture = inPinnedWindowingMode(); final boolean wasInPictureInPicture = inPinnedWindowingMode(); final int oldOrientation = getOrientation(); super.onConfigurationChanged(newParentConfig); super.onConfigurationChanged(newParentConfig); // Only need to update surface size here since the super method will handle updating // Only need to update surface size here since the super method will handle updating // surface position. // surface position. updateSurfaceSize(getSyncTransaction()); updateSurfaceSize(getSyncTransaction()); if (wasInPictureInPicture != inPinnedWindowingMode()) { final boolean pipChanging = wasInPictureInPicture != inPinnedWindowingMode(); if (pipChanging) { mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, getStack()); mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, getStack()); } else if (wasInMultiWindowMode != inMultiWindowMode()) { } else if (wasInMultiWindowMode != inMultiWindowMode()) { mStackSupervisor.scheduleUpdateMultiWindowMode(this); mStackSupervisor.scheduleUpdateMultiWindowMode(this); Loading @@ -1928,6 +1930,26 @@ class Task extends WindowContainer<WindowContainer> { } } } } if (pipChanging) { mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(true); } try { // We have 2 reasons why we need to report orientation change here. // 1. In some cases (e.g. freeform -> fullscreen) we don't have other ways of reporting. // 2. Report orientation as soon as possible so that the display can freeze earlier if // the display orientation will be changed. Because the surface bounds of activity // may have been set to fullscreen but the activity hasn't redrawn its content yet, // the rotation animation needs to capture snapshot earlier to avoid animating from // an intermediate state. if (oldOrientation != getOrientation()) { onDescendantOrientationChanged(null, this); } } finally { if (pipChanging) { mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(false); } } saveLaunchingStateIfNeeded(); saveLaunchingStateIfNeeded(); final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */); final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */); // If the task organizer has changed, then it will already be receiving taskAppeared with // If the task organizer has changed, then it will already be receiving taskAppeared with Loading Loading @@ -2518,20 +2540,7 @@ class Task extends WindowContainer<WindowContainer> { return; return; } } if (inStack.inFreeformWindowingMode()) { if (!inStack.inFreeformWindowingMode()) { if (!isResizeable()) { throw new IllegalArgumentException("Can not position non-resizeable task=" + this + " in stack=" + inStack); } if (!matchParentBounds()) { return; } if (mLastNonFullscreenBounds != null) { setBounds(mLastNonFullscreenBounds); } else { mStackSupervisor.getLaunchParamsController().layoutTask(this, null); } } else { setBounds(inStack.getRequestedOverrideBounds()); setBounds(inStack.getRequestedOverrideBounds()); } } } } Loading Loading @@ -3044,10 +3053,7 @@ class Task extends WindowContainer<WindowContainer> { if (displayContent == null) { if (displayContent == null) { return; return; } } if (matchParentBounds()) { if (getRequestedOverrideBounds().isEmpty()) { // TODO: Yeah...not sure if this works with WindowConfiguration, but shouldn't be a // problem once we move mBounds into WindowConfiguration. setBounds(null); return; return; } } final int displayId = displayContent.getDisplayId(); final int displayId = displayContent.getDisplayId(); Loading
services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE; import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE; Loading Loading @@ -957,6 +958,23 @@ public class TaskRecordTests extends ActivityTestsBase { assertEquals(SCREEN_ORIENTATION_UNSET, taskDisplayArea.getOrientation()); assertEquals(SCREEN_ORIENTATION_UNSET, taskDisplayArea.getOrientation()); } } @Test public void testNotifyOrientationChangeCausedByConfigurationChange() { final Task task = getTestTask(); final ActivityRecord activity = task.getTopMostActivity(); final DisplayContent display = task.getDisplayContent(); display.setWindowingMode(WINDOWING_MODE_FREEFORM); activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); assertEquals(SCREEN_ORIENTATION_UNSET, task.getOrientation()); verify(display).onDescendantOrientationChanged(any(), same(task)); reset(display); display.setWindowingMode(WINDOWING_MODE_FULLSCREEN); assertEquals(SCREEN_ORIENTATION_LANDSCAPE, task.getOrientation()); verify(display).onDescendantOrientationChanged(any(), same(task)); } private Task getTestTask() { private Task getTestTask() { final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); return stack.getBottomMostTask(); return stack.getBottomMostTask(); Loading