diff options
13 files changed, 283 insertions, 133 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 9dfd43cde628..330d72f139db 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -107,12 +107,6 @@ interface IWindowManager */ void endProlongedAnimations(); - // Re-evaluate the current orientation from the caller's state. - // If there is a change, the new Configuration is returned and the - // caller must call setNewConfiguration() sometime later. - Configuration updateOrientationFromAppTokens(in Configuration currentConfig, - IBinder freezeThisOneIfNeeded, int displayId); - void startFreezingScreen(int exitAnim, int enterAnim); void stopFreezingScreen(); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 4d8440a899a3..2cd0168aff42 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2486,36 +2486,20 @@ final class ActivityRecord extends ConfigurationContainer { } void setRequestedOrientation(int requestedOrientation) { - final int displayId = getDisplayId(); - final Configuration displayConfig = - mRootActivityContainer.getDisplayOverrideConfiguration(displayId); - - final Configuration config = setOrientation(requestedOrientation, - displayId, displayConfig, mayFreezeScreenLocked(app)); - if (config != null) { - frozenBeforeDestroy = true; - if (!mAtmService.updateDisplayOverrideConfigurationLocked(config, this, - false /* deferResume */, displayId)) { - mRootActivityContainer.resumeFocusedStacksTopActivities(); - } - } + setOrientation(requestedOrientation, mayFreezeScreenLocked(app)); mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged( task.taskId, requestedOrientation); } - Configuration setOrientation(int requestedOrientation, int displayId, - Configuration displayConfig, boolean freezeScreenIfNeeded) { + private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) { if (mAppWindowToken == null) { Slog.w(TAG_WM, "Attempted to set orientation of non-existing app token: " + appToken); - return null; + return; } - mAppWindowToken.setOrientation(requestedOrientation); - final IBinder binder = freezeScreenIfNeeded ? appToken.asBinder() : null; - return mAtmService.mWindowManager.updateOrientationFromAppTokens(displayConfig, binder, - displayId); + mAppWindowToken.setOrientation(requestedOrientation, binder, this); } int getOrientation() { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 1943efca8ad0..a5ceee268fa2 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -397,10 +397,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final Matrix mTmpMatrix = new Matrix(); private final Region mTmpRegion = new Region(); - /** Used for handing back size of display */ private final Rect mTmpBounds = new Rect(); + private final Configuration mTmpConfiguration = new Configuration(); + /** Remove this display when animation on it has completed. */ private boolean mDeferredRemoval; @@ -1156,6 +1157,36 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mWmService.mH.obtainMessage(SEND_NEW_CONFIGURATION, this).sendToTarget(); } + @Override + boolean onDescendantOrientationChanged(IBinder freezeDisplayToken, + ConfigurationContainer requestingContainer) { + final Configuration config = updateOrientationFromAppTokens( + getRequestedOverrideConfiguration(), freezeDisplayToken, false); + // 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(); + if (config == null) { + return handled; + } + + if (handled && requestingContainer instanceof ActivityRecord) { + final ActivityRecord activityRecord = (ActivityRecord) requestingContainer; + final boolean kept = mWmService.mAtmService.updateDisplayOverrideConfigurationLocked( + config, activityRecord, false /* deferResume */, getDisplayId()); + activityRecord.frozenBeforeDestroy = true; + if (!kept) { + mWmService.mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities(); + } + } else { + // We have a new configuration to push so we need to update ATMS for now. + // TODO: Clean up display configuration push between ATMS and WMS after unification. + mWmService.mAtmService.updateDisplayOverrideConfigurationLocked( + config, null /* starting */, false /* deferResume */, getDisplayId()); + } + return handled; + } + /** * Determine the new desired orientation of this display. * @@ -1169,7 +1200,56 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return updateOrientationFromAppTokens(false /* forceUpdate */); } - boolean updateOrientationFromAppTokens(boolean forceUpdate) { + /** + * Update orientation of the target display, returning a non-null new Configuration if it has + * changed from the current orientation. If a non-null configuration is returned, someone must + * call {@link WindowManagerService#setNewDisplayOverrideConfiguration(Configuration, + * DisplayContent)} to tell the window manager it can unfreeze the screen. This will typically + * be done by calling {@link WindowManagerService#sendNewConfiguration(int)}. + */ + Configuration updateOrientationFromAppTokens(Configuration currentConfig, + IBinder freezeDisplayToken, boolean forceUpdate) { + if (!mDisplayReady) { + return null; + } + + Configuration config = null; + if (updateOrientationFromAppTokens(forceUpdate)) { + // If we changed the orientation but mOrientationChangeComplete is already true, + // we used seamless rotation, and we don't need to freeze the screen. + if (freezeDisplayToken != null && !mWmService.mRoot.mOrientationChangeComplete) { + final AppWindowToken atoken = getAppWindowToken(freezeDisplayToken); + if (atoken != null) { + atoken.startFreezingScreen(); + } + } + config = new Configuration(); + computeScreenConfiguration(config); + } else if (currentConfig != null) { + // No obvious action we need to take, but if our current state mismatches the + // activity manager's, update it, disregarding font scale, which should remain set + // to the value of the previous configuration. + // Here we're calling Configuration#unset() instead of setToDefaults() because we + // need to keep override configs clear of non-empty values (e.g. fontSize). + mTmpConfiguration.unset(); + mTmpConfiguration.updateFrom(currentConfig); + computeScreenConfiguration(mTmpConfiguration); + if (currentConfig.diff(mTmpConfiguration) != 0) { + mWaitingForConfig = true; + setLayoutNeeded(); + int[] anim = new int[2]; + getDisplayPolicy().selectRotationAnimationLw(anim); + + mWmService.startFreezingDisplayLocked(anim[0], anim[1], this); + config = new Configuration(mTmpConfiguration); + } + } + + return config; + } + + + private boolean updateOrientationFromAppTokens(boolean forceUpdate) { final int req = getOrientation(); if (req != mLastOrientation || forceUpdate) { mLastOrientation = req; diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 7aabc15d9860..bcc7be42333b 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -329,6 +329,15 @@ 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 !mFixedToUserRotation; + } + public int getLandscapeRotation() { return mLandscapeRotation; } diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java index 8ec97c5117f1..325f95f78dd8 100644 --- a/services/core/java/com/android/server/wm/RootActivityContainer.java +++ b/services/core/java/com/android/server/wm/RootActivityContainer.java @@ -597,11 +597,15 @@ class RootActivityContainer extends ConfigurationContainer // Force-update the orientation from the WindowManager, since we need the true configuration // to send to the client now. - final Configuration config = mWindowManager.updateOrientationFromAppTokens( - getDisplayOverrideConfiguration(displayId), - starting != null && starting.mayFreezeScreenLocked(starting.app) - ? starting.appToken : null, - displayId, true /* forceUpdate */); + final DisplayContent displayContent = mRootWindowContainer.getDisplayContent(displayId); + Configuration config = null; + if (displayContent != null) { + config = displayContent.updateOrientationFromAppTokens( + getDisplayOverrideConfiguration(displayId), + starting != null && starting.mayFreezeScreenLocked(starting.app) + ? starting.appToken : null, + true /* forceUpdate */); + } if (starting != null && markFrozenIfConfigChanged && config != null) { starting.frozenBeforeDestroy = true; } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index b10fd31ba7ad..d334bd298ada 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -44,6 +44,7 @@ import android.app.ActivityManager.TaskDescription; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; +import android.os.IBinder; import android.util.EventLog; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -328,6 +329,23 @@ class Task extends WindowContainer<AppWindowToken> implements ConfigurationConta return boundsChange; } + @Override + public boolean onDescendantOrientationChanged(IBinder freezeDisplayToken, + ConfigurationContainer requestingContainer) { + if (super.onDescendantOrientationChanged(freezeDisplayToken, requestingContainer)) { + return true; + } + + // 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) { + mTaskRecord.onConfigurationChanged(mTaskRecord.getParent().getConfiguration()); + return true; + } + return false; + } + void resize(boolean relayout, boolean forced) { if (setBounds(getRequestedOverrideBounds(), forced) != BOUNDS_CHANGE_NONE && relayout) { getDisplayContent().layoutAndAssignWindowLayersIfNeeded(); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 651089d6ce10..32c5a3b8688e 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -31,10 +31,12 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.CallSuper; import android.annotation.IntDef; +import android.annotation.Nullable; import android.app.WindowConfiguration; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; +import android.os.IBinder; import android.util.Pools; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -698,8 +700,58 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } } + /** + * Called when this container or one of its descendants changed its requested orientation, and + * wants this container to handle it or pass it to its parent. + * + * @param freezeDisplayToken freeze this app window token if display needs to freeze + * @param requestingContainer the container which orientation request has changed + * @return {@code true} if handled; {@code false} otherwise. + */ + boolean onDescendantOrientationChanged(@Nullable IBinder freezeDisplayToken, + @Nullable ConfigurationContainer requestingContainer) { + final WindowContainer parent = getParent(); + if (parent == null) { + return false; + } + return parent.onDescendantOrientationChanged(freezeDisplayToken, + requestingContainer); + } + + /** + * Calls {@link #setOrientation(int, IBinder, ActivityRecord)} with {@code null} to the last 2 + * parameters. + * + * @param orientation the specified orientation. + */ void setOrientation(int orientation) { + setOrientation(orientation, null /* freezeDisplayToken */, + null /* ActivityRecord */); + } + + /** + * Sets the specified orientation of this container. It percolates this change upward along the + * hierarchy to let each level of the hierarchy a chance to respond to it. + * + * @param orientation the specified orientation. Needs to be one of {@link + * android.content.pm.ActivityInfo.ScreenOrientation}. + * @param freezeDisplayToken uses this token to freeze display if orientation change is not + * done. Display will not be frozen if this is {@code null}, which + * should only happen in tests. + * @param requestingContainer the container which orientation request has changed. Mostly used + * to ensure it gets correct configuration. + */ + void setOrientation(int orientation, @Nullable IBinder freezeDisplayToken, + @Nullable ConfigurationContainer requestingContainer) { + final boolean changed = mOrientation != orientation; mOrientation = orientation; + if (!changed) { + return; + } + final WindowContainer parent = getParent(); + if (parent != null) { + onDescendantOrientationChanged(freezeDisplayToken, requestingContainer); + } } int getOrientation() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index e3ced8350f0d..b6a4a51c41f2 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2383,85 +2383,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - @Override - public Configuration updateOrientationFromAppTokens(Configuration currentConfig, - IBinder freezeThisOneIfNeeded, int displayId) { - return updateOrientationFromAppTokens(currentConfig, freezeThisOneIfNeeded, displayId, - false /* forceUpdate */); - } - - public Configuration updateOrientationFromAppTokens(Configuration currentConfig, - IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) { - if (!checkCallingPermission(MANAGE_APP_TOKENS, "updateOrientationFromAppTokens()")) { - throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); - } - - final Configuration config; - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded, - displayId, forceUpdate); - } - } finally { - Binder.restoreCallingIdentity(ident); - } - - return config; - } - - /** - * Update orientation of the target display, returning a non-null new Configuration if it has - * changed from the current orientation. If a non-null configuration is returned, someone must - * call {@link #setNewDisplayOverrideConfiguration(Configuration, int)} to tell the window - * manager it can unfreeze the screen. This will typically be done by calling - * {@link #sendNewConfiguration(int)}. - * - * @see android.view.IWindowManager#updateOrientationFromAppTokens(Configuration, IBinder, int) - */ - private Configuration updateOrientationFromAppTokensLocked(Configuration currentConfig, - IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) { - if (!mDisplayReady) { - return null; - } - Configuration config = null; - - final DisplayContent dc = mRoot.getDisplayContent(displayId); - if (dc != null && dc.updateOrientationFromAppTokens(forceUpdate)) { - // If we changed the orientation but mOrientationChangeComplete is already true, - // we used seamless rotation, and we don't need to freeze the screen. - if (freezeThisOneIfNeeded != null && !mRoot.mOrientationChangeComplete) { - final AppWindowToken atoken = mRoot.getAppWindowToken(freezeThisOneIfNeeded); - if (atoken != null) { - atoken.startFreezingScreen(); - } - } - config = computeNewConfigurationLocked(displayId); - - } else if (currentConfig != null) { - // No obvious action we need to take, but if our current state mismatches the activity - // manager's, update it, disregarding font scale, which should remain set to the value - // of the previous configuration. - // Here we're calling Configuration#unset() instead of setToDefaults() because we need - // to keep override configs clear of non-empty values (e.g. fontSize). - mTempConfiguration.unset(); - mTempConfiguration.updateFrom(currentConfig); - final DisplayContent displayContent = mRoot.getDisplayContent(displayId); - displayContent.computeScreenConfiguration(mTempConfiguration); - if (currentConfig.diff(mTempConfiguration) != 0) { - displayContent.mWaitingForConfig = true; - displayContent.setLayoutNeeded(); - int anim[] = new int[2]; - displayContent.getDisplayPolicy().selectRotationAnimationLw(anim); - - startFreezingDisplayLocked(anim[0], anim[1], displayContent); - config = new Configuration(mTempConfiguration); - } - } - - return config; - } - void setNewDisplayOverrideConfiguration(Configuration overrideConfig, @NonNull DisplayContent dc) { if (dc.mWaitingForConfig) { diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java index 92b4dbb5076b..bc62de12373d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java @@ -155,15 +155,17 @@ public class AppWindowTokenTests extends WindowTestsBase { // Set initial orientation and update. mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); - mWm.updateOrientationFromAppTokens(mDisplayContent.getRequestedOverrideConfiguration(), - null, mDisplayContent.getDisplayId()); + mDisplayContent.updateOrientationFromAppTokens( + mDisplayContent.getRequestedOverrideConfiguration(), + null /* freezeThisOneIfNeeded */, false /* forceUpdate */); assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation()); appWindow.mResizeReported = false; // Update the orientation to perform 180 degree rotation and check that resize was reported. mToken.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE); - mWm.updateOrientationFromAppTokens(mDisplayContent.getRequestedOverrideConfiguration(), - null, mDisplayContent.getDisplayId()); + mDisplayContent.updateOrientationFromAppTokens( + mDisplayContent.getRequestedOverrideConfiguration(), + null /* freezeThisOneIfNeeded */, false /* forceUpdate */); mWm.mRoot.performSurfacePlacement(false /* recoveringMemory */); assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation()); assertTrue(appWindow.mResizeReported); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 8430616731d2..3826fac22b05 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -31,7 +31,13 @@ import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.same; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; @@ -60,9 +66,11 @@ import android.view.Surface; import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; +import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.server.wm.utils.WmDisplayCutout; import org.junit.Test; +import org.mockito.ArgumentCaptor; import java.util.ArrayList; import java.util.Arrays; @@ -475,6 +483,13 @@ public class DisplayContentTests extends WindowTestsBase { @SuppressLint("InlinedApi") public void testOrientationDefinedByKeyguard() { final DisplayContent dc = createNewDisplay(); + + // When display content is created its configuration is not yet initialized, which could + // cause unnecessary configuration propagation, so initialize it here. + final Configuration config = new Configuration(); + dc.computeScreenConfiguration(config); + dc.onRequestedOverrideConfigurationChanged(config); + // Create a window that requests landscape orientation. It will define device orientation // by default. final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w"); @@ -567,6 +582,52 @@ public class DisplayContentTests extends WindowTestsBase { assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget); } + @Test + public void testOnDescendantOrientationRequestChanged() { + final DisplayContent dc = createNewDisplay(); + mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class); + final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE + ? SCREEN_ORIENTATION_PORTRAIT + : SCREEN_ORIENTATION_LANDSCAPE; + + final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w"); + window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS); + window.mAppToken.setOrientation(newOrientation); + + ActivityRecord activityRecord = mock(ActivityRecord.class); + + assertTrue("Display should rotate to handle orientation request by default.", + dc.onDescendantOrientationChanged(window.mToken.token, activityRecord)); + + final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class); + verify(mWm.mAtmService).updateDisplayOverrideConfigurationLocked(captor.capture(), + same(activityRecord), anyBoolean(), eq(dc.getDisplayId())); + final Configuration newDisplayConfig = captor.getValue(); + assertEquals(Configuration.ORIENTATION_PORTRAIT, newDisplayConfig.orientation); + } + + @Test + public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() { + final DisplayContent dc = createNewDisplay(); + dc.getDisplayRotation().setFixedToUserRotation(true); + mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class); + final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE + ? SCREEN_ORIENTATION_PORTRAIT + : SCREEN_ORIENTATION_LANDSCAPE; + + final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w"); + window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS); + window.mAppToken.setOrientation(newOrientation); + + ActivityRecord activityRecord = mock(ActivityRecord.class); + + assertFalse("Display shouldn't rotate to handle orientation request if fixed to" + + " user rotation.", + dc.onDescendantOrientationChanged(window.mToken.token, activityRecord)); + verify(mWm.mAtmService, never()).updateDisplayOverrideConfigurationLocked(any(), + eq(activityRecord), anyBoolean(), eq(dc.getDisplayId())); + } + private boolean isOptionsPanelAtRight(int displayId) { return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT; } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java index bf4b52eb72aa..6b31e6fdbd28 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -33,6 +33,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.content.ContentResolver; @@ -234,7 +235,7 @@ public class DisplayRotationTests { } @Test - public void testReturnsSidesays_UserRotationLocked_IncompatibleAppRequest() + public void testReturnsSideways_UserRotationLocked_IncompatibleAppRequest() throws Exception { mBuilder.build(); configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false); @@ -604,6 +605,26 @@ public class DisplayRotationTests { SCREEN_ORIENTATION_UNSPECIFIED, Surface.ROTATION_0)); } + // ======================== + // Non-rotation API Tests + // ======================== + @Test + public void testRespectsAppRequestedOrientationByDefault() throws Exception { + mBuilder.build(); + + assertTrue("Display rotation should respect app requested orientation by" + + " default.", mTarget.respectAppRequestedOrientation()); + } + + @Test + public void testNotRespectAppRequestedOrientation_FixedToUserRotation() throws Exception { + mBuilder.build(); + mTarget.setFixedToUserRotation(true); + + assertFalse("Display rotation shouldn't respect app requested orientation if" + + " fixed to user rotation.", mTarget.respectAppRequestedOrientation()); + } + /** * Call {@link DisplayRotation#configure(int, int, int, int)} to configure {@link #mTarget} * according to given parameters. diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 60f957f8f569..e1561436c022 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -27,6 +27,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyFloat; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; @@ -38,8 +39,10 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; +import android.os.IBinder; import android.platform.test.annotations.Presubmit; import android.view.SurfaceControl; import android.view.SurfaceSession; @@ -559,8 +562,7 @@ public class WindowContainerTests extends WindowTestsBase { builder.setLayer(2).setIsVisible(true); final TestWindowContainer visibleUnspecifiedRootChildChildFillsParent = visibleUnspecifiedRootChild.addChildWindow(builder); - visibleUnspecifiedRootChildChildFillsParent.setOrientation( - SCREEN_ORIENTATION_PORTRAIT); + visibleUnspecifiedRootChildChildFillsParent.setOrientation(SCREEN_ORIENTATION_PORTRAIT); assertEquals(SCREEN_ORIENTATION_PORTRAIT, visibleUnspecifiedRootChildChildFillsParent.getOrientation()); assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnspecifiedRootChild.getOrientation()); @@ -724,6 +726,19 @@ public class WindowContainerTests extends WindowTestsBase { verify(grandChild, times(1)).onParentResize(); } + @Test + public void testOnDescendantOrientationRequestChangedPropagation() { + final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm); + final TestWindowContainer root = spy(builder.build()); + + final IBinder binder = mock(IBinder.class); + final ActivityRecord activityRecord = mock(ActivityRecord.class); + final TestWindowContainer child = root.addChildWindow(); + + child.setOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED, binder, activityRecord); + verify(root).onDescendantOrientationChanged(binder, activityRecord); + } + /* Used so we can gain access to some protected members of the {@link WindowContainer} class */ private static class TestWindowContainer extends WindowContainer<TestWindowContainer> { private final int mLayer; diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java index 369a002fa273..4c2a984f8198 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -16,16 +16,16 @@ package com.android.framework.permission.tests; -import android.content.res.Configuration; +import static android.view.Display.DEFAULT_DISPLAY; + import android.os.Binder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.test.suitebuilder.annotation.SmallTest; import android.view.IWindowManager; -import junit.framework.TestCase; -import static android.view.Display.DEFAULT_DISPLAY; +import junit.framework.TestCase; /** * TODO: Remove this. This is only a placeholder, need to implement this. @@ -73,17 +73,6 @@ public class WindowManagerPermissionTests extends TestCase { } try { - mWm.updateOrientationFromAppTokens(new Configuration(), - null /* freezeThisOneIfNeeded */, DEFAULT_DISPLAY); - fail("IWindowManager.updateOrientationFromAppTokens did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - - try { mWm.prepareAppTransition(0, false); fail("IWindowManager.prepareAppTransition did not throw SecurityException as" + " expected"); |