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

Commit 5b15d13d authored by Massimo Carli's avatar Massimo Carli
Browse files

Prevent NullPointerException in ActivityRecord when in Size Compat Mode

When checking if a translucent activity strategy was in place we
also checked if the current activity bounds was matching the
bounds of the parent. When the translucent activities strategy
is in place, ActivityRecord#matchParentBounds() can return true
making LetterboxUiController#hasInheritedLetterboxBehavior return
false. When this happens it's possible that
ActivityRecord#getCompatDisplayInsets() returns null and then
the NullPointerException.

This CL also adds additional checks to prevent NullPointerException
also reducing ActivityRecord#getCompatDisplayInsets() invocation using local
variables.

Fixes: 271427810
Test: Existing presubmit tests.

Change-Id: I10591cd59057f7dc2e03653747bd541c66f23d4a
parent 5480a55e
Loading
Loading
Loading
Loading
+14 −13
Original line number Diff line number Diff line
@@ -8099,9 +8099,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        if (isFixedOrientationLetterboxAllowed) {
            resolveFixedOrientationConfiguration(newParentConfiguration);
        }

        if (getCompatDisplayInsets() != null) {
            resolveSizeCompatModeConfiguration(newParentConfiguration);
        final CompatDisplayInsets compatDisplayInsets = getCompatDisplayInsets();
        if (compatDisplayInsets != null) {
            resolveSizeCompatModeConfiguration(newParentConfiguration, compatDisplayInsets);
        } else if (inMultiWindowMode() && !isFixedOrientationLetterboxAllowed) {
            // We ignore activities' requested orientation in multi-window modes. They may be
            // taken into consideration in resolveFixedOrientationConfiguration call above.
@@ -8118,7 +8118,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            resolveAspectRatioRestriction(newParentConfiguration);
        }

        if (isFixedOrientationLetterboxAllowed || getCompatDisplayInsets() != null
        if (isFixedOrientationLetterboxAllowed || compatDisplayInsets != null
                // In fullscreen, can be letterboxed for aspect ratio.
                || !inMultiWindowMode()) {
            updateResolvedBoundsPosition(newParentConfiguration);
@@ -8126,7 +8126,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

        boolean isIgnoreOrientationRequest = mDisplayContent != null
                && mDisplayContent.getIgnoreOrientationRequest();
        if (getCompatDisplayInsets() == null
        if (compatDisplayInsets == null
                // for size compat mode set in updateCompatDisplayInsets
                // Fixed orientation letterboxing is possible on both large screen devices
                // with ignoreOrientationRequest enabled and on phones in split screen even with
@@ -8173,7 +8173,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                        info.neverSandboxDisplayApis(sConstrainDisplayApisConfig),
                        info.alwaysSandboxDisplayApis(sConstrainDisplayApisConfig),
                        !matchParentBounds(),
                        getCompatDisplayInsets() != null,
                        compatDisplayInsets != null,
                        shouldCreateCompatDisplayInsets());
            }
            resolvedConfig.windowConfiguration.setMaxBounds(mTmpBounds);
@@ -8581,7 +8581,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * Resolves consistent screen configuration for orientation and rotation changes without
     * inheriting the parent bounds.
     */
    private void resolveSizeCompatModeConfiguration(Configuration newParentConfiguration) {
    private void resolveSizeCompatModeConfiguration(Configuration newParentConfiguration,
            @NonNull CompatDisplayInsets compatDisplayInsets) {
        final Configuration resolvedConfig = getResolvedOverrideConfiguration();
        final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();

@@ -8602,13 +8603,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                ? requestedOrientation
                // We should use the original orientation of the activity when possible to avoid
                // forcing the activity in the opposite orientation.
                : getCompatDisplayInsets().mOriginalRequestedOrientation != ORIENTATION_UNDEFINED
                        ? getCompatDisplayInsets().mOriginalRequestedOrientation
                : compatDisplayInsets.mOriginalRequestedOrientation != ORIENTATION_UNDEFINED
                        ? compatDisplayInsets.mOriginalRequestedOrientation
                        : newParentConfiguration.orientation;
        int rotation = newParentConfiguration.windowConfiguration.getRotation();
        final boolean isFixedToUserRotation = mDisplayContent == null
                || mDisplayContent.getDisplayRotation().isFixedToUserRotation();
        if (!isFixedToUserRotation && !getCompatDisplayInsets().mIsFloating) {
        if (!isFixedToUserRotation && !compatDisplayInsets.mIsFloating) {
            // Use parent rotation because the original display can be rotated.
            resolvedConfig.windowConfiguration.setRotation(rotation);
        } else {
@@ -8624,11 +8625,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // rely on them to contain the original and unchanging width and height of the app.
        final Rect containingAppBounds = new Rect();
        final Rect containingBounds = mTmpBounds;
        getCompatDisplayInsets().getContainerBounds(containingAppBounds, containingBounds, rotation,
        compatDisplayInsets.getContainerBounds(containingAppBounds, containingBounds, rotation,
                orientation, orientationRequested, isFixedToUserRotation);
        resolvedBounds.set(containingBounds);
        // The size of floating task is fixed (only swap), so the aspect ratio is already correct.
        if (!getCompatDisplayInsets().mIsFloating) {
        if (!compatDisplayInsets.mIsFloating) {
            mIsAspectRatioApplied =
                    applyAspectRatio(resolvedBounds, containingAppBounds, containingBounds);
        }
@@ -8637,7 +8638,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // are calculated in compat container space. The actual position on screen will be applied
        // later, so the calculation is simpler that doesn't need to involve offset from parent.
        getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
                getCompatDisplayInsets());
                compatDisplayInsets);
        // Use current screen layout as source because the size of app is independent to parent.
        resolvedConfig.screenLayout = TaskFragment.computeScreenLayoutOverride(
                getConfiguration().screenLayout, resolvedConfig.screenWidthDp,
+1 −1
Original line number Diff line number Diff line
@@ -1433,7 +1433,7 @@ final class LetterboxUiController {
     * the first opaque activity beneath.
     */
    boolean hasInheritedLetterboxBehavior() {
        return mLetterboxConfigListener != null && !mActivityRecord.matchParentBounds();
        return mLetterboxConfigListener != null;
    }

    /**