Loading core/java/android/app/Activity.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -131,6 +131,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.List; import java.util.List; import static android.os.Build.VERSION_CODES.O; import static java.lang.Character.MIN_VALUE; import static java.lang.Character.MIN_VALUE; /** /** Loading Loading @@ -974,6 +975,18 @@ public class Activity extends ContextThemeWrapper @CallSuper @CallSuper protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState); if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState); if (getApplicationInfo().targetSdkVersion >= O && mActivityInfo.isFixedOrientation()) { final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window); final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta); ta.recycle(); if (isTranslucentOrFloating) { throw new IllegalStateException( "Only fullscreen opaque activities can request orientation"); } } if (mLastNonConfigurationInstances != null) { if (mLastNonConfigurationInstances != null) { mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders); mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders); } } Loading core/java/android/content/pm/ActivityInfo.java +29 −2 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.content.Intent; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Configuration; import android.content.res.Configuration.NativeConfig; import android.content.res.Configuration.NativeConfig; import android.content.res.TypedArray; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.util.Printer; import android.util.Printer; Loading Loading @@ -440,7 +441,6 @@ public class ActivityInfo extends ComponentInfo * @hide * @hide */ */ public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x400000; public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x400000; /** /** * @hide Bit in {@link #flags}: If set, this component will only be seen * @hide Bit in {@link #flags}: If set, this component will only be seen * by the system user. Only works with broadcast receivers. Set from the * by the system user. Only works with broadcast receivers. Set from the Loading Loading @@ -978,11 +978,19 @@ public class ActivityInfo extends ComponentInfo * Returns true if the activity's orientation is fixed. * Returns true if the activity's orientation is fixed. * @hide * @hide */ */ boolean isFixedOrientation() { public boolean isFixedOrientation() { return isFixedOrientationLandscape() || isFixedOrientationPortrait() return isFixedOrientationLandscape() || isFixedOrientationPortrait() || screenOrientation == SCREEN_ORIENTATION_LOCKED; || screenOrientation == SCREEN_ORIENTATION_LOCKED; } } /** * Returns true if the specified orientation is considered fixed. * @hide */ static public boolean isFixedOrientation(int orientation) { return isFixedOrientationLandscape(orientation) || isFixedOrientationPortrait(orientation); } /** /** * Returns true if the activity's orientation is fixed to landscape. * Returns true if the activity's orientation is fixed to landscape. * @hide * @hide Loading Loading @@ -1162,6 +1170,25 @@ public class ActivityInfo extends ComponentInfo dest.writeFloat(maxAspectRatio); dest.writeFloat(maxAspectRatio); } } /** * Determines whether the {@link Activity} is considered translucent or floating. * @hide */ public static boolean isTranslucentOrFloating(TypedArray attributes) { final boolean isTranslucent = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, false); final boolean isSwipeToDismiss = !attributes.hasValue( com.android.internal.R.styleable.Window_windowIsTranslucent) && attributes.getBoolean( com.android.internal.R.styleable.Window_windowSwipeToDismiss, false); final boolean isFloating = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false); return isFloating || isTranslucent || isSwipeToDismiss; } public static final Parcelable.Creator<ActivityInfo> CREATOR public static final Parcelable.Creator<ActivityInfo> CREATOR = new Parcelable.Creator<ActivityInfo>() { = new Parcelable.Creator<ActivityInfo>() { public ActivityInfo createFromParcel(Parcel source) { public ActivityInfo createFromParcel(Parcel source) { Loading services/core/java/com/android/server/am/ActivityRecord.java +7 −9 Original line number Original line Diff line number Diff line Loading @@ -131,6 +131,7 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.os.Bundle; import android.os.Debug; import android.os.Debug; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -892,15 +893,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo Entry ent = AttributeCache.instance().get(packageName, Entry ent = AttributeCache.instance().get(packageName, realTheme, com.android.internal.R.styleable.Window, userId); realTheme, com.android.internal.R.styleable.Window, userId); final boolean translucent = ent != null && (ent.array.getBoolean( fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array); com.android.internal.R.styleable.Window_windowIsTranslucent, false) || (!ent.array.hasValue( com.android.internal.R.styleable.Window_windowIsTranslucent) && ent.array.getBoolean( com.android.internal.R.styleable.Window_windowSwipeToDismiss, false))); fullscreen = ent != null && !ent.array.getBoolean( com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent; noDisplay = ent != null && ent.array.getBoolean( noDisplay = ent != null && ent.array.getBoolean( com.android.internal.R.styleable.Window_windowNoDisplay, false); com.android.internal.R.styleable.Window_windowNoDisplay, false); Loading Loading @@ -2186,6 +2179,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } } void setRequestedOrientation(int requestedOrientation) { void setRequestedOrientation(int requestedOrientation) { if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen && appInfo.targetSdkVersion >= O) { throw new IllegalStateException("Only fullscreen activities can request orientation"); } final int displayId = getDisplayId(); final int displayId = getDisplayId(); final Configuration displayConfig = final Configuration displayConfig = mStackSupervisor.getDisplayOverrideConfiguration(displayId); mStackSupervisor.getDisplayOverrideConfiguration(displayId); Loading services/core/java/com/android/server/wm/AppWindowToken.java +8 −1 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.app.Activity; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Rect; import android.os.Binder; import android.os.Binder; import android.os.Build; import android.os.Debug; import android.os.Debug; import android.os.IBinder; import android.os.IBinder; import android.os.SystemClock; import android.os.SystemClock; Loading @@ -70,6 +71,8 @@ import java.io.PrintWriter; import java.util.ArrayDeque; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.ArrayList; import static android.os.Build.VERSION_CODES.O; class AppTokenList extends ArrayList<AppWindowToken> { class AppTokenList extends ArrayList<AppWindowToken> { } } Loading Loading @@ -1245,7 +1248,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree */ */ @Override @Override int getOrientation(int candidate) { int getOrientation(int candidate) { if (!fillsParent()) { // We do not allow non-fullscreen apps to influence orientation at and beyond O. While we do // throw an exception in {@link Activity#onCreate} and // {@link Activity#setRequestedOrientation}, we also ignore the orientation here so that // other calculations aren't affected. if (!fillsParent() && mTargetSdk >= O) { // Can't specify orientation if app doesn't fill parent. // Can't specify orientation if app doesn't fill parent. return SCREEN_ORIENTATION_UNSET; return SCREEN_ORIENTATION_UNSET; } } Loading services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -173,8 +173,8 @@ public class AppWindowTokenTests extends WindowTestsBase { token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); token.setFillsParent(false); token.setFillsParent(false); // Can not specify orientation if app doesn't fill parent. // Can specify orientation if app doesn't fill parent. Allowed for SDK <= 25. assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation()); assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation()); token.setFillsParent(true); token.setFillsParent(true); token.hidden = true; token.hidden = true; Loading Loading
core/java/android/app/Activity.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -131,6 +131,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.List; import java.util.List; import static android.os.Build.VERSION_CODES.O; import static java.lang.Character.MIN_VALUE; import static java.lang.Character.MIN_VALUE; /** /** Loading Loading @@ -974,6 +975,18 @@ public class Activity extends ContextThemeWrapper @CallSuper @CallSuper protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState); if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState); if (getApplicationInfo().targetSdkVersion >= O && mActivityInfo.isFixedOrientation()) { final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window); final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta); ta.recycle(); if (isTranslucentOrFloating) { throw new IllegalStateException( "Only fullscreen opaque activities can request orientation"); } } if (mLastNonConfigurationInstances != null) { if (mLastNonConfigurationInstances != null) { mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders); mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders); } } Loading
core/java/android/content/pm/ActivityInfo.java +29 −2 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.content.Intent; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Configuration; import android.content.res.Configuration.NativeConfig; import android.content.res.Configuration.NativeConfig; import android.content.res.TypedArray; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.util.Printer; import android.util.Printer; Loading Loading @@ -440,7 +441,6 @@ public class ActivityInfo extends ComponentInfo * @hide * @hide */ */ public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x400000; public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x400000; /** /** * @hide Bit in {@link #flags}: If set, this component will only be seen * @hide Bit in {@link #flags}: If set, this component will only be seen * by the system user. Only works with broadcast receivers. Set from the * by the system user. Only works with broadcast receivers. Set from the Loading Loading @@ -978,11 +978,19 @@ public class ActivityInfo extends ComponentInfo * Returns true if the activity's orientation is fixed. * Returns true if the activity's orientation is fixed. * @hide * @hide */ */ boolean isFixedOrientation() { public boolean isFixedOrientation() { return isFixedOrientationLandscape() || isFixedOrientationPortrait() return isFixedOrientationLandscape() || isFixedOrientationPortrait() || screenOrientation == SCREEN_ORIENTATION_LOCKED; || screenOrientation == SCREEN_ORIENTATION_LOCKED; } } /** * Returns true if the specified orientation is considered fixed. * @hide */ static public boolean isFixedOrientation(int orientation) { return isFixedOrientationLandscape(orientation) || isFixedOrientationPortrait(orientation); } /** /** * Returns true if the activity's orientation is fixed to landscape. * Returns true if the activity's orientation is fixed to landscape. * @hide * @hide Loading Loading @@ -1162,6 +1170,25 @@ public class ActivityInfo extends ComponentInfo dest.writeFloat(maxAspectRatio); dest.writeFloat(maxAspectRatio); } } /** * Determines whether the {@link Activity} is considered translucent or floating. * @hide */ public static boolean isTranslucentOrFloating(TypedArray attributes) { final boolean isTranslucent = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, false); final boolean isSwipeToDismiss = !attributes.hasValue( com.android.internal.R.styleable.Window_windowIsTranslucent) && attributes.getBoolean( com.android.internal.R.styleable.Window_windowSwipeToDismiss, false); final boolean isFloating = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false); return isFloating || isTranslucent || isSwipeToDismiss; } public static final Parcelable.Creator<ActivityInfo> CREATOR public static final Parcelable.Creator<ActivityInfo> CREATOR = new Parcelable.Creator<ActivityInfo>() { = new Parcelable.Creator<ActivityInfo>() { public ActivityInfo createFromParcel(Parcel source) { public ActivityInfo createFromParcel(Parcel source) { Loading
services/core/java/com/android/server/am/ActivityRecord.java +7 −9 Original line number Original line Diff line number Diff line Loading @@ -131,6 +131,7 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.os.Bundle; import android.os.Debug; import android.os.Debug; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -892,15 +893,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo Entry ent = AttributeCache.instance().get(packageName, Entry ent = AttributeCache.instance().get(packageName, realTheme, com.android.internal.R.styleable.Window, userId); realTheme, com.android.internal.R.styleable.Window, userId); final boolean translucent = ent != null && (ent.array.getBoolean( fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array); com.android.internal.R.styleable.Window_windowIsTranslucent, false) || (!ent.array.hasValue( com.android.internal.R.styleable.Window_windowIsTranslucent) && ent.array.getBoolean( com.android.internal.R.styleable.Window_windowSwipeToDismiss, false))); fullscreen = ent != null && !ent.array.getBoolean( com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent; noDisplay = ent != null && ent.array.getBoolean( noDisplay = ent != null && ent.array.getBoolean( com.android.internal.R.styleable.Window_windowNoDisplay, false); com.android.internal.R.styleable.Window_windowNoDisplay, false); Loading Loading @@ -2186,6 +2179,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } } void setRequestedOrientation(int requestedOrientation) { void setRequestedOrientation(int requestedOrientation) { if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen && appInfo.targetSdkVersion >= O) { throw new IllegalStateException("Only fullscreen activities can request orientation"); } final int displayId = getDisplayId(); final int displayId = getDisplayId(); final Configuration displayConfig = final Configuration displayConfig = mStackSupervisor.getDisplayOverrideConfiguration(displayId); mStackSupervisor.getDisplayOverrideConfiguration(displayId); Loading
services/core/java/com/android/server/wm/AppWindowToken.java +8 −1 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.app.Activity; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Rect; import android.os.Binder; import android.os.Binder; import android.os.Build; import android.os.Debug; import android.os.Debug; import android.os.IBinder; import android.os.IBinder; import android.os.SystemClock; import android.os.SystemClock; Loading @@ -70,6 +71,8 @@ import java.io.PrintWriter; import java.util.ArrayDeque; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.ArrayList; import static android.os.Build.VERSION_CODES.O; class AppTokenList extends ArrayList<AppWindowToken> { class AppTokenList extends ArrayList<AppWindowToken> { } } Loading Loading @@ -1245,7 +1248,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree */ */ @Override @Override int getOrientation(int candidate) { int getOrientation(int candidate) { if (!fillsParent()) { // We do not allow non-fullscreen apps to influence orientation at and beyond O. While we do // throw an exception in {@link Activity#onCreate} and // {@link Activity#setRequestedOrientation}, we also ignore the orientation here so that // other calculations aren't affected. if (!fillsParent() && mTargetSdk >= O) { // Can't specify orientation if app doesn't fill parent. // Can't specify orientation if app doesn't fill parent. return SCREEN_ORIENTATION_UNSET; return SCREEN_ORIENTATION_UNSET; } } Loading
services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -173,8 +173,8 @@ public class AppWindowTokenTests extends WindowTestsBase { token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); token.setFillsParent(false); token.setFillsParent(false); // Can not specify orientation if app doesn't fill parent. // Can specify orientation if app doesn't fill parent. Allowed for SDK <= 25. assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation()); assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation()); token.setFillsParent(true); token.setFillsParent(true); token.hidden = true; token.hidden = true; Loading