diff options
5 files changed, 81 insertions, 22 deletions
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index baf777220691..020e75f9fec4 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -1899,11 +1899,22 @@ final class ActivityRecord implements AppWindowContainerListener { task.taskId, requestedOrientation); } - // TODO: now used only in one place to address race-condition. Remove when that will be fixed. - void setLastReportedConfiguration(@NonNull Configuration config) { + /** + * Set the last reported global configuration to the client. Should be called whenever a new + * global configuration is sent to the client for this activity. + */ + void setLastReportedGlobalConfiguration(@NonNull Configuration config) { mLastReportedConfiguration.setTo(config); } + /** + * Set the last reported merged override configuration to the client. Should be called whenever + * a new merged configuration is sent to the client for this activity. + */ + void setLastReportedMergedOverrideConfiguration(@NonNull Configuration config) { + mLastReportedOverrideConfiguration.setTo(config); + } + /** Call when override config was sent to the Window Manager to update internal records. */ void onOverrideConfigurationSent() { mLastReportedOverrideConfiguration.setTo(task.getMergedOverrideConfiguration()); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index b2b3e61ca534..ef06fc581ebb 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1333,10 +1333,18 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Because we could be starting an Activity in the system process this may not go across // a Binder interface which would create a new Configuration. Consequently we have to // always create a new Configuration here. + + final Configuration globalConfiguration = + new Configuration(mService.getGlobalConfiguration()); + r.setLastReportedGlobalConfiguration(globalConfiguration); + final Configuration mergedOverrideConfiguration = + new Configuration(task.getMergedOverrideConfiguration()); + r.setLastReportedMergedOverrideConfiguration(mergedOverrideConfiguration); + app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, - new Configuration(mService.getGlobalConfiguration()), - new Configuration(task.getMergedOverrideConfiguration()), r.compat, + globalConfiguration, + mergedOverrideConfiguration, r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); @@ -1731,7 +1739,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // We'll update with whatever configuration it now says // it used to launch. if (config != null) { - r.setLastReportedConfiguration(config); + r.setLastReportedGlobalConfiguration(config); } // We are now idle. If someone is waiting for a thumbnail from diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index bcc720d05424..d64376973616 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1151,10 +1151,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree */ @Override int getOrientation() { - if (hidden || hiddenRequested) { - return SCREEN_ORIENTATION_UNSET; + if (fillsParent() && (isVisible() || mService.mOpeningApps.contains(this))) { + return mOrientation; } - return mOrientation; + + return SCREEN_ORIENTATION_UNSET; } /** Returns the app's preferred orientation regardless of its currently visibility state. */ diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 5b96263b1817..6973c3c95d49 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -510,14 +510,13 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon * specification... */ int getOrientation() { - - if (!fillsParent() || !isVisible()) { - // Ignore invisible containers or containers that don't completely fills their parents. + if (!fillsParent()) { + // Ignore containers that don't completely fill their parents. return SCREEN_ORIENTATION_UNSET; } - // The container fills its parent so we can use it orientation if it has one specified, - // otherwise we prefer to use the orientation of its topmost child that has one + // The container fills its parent so we can use it orientation if it has one + // specified; otherwise we prefer to use the orientation of its topmost child that has one // specified and fall back on this container's unset or unspecified value as a candidate // if none of the children have a better candidate for the orientation. if (mOrientation != SCREEN_ORIENTATION_UNSET diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java index 4f740ac46646..4f9cd9547a52 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java @@ -388,6 +388,32 @@ public class WindowContainerTests extends WindowTestsBase { } @Test + public void testGetOrientation_childSpecified() throws Exception { + testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_LANDSCAPE, + SCREEN_ORIENTATION_LANDSCAPE); + testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_UNSET, + SCREEN_ORIENTATION_UNSET); + } + + private void testGetOrientation_childSpecifiedConfig(boolean childVisible, int childOrientation, + int expectedOrientation) { + final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(); + final TestWindowContainer root = builder.setLayer(0).build(); + root.setFillsParent(true); + + builder.setIsVisible(childVisible); + + if (childOrientation != SCREEN_ORIENTATION_UNSET) { + builder.setOrientation(childOrientation); + } + + final TestWindowContainer child1 = root.addChildWindow(builder); + child1.setFillsParent(true); + + assertTrue(root.getOrientation() == expectedOrientation); + } + + @Test public void testGetOrientation_Unset() throws Exception { final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(); final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build(); @@ -407,18 +433,17 @@ public class WindowContainerTests extends WindowTestsBase { invisibleChild1VisibleAndSet.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); // Landscape well because the container is visible and that is what we set on it above. assertEquals(SCREEN_ORIENTATION_LANDSCAPE, invisibleChild1VisibleAndSet.getOrientation()); - // Unset because the container isn't visible even though it has a child that thinks it is - // visible. - assertEquals(SCREEN_ORIENTATION_UNSET, invisible.getOrientation()); - // Unspecified because we are visible and we didn't specify an orientation and there isn't - // a visible child. - assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, root.getOrientation()); + // Landscape because even though the container isn't visible it has a child that is + // specifying it can influence the orientation by being visible. + assertEquals(SCREEN_ORIENTATION_LANDSCAPE, invisible.getOrientation()); + // Landscape because the grandchild is visible and therefore can participate. + assertEquals(SCREEN_ORIENTATION_LANDSCAPE, root.getOrientation()); builder.setIsVisible(true).setLayer(-3); final TestWindowContainer visibleUnset = root.addChildWindow(builder); visibleUnset.setOrientation(SCREEN_ORIENTATION_UNSET); assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnset.getOrientation()); - assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, root.getOrientation()); + assertEquals(SCREEN_ORIENTATION_LANDSCAPE, root.getOrientation()); } @@ -690,6 +715,7 @@ public class WindowContainerTests extends WindowTestsBase { private boolean mIsAnimating; private boolean mIsVisible; private boolean mFillsParent; + private Integer mOrientation; private boolean mOnParentSetCalled; @@ -708,11 +734,13 @@ public class WindowContainerTests extends WindowTestsBase { return 1; }; - TestWindowContainer(int layer, boolean isAnimating, boolean isVisible) { + TestWindowContainer(int layer, boolean isAnimating, boolean isVisible, + Integer orientation) { mLayer = layer; mIsAnimating = isAnimating; mIsVisible = isVisible; mFillsParent = true; + mOrientation = orientation; } TestWindowContainer getParentWindow() { @@ -758,6 +786,11 @@ public class WindowContainerTests extends WindowTestsBase { } @Override + int getOrientation() { + return mOrientation != null ? mOrientation : super.getOrientation(); + } + + @Override boolean fillsParent() { return mFillsParent; } @@ -771,6 +804,7 @@ public class WindowContainerTests extends WindowTestsBase { private int mLayer; private boolean mIsAnimating; private boolean mIsVisible; + private Integer mOrientation; public TestWindowContainerBuilder() { reset(); @@ -791,15 +825,21 @@ public class WindowContainerTests extends WindowTestsBase { return this; } + TestWindowContainerBuilder setOrientation(int orientation) { + mOrientation = orientation; + return this; + } + TestWindowContainerBuilder reset() { mLayer = 0; mIsAnimating = false; mIsVisible = false; + mOrientation = null; return this; } TestWindowContainer build() { - return new TestWindowContainer(mLayer, mIsAnimating, mIsVisible); + return new TestWindowContainer(mLayer, mIsAnimating, mIsVisible, mOrientation); } } } |