Loading services/core/java/com/android/server/wm/AppWindowToken.java +22 −0 Original line number Diff line number Diff line Loading @@ -582,6 +582,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } } } // Changes in opening apps and closing apps may cause orientation change. reportDescendantOrientationChangeIfNeeded(); return; } Loading Loading @@ -729,11 +731,31 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } SurfaceControl.closeTransaction(); } // Visibility changes may cause orientation request change. reportDescendantOrientationChangeIfNeeded(); } return delayed; } private void reportDescendantOrientationChangeIfNeeded() { // Orientation request is exposed only when we're visible. Therefore visibility change // will change requested orientation. Notify upward the hierarchy ladder to adjust // configuration. This is important to cases where activities with incompatible // orientations launch, or user goes back from an activity of bi-orientation to an // activity with specified orientation. if (mActivityRecord.getRequestedConfigurationOrientation() == getConfiguration().orientation || getOrientationIgnoreVisibility() == SCREEN_ORIENTATION_UNSET) { return; } final IBinder freezeToken = mActivityRecord.mayFreezeScreenLocked(mActivityRecord.app) ? mActivityRecord.appToken : null; onDescendantOrientationChanged(freezeToken, mActivityRecord); } /** * @return The to top most child window for which {@link LayoutParams#isFullscreen()} returns * true. Loading services/core/java/com/android/server/wm/Task.java +1 −1 Original line number Diff line number Diff line Loading @@ -330,7 +330,7 @@ class Task extends WindowContainer<AppWindowToken> implements ConfigurationConta // No one in higher hierarchy handles this request, let's adjust our bounds to fulfill // it if possible. // TODO: Move to TaskRecord after unification is done. if (mTaskRecord != null) { if (mTaskRecord != null && mTaskRecord.getParent() != null) { mTaskRecord.onConfigurationChanged(mTaskRecord.getParent().getConfiguration()); return true; } Loading services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +46 −1 Original line number Diff line number Diff line Loading @@ -18,11 +18,11 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.content.ActivityInfoProto.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; Loading @@ -42,12 +42,16 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.verify; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.view.Display; import android.view.Surface; import android.view.WindowManager; Loading @@ -55,6 +59,7 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; /** * Tests for the {@link AppWindowToken} class. Loading Loading @@ -331,6 +336,46 @@ public class AppWindowTokenTests extends WindowTestsBase { mWm.mDisplayFrozen = false; } @Test public void testReportOrientationChangeOnVisibilityChange() { synchronized (mWm.mGlobalLock) { mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); mDisplayContent.getDisplayRotation().setFixedToUserRotation( DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED); doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord) .getRequestedConfigurationOrientation(); mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS); mToken.commitVisibility(null, false /* visible */, TRANSIT_UNSET, true /* performLayout */, false /* isVoiceInteraction */); } verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class)); } @Test public void testReportOrientationChangeOnOpeningClosingAppChange() { synchronized (mWm.mGlobalLock) { mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); mDisplayContent.getDisplayRotation().setFixedToUserRotation( DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED); mDisplayContent.getDisplayInfo().state = Display.STATE_ON; mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */); doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord) .getRequestedConfigurationOrientation(); mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS); mToken.setVisibility(false, false); } verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class)); } @Test public void testCreateRemoveStartingWindow() { mToken.addStartingWindow(mPackageName, Loading services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java +2 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,8 @@ class WindowTestUtils { }, new ComponentName("", ""), false, dc, true /* fillsParent */); mTargetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT; mSkipOnParentChanged = skipOnParentChanged; mActivityRecord = mock(ActivityRecord.class); mActivityRecord.app = mock(WindowProcessController.class); } int getWindowsCount() { Loading Loading
services/core/java/com/android/server/wm/AppWindowToken.java +22 −0 Original line number Diff line number Diff line Loading @@ -582,6 +582,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } } } // Changes in opening apps and closing apps may cause orientation change. reportDescendantOrientationChangeIfNeeded(); return; } Loading Loading @@ -729,11 +731,31 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } SurfaceControl.closeTransaction(); } // Visibility changes may cause orientation request change. reportDescendantOrientationChangeIfNeeded(); } return delayed; } private void reportDescendantOrientationChangeIfNeeded() { // Orientation request is exposed only when we're visible. Therefore visibility change // will change requested orientation. Notify upward the hierarchy ladder to adjust // configuration. This is important to cases where activities with incompatible // orientations launch, or user goes back from an activity of bi-orientation to an // activity with specified orientation. if (mActivityRecord.getRequestedConfigurationOrientation() == getConfiguration().orientation || getOrientationIgnoreVisibility() == SCREEN_ORIENTATION_UNSET) { return; } final IBinder freezeToken = mActivityRecord.mayFreezeScreenLocked(mActivityRecord.app) ? mActivityRecord.appToken : null; onDescendantOrientationChanged(freezeToken, mActivityRecord); } /** * @return The to top most child window for which {@link LayoutParams#isFullscreen()} returns * true. Loading
services/core/java/com/android/server/wm/Task.java +1 −1 Original line number Diff line number Diff line Loading @@ -330,7 +330,7 @@ class Task extends WindowContainer<AppWindowToken> implements ConfigurationConta // No one in higher hierarchy handles this request, let's adjust our bounds to fulfill // it if possible. // TODO: Move to TaskRecord after unification is done. if (mTaskRecord != null) { if (mTaskRecord != null && mTaskRecord.getParent() != null) { mTaskRecord.onConfigurationChanged(mTaskRecord.getParent().getConfiguration()); return true; } Loading
services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +46 −1 Original line number Diff line number Diff line Loading @@ -18,11 +18,11 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.content.ActivityInfoProto.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; Loading @@ -42,12 +42,16 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.verify; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.view.Display; import android.view.Surface; import android.view.WindowManager; Loading @@ -55,6 +59,7 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; /** * Tests for the {@link AppWindowToken} class. Loading Loading @@ -331,6 +336,46 @@ public class AppWindowTokenTests extends WindowTestsBase { mWm.mDisplayFrozen = false; } @Test public void testReportOrientationChangeOnVisibilityChange() { synchronized (mWm.mGlobalLock) { mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); mDisplayContent.getDisplayRotation().setFixedToUserRotation( DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED); doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord) .getRequestedConfigurationOrientation(); mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS); mToken.commitVisibility(null, false /* visible */, TRANSIT_UNSET, true /* performLayout */, false /* isVoiceInteraction */); } verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class)); } @Test public void testReportOrientationChangeOnOpeningClosingAppChange() { synchronized (mWm.mGlobalLock) { mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); mDisplayContent.getDisplayRotation().setFixedToUserRotation( DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED); mDisplayContent.getDisplayInfo().state = Display.STATE_ON; mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */); doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord) .getRequestedConfigurationOrientation(); mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS); mToken.setVisibility(false, false); } verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class)); } @Test public void testCreateRemoveStartingWindow() { mToken.addStartingWindow(mPackageName, Loading
services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java +2 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,8 @@ class WindowTestUtils { }, new ComponentName("", ""), false, dc, true /* fillsParent */); mTargetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT; mSkipOnParentChanged = skipOnParentChanged; mActivityRecord = mock(ActivityRecord.class); mActivityRecord.app = mock(WindowProcessController.class); } int getWindowsCount() { Loading