Merge "Allow opening activity to specify orientation."

This commit is contained in:
Bryce Lee
2017-02-01 22:54:28 +00:00
committed by Android (Google) Code Review
5 changed files with 81 additions and 22 deletions

View File

@@ -1902,11 +1902,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());

View File

@@ -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

View File

@@ -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. */

View File

@@ -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

View File

@@ -387,6 +387,32 @@ public class WindowContainerTests extends WindowTestsBase {
assertTrue(gotException);
}
@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();
@@ -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() {
@@ -757,6 +785,11 @@ public class WindowContainerTests extends WindowTestsBase {
return mIsVisible;
}
@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);
}
}
}