Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 537ece98 authored by Bryce Lee's avatar Bryce Lee Committed by android-build-merger
Browse files

Merge "Prevent non-fullscreen activities from influencing orientation" into oc-dev

am: 8a698a17

Change-Id: I7dd30182184fc5ce6ec5e9750eaa26f174b79b38
parents 12018312 8a698a17
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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);
        }
+29 −2
Original line number Diff line number Diff line
@@ -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,11 +978,19 @@ 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) {
+7 −9
Original line number Diff line number Diff line
@@ -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);
+8 −1
Original line number Diff line number Diff line
@@ -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;
        }
+2 −2
Original line number Diff line number Diff line
@@ -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;