Loading services/core/java/com/android/server/wm/DisplayContent.java +8 −10 Original line number Diff line number Diff line Loading @@ -6923,27 +6923,25 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return; } if (mFixedRotationLaunchingApp.hasFixedRotationTransform(r)) { if (!r.isVisible()) { // Let the opening activity update orientation. return; } if (mFixedRotationLaunchingApp.hasAnimatingFixedRotationTransition()) { // Waiting until all of the associated activities have done animation, or the // orientation would be updated too early and cause flickering. return; } } else { // Handle a corner case that the task of {@link #mFixedRotationLaunchingApp} is no // longer animating but the corresponding transition finished event won't notify. // E.g. activity A transferred starting window to B, only A will receive transition // finished event. A doesn't have fixed rotation but B is the rotated launching app. final Task task = r.getTask(); if (task != mFixedRotationLaunchingApp.getTask() // Check to skip updating display orientation by a non-top activity. if ((!r.isVisible() || !mFixedRotationLaunchingApp.fillsParent()) // When closing a translucent task A (r.fillsParent() is false) to a // visible task B, because only A has visibility change, there is only A's // transition callback. Then it still needs to update orientation for B. && (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation || r.fillsParent())) { // Different tasks won't be in one activity transition animation. && r.fillsParent()) { return; } if (task.getActivity(ActivityRecord::isInTransition) != null) { if (r.inTransition()) { return; // Continue to update orientation because the transition of the top rotated // launching activity is done. Loading services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +13 −19 Original line number Diff line number Diff line Loading @@ -1609,8 +1609,10 @@ public class DisplayContentTests extends WindowTestsBase { final ActivityRecord app = mAppWindow.mActivityRecord; app.setVisible(false); mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_OPEN); mDisplayContent.mOpeningApps.add(app); app.setVisibleRequested(false); registerTestTransitionPlayer(); mDisplayContent.requestTransitionAndLegacyPrepare(WindowManager.TRANSIT_OPEN, 0); app.setVisibility(true); final int newOrientation = getRotatedOrientation(mDisplayContent); app.setRequestedOrientation(newOrientation); Loading Loading @@ -1641,14 +1643,6 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(state.isSourceOrDefaultVisible(statusBarId, statusBars()), rotatedState.isSourceOrDefaultVisible(statusBarId, statusBars())); final Rect outFrame = new Rect(); final Rect outInsets = new Rect(); final Rect outStableInsets = new Rect(); final Rect outSurfaceInsets = new Rect(); mAppWindow.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets); // The animation frames should not be rotated because display hasn't rotated. assertEquals(mDisplayContent.getBounds(), outFrame); // The display should keep current orientation and the rotated configuration should apply // to the activity. assertEquals(config.orientation, mDisplayContent.getConfiguration().orientation); Loading Loading @@ -1676,9 +1670,8 @@ public class DisplayContentTests extends WindowTestsBase { // Launch another activity before the transition is finished. final Task task2 = new TaskBuilder(mSupervisor).setDisplay(mDisplayContent).build(); final ActivityRecord app2 = new ActivityBuilder(mAtm).setTask(task2) .setUseProcess(app.app).build(); app2.setVisible(false); mDisplayContent.mOpeningApps.add(app2); .setUseProcess(app.app).setVisible(false).build(); app2.setVisibility(true); app2.setRequestedOrientation(newOrientation); // The activity should share the same transform state as the existing one. The activity Loading @@ -1701,14 +1694,15 @@ public class DisplayContentTests extends WindowTestsBase { assertTrue(mImeWindow.isAnimating(PARENTS, ANIMATION_TYPE_TOKEN_TRANSFORM)); // The fixed rotation transform can only be finished when all animation finished. doReturn(false).when(app2).isAnimating(anyInt(), anyInt()); mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app2.token); doReturn(false).when(app2).inTransition(); mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app2.token); assertTrue(app.hasFixedRotationTransform()); assertTrue(app2.hasFixedRotationTransform()); // The display should be rotated after the launch is finished. doReturn(false).when(app).isAnimating(anyInt(), anyInt()); mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app.token); app.setVisible(true); doReturn(false).when(app).inTransition(); mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token); mStatusBarWindow.finishSeamlessRotation(t); mNavBarWindow.finishSeamlessRotation(t); Loading @@ -1726,7 +1720,7 @@ public class DisplayContentTests extends WindowTestsBase { final Task task = app.getTask(); final ActivityRecord app2 = new ActivityBuilder(mWm.mAtmService).setTask(task).build(); mDisplayContent.setFixedRotationLaunchingApp(app2, (mDisplayContent.getRotation() + 1) % 4); doReturn(true).when(app).inTransitionSelfOrParent(); doReturn(true).when(app).inTransition(); // If the task contains a transition, this should be no-op. mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token); Loading @@ -1736,7 +1730,7 @@ public class DisplayContentTests extends WindowTestsBase { // The display should be unlikely to be in transition, but if it happens, the fixed // rotation should proceed to finish because the activity/task level transition is finished. doReturn(true).when(mDisplayContent).inTransition(); doReturn(false).when(app).inTransitionSelfOrParent(); doReturn(false).when(app).inTransition(); // Although this notifies app instead of app2 that uses the fixed rotation, app2 should // still finish the transform because there is no more transition event. mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token); Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +8 −10 Original line number Diff line number Diff line Loading @@ -6923,27 +6923,25 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return; } if (mFixedRotationLaunchingApp.hasFixedRotationTransform(r)) { if (!r.isVisible()) { // Let the opening activity update orientation. return; } if (mFixedRotationLaunchingApp.hasAnimatingFixedRotationTransition()) { // Waiting until all of the associated activities have done animation, or the // orientation would be updated too early and cause flickering. return; } } else { // Handle a corner case that the task of {@link #mFixedRotationLaunchingApp} is no // longer animating but the corresponding transition finished event won't notify. // E.g. activity A transferred starting window to B, only A will receive transition // finished event. A doesn't have fixed rotation but B is the rotated launching app. final Task task = r.getTask(); if (task != mFixedRotationLaunchingApp.getTask() // Check to skip updating display orientation by a non-top activity. if ((!r.isVisible() || !mFixedRotationLaunchingApp.fillsParent()) // When closing a translucent task A (r.fillsParent() is false) to a // visible task B, because only A has visibility change, there is only A's // transition callback. Then it still needs to update orientation for B. && (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation || r.fillsParent())) { // Different tasks won't be in one activity transition animation. && r.fillsParent()) { return; } if (task.getActivity(ActivityRecord::isInTransition) != null) { if (r.inTransition()) { return; // Continue to update orientation because the transition of the top rotated // launching activity is done. Loading
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +13 −19 Original line number Diff line number Diff line Loading @@ -1609,8 +1609,10 @@ public class DisplayContentTests extends WindowTestsBase { final ActivityRecord app = mAppWindow.mActivityRecord; app.setVisible(false); mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_OPEN); mDisplayContent.mOpeningApps.add(app); app.setVisibleRequested(false); registerTestTransitionPlayer(); mDisplayContent.requestTransitionAndLegacyPrepare(WindowManager.TRANSIT_OPEN, 0); app.setVisibility(true); final int newOrientation = getRotatedOrientation(mDisplayContent); app.setRequestedOrientation(newOrientation); Loading Loading @@ -1641,14 +1643,6 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(state.isSourceOrDefaultVisible(statusBarId, statusBars()), rotatedState.isSourceOrDefaultVisible(statusBarId, statusBars())); final Rect outFrame = new Rect(); final Rect outInsets = new Rect(); final Rect outStableInsets = new Rect(); final Rect outSurfaceInsets = new Rect(); mAppWindow.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets); // The animation frames should not be rotated because display hasn't rotated. assertEquals(mDisplayContent.getBounds(), outFrame); // The display should keep current orientation and the rotated configuration should apply // to the activity. assertEquals(config.orientation, mDisplayContent.getConfiguration().orientation); Loading Loading @@ -1676,9 +1670,8 @@ public class DisplayContentTests extends WindowTestsBase { // Launch another activity before the transition is finished. final Task task2 = new TaskBuilder(mSupervisor).setDisplay(mDisplayContent).build(); final ActivityRecord app2 = new ActivityBuilder(mAtm).setTask(task2) .setUseProcess(app.app).build(); app2.setVisible(false); mDisplayContent.mOpeningApps.add(app2); .setUseProcess(app.app).setVisible(false).build(); app2.setVisibility(true); app2.setRequestedOrientation(newOrientation); // The activity should share the same transform state as the existing one. The activity Loading @@ -1701,14 +1694,15 @@ public class DisplayContentTests extends WindowTestsBase { assertTrue(mImeWindow.isAnimating(PARENTS, ANIMATION_TYPE_TOKEN_TRANSFORM)); // The fixed rotation transform can only be finished when all animation finished. doReturn(false).when(app2).isAnimating(anyInt(), anyInt()); mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app2.token); doReturn(false).when(app2).inTransition(); mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app2.token); assertTrue(app.hasFixedRotationTransform()); assertTrue(app2.hasFixedRotationTransform()); // The display should be rotated after the launch is finished. doReturn(false).when(app).isAnimating(anyInt(), anyInt()); mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app.token); app.setVisible(true); doReturn(false).when(app).inTransition(); mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token); mStatusBarWindow.finishSeamlessRotation(t); mNavBarWindow.finishSeamlessRotation(t); Loading @@ -1726,7 +1720,7 @@ public class DisplayContentTests extends WindowTestsBase { final Task task = app.getTask(); final ActivityRecord app2 = new ActivityBuilder(mWm.mAtmService).setTask(task).build(); mDisplayContent.setFixedRotationLaunchingApp(app2, (mDisplayContent.getRotation() + 1) % 4); doReturn(true).when(app).inTransitionSelfOrParent(); doReturn(true).when(app).inTransition(); // If the task contains a transition, this should be no-op. mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token); Loading @@ -1736,7 +1730,7 @@ public class DisplayContentTests extends WindowTestsBase { // The display should be unlikely to be in transition, but if it happens, the fixed // rotation should proceed to finish because the activity/task level transition is finished. doReturn(true).when(mDisplayContent).inTransition(); doReturn(false).when(app).inTransitionSelfOrParent(); doReturn(false).when(app).inTransition(); // Although this notifies app instead of app2 that uses the fixed rotation, app2 should // still finish the transform because there is no more transition event. mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token); Loading