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

Commit 989861f0 authored by Louis Chang's avatar Louis Chang Committed by Android (Google) Code Review
Browse files

Merge "Ignore fixed-orientation request on large screen device for AE"

parents 2f3f0fcc fe12e780
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -52504,6 +52504,7 @@ package android.view {
    method public default void removeCrossWindowBlurEnabledListener(@NonNull java.util.function.Consumer<java.lang.Boolean>);
    method public void removeViewImmediate(android.view.View);
    field public static final String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE = "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE";
    field public static final String PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED = "android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED";
  }
  public static class WindowManager.BadTokenException extends java.lang.RuntimeException {
+22 −0
Original line number Diff line number Diff line
@@ -860,6 +860,28 @@ public interface WindowManager extends ViewManager {
    String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE =
            "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE";

    /**
     * Application level {@link android.content.pm.PackageManager.Property PackageManager
     * .Property} that an app can specify to inform the system that the app is ActivityEmbedding
     * split feature enabled.
     *
     * <p>With this property, the system could provide custom behaviors for the apps that are
     * ActivityEmbedding split feature enabled. For example, the fixed-portrait orientation
     * requests of the activities could be ignored by the system in order to provide seamless
     * ActivityEmbedding split experiences while holding the large-screen devices in landscape mode.
     *
     * <p><b>Syntax:</b>
     * <pre>
     * &lt;application&gt;
     *   &lt;property
     *     android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED"
     *     android:value="true|false"/&gt;
     * &lt;/application&gt;
     * </pre>
     */
    String PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED =
            "android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED";

    /**
     * Request for keyboard shortcuts to be retrieved asynchronously.
     *
+44 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_UNSET;
@@ -931,6 +932,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    // is launched from this ActivityRecord. Touches are always allowed within the same uid.
    int mAllowedTouchUid;

    // Whether the ActivityEmbedding is enabled on the app.
    private final boolean mAppActivityEmbeddingSplitsEnabled;

    private final Runnable mPauseTimeoutRunnable = new Runnable() {
        @Override
        public void run() {
@@ -2116,6 +2120,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        mActivityRecordInputSink = new ActivityRecordInputSink(this, sourceRecord);

        updateEnterpriseThumbnailDrawable(mAtmService.getUiContext());

        boolean appActivityEmbeddingEnabled = false;
        try {
            appActivityEmbeddingEnabled = WindowManagerService.sWindowExtensionsEnabled
                    && mAtmService.mContext.getPackageManager()
                            .getProperty(PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED, packageName)
                            .getBoolean();
        } catch (PackageManager.NameNotFoundException e) {
            // No such property name.
        }
        mAppActivityEmbeddingSplitsEnabled = appActivityEmbeddingEnabled;
    }

    /**
@@ -7731,12 +7746,33 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
    }

    /**
     * Ignores the activity orientation request if the App is fixed-orientation portrait and has
     * ActivityEmbedding enabled and is currently running on large screen display. Or the display
     * could be rotated to portrait and not having large enough width for app to split.
     */
    @VisibleForTesting
    boolean shouldIgnoreOrientationRequests() {
        if (!mAppActivityEmbeddingSplitsEnabled
                || !ActivityInfo.isFixedOrientationPortrait(mOrientation)
                || task.inMultiWindowMode()) {
            return false;
        }

        return getTask().getConfiguration().smallestScreenWidthDp
                >= mAtmService.mLargeScreenSmallestScreenWidthDp;
    }

    /**
     * We override because this class doesn't want its children affecting its reported orientation
     * in anyway.
     */
    @Override
    int getOrientation(int candidate) {
        if (shouldIgnoreOrientationRequests()) {
            return SCREEN_ORIENTATION_UNSET;
        }

        if (candidate == SCREEN_ORIENTATION_BEHIND) {
            // Allow app to specify orientation regardless of its visibility state if the current
            // candidate want us to use orientation behind. I.e. the visible app on-top of this one
@@ -8274,6 +8310,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return orientationRespectedWithInsets;
    }

    @Override
    boolean handlesOrientationChangeFromDescendant() {
        if (shouldIgnoreOrientationRequests()) {
            return false;
        }
        return super.handlesOrientationChangeFromDescendant();
    }

    /**
     * Computes bounds (letterbox or pillarbox) when either:
     * 1. The parent doesn't handle the orientation change and the requested orientation is
+10 −0
Original line number Diff line number Diff line
@@ -434,6 +434,16 @@ public class WindowManagerService extends IWindowManager.Stub
    static final boolean ENABLE_FIXED_ROTATION_TRANSFORM =
            SystemProperties.getBoolean("persist.wm.fixed_rotation_transform", true);

    /**
     * Whether the device supports the WindowManager Extensions.
     * OEMs can enable this by having their device config to inherit window_extensions.mk, such as:
     * <pre>
     * $(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)
     * </pre>
     */
    static final boolean sWindowExtensionsEnabled =
            SystemProperties.getBoolean("persist.wm.extensions.enabled", false);

    // Enums for animation scale update types.
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE})
+4 −0
Original line number Diff line number Diff line
@@ -2533,6 +2533,10 @@ public class ActivityRecordTests extends WindowTestsBase {
        // Can specify orientation if app doesn't occludes parent.
        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, activity.getOrientation());

        doReturn(true).when(activity).shouldIgnoreOrientationRequests();
        assertEquals(SCREEN_ORIENTATION_UNSET, activity.getOrientation());

        doReturn(false).when(activity).shouldIgnoreOrientationRequests();
        activity.setOccludesParent(true);
        activity.setVisible(false);
        activity.setVisibleRequested(false);