summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Bryce Lee <brycelee@google.com> 2017-05-10 14:45:34 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-05-10 14:45:39 +0000
commit8a698a17215919e6ce575ec80d091381f0482d27 (patch)
tree26c285f66203540cb73d6cceafe0740dfd5dc235
parentb94abe5e30f9be317cee31331e15fa1fab7898fc (diff)
parent39791594560b2326625b663ed6796882900c220f (diff)
Merge "Prevent non-fullscreen activities from influencing orientation" into oc-dev
-rw-r--r--core/java/android/app/Activity.java13
-rw-r--r--core/java/android/content/pm/ActivityInfo.java31
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java16
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java4
5 files changed, 59 insertions, 14 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 26ac6adce95d..4dea0e046f5a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -131,6 +131,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import static android.os.Build.VERSION_CODES.O;
import static java.lang.Character.MIN_VALUE;
/**
@@ -974,6 +975,18 @@ public class Activity extends ContextThemeWrapper
@CallSuper
protected void onCreate(@Nullable Bundle 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) {
mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 587ab3b3b743..9a014766c206 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Configuration.NativeConfig;
+import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Printer;
@@ -440,7 +441,6 @@ public class ActivityInfo extends ComponentInfo
* @hide
*/
public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x400000;
-
/**
* @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
@@ -978,12 +978,20 @@ public class ActivityInfo extends ComponentInfo
* Returns true if the activity's orientation is fixed.
* @hide
*/
- boolean isFixedOrientation() {
+ public boolean isFixedOrientation() {
return isFixedOrientationLandscape() || isFixedOrientationPortrait()
|| 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.
* @hide
*/
@@ -1162,6 +1170,25 @@ public class ActivityInfo extends ComponentInfo
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
= new Parcelable.Creator<ActivityInfo>() {
public ActivityInfo createFromParcel(Parcel source) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index a5cfbcf30b3f..5c57be283793 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -131,6 +131,7 @@ import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Rect;
+import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
@@ -892,15 +893,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
Entry ent = AttributeCache.instance().get(packageName,
realTheme, com.android.internal.R.styleable.Window, userId);
- final boolean translucent = ent != null && (ent.array.getBoolean(
- 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;
+ fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);
noDisplay = ent != null && ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
@@ -2186,6 +2179,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
}
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 Configuration displayConfig =
mStackSupervisor.getDisplayOverrideConfiguration(displayId);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 640bac28efdf..982561c989ff 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -53,6 +53,7 @@ import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Binder;
+import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
import android.os.SystemClock;
@@ -70,6 +71,8 @@ import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
+import static android.os.Build.VERSION_CODES.O;
+
class AppTokenList extends ArrayList<AppWindowToken> {
}
@@ -1245,7 +1248,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
*/
@Override
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.
return SCREEN_ORIENTATION_UNSET;
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 876008b7412b..46f10c1959ff 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -173,8 +173,8 @@ public class AppWindowTokenTests extends WindowTestsBase {
token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
token.setFillsParent(false);
- // Can not specify orientation if app doesn't fill parent.
- assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());
+ // Can specify orientation if app doesn't fill parent. Allowed for SDK <= 25.
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation());
token.setFillsParent(true);
token.hidden = true;