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

Commit 93281eda authored by Naomi Musgrave's avatar Naomi Musgrave
Browse files

Sandbox letterbox and size compat apps

Sandbox Display#getRealSize and WindowManager
bounds when letterbox or size compat mode are
applied to the configuration. Display uses
this field to provide the sandboxed display
size.

This reverts commit 0ba61856.

Test: atest WindowConfigurationTests
Test: atest FrameworksMockingCoreTests:android.view.DisplayTests
Test: atest WmTests:SizeCompatTests
Bug: 181219241

Change-Id: I86e8edb8368269da8e02cf34f429d245550666c6
parent 46c0a4b9
Loading
Loading
Loading
Loading
+45 −3
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.app.KeyguardManager;
import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -678,9 +679,9 @@ public final class Display {
    @UnsupportedAppUsage
    public DisplayAdjustments getDisplayAdjustments() {
        if (mResources != null) {
            final DisplayAdjustments currentAdjustements = mResources.getDisplayAdjustments();
            if (!mDisplayAdjustments.equals(currentAdjustements)) {
                mDisplayAdjustments = new DisplayAdjustments(currentAdjustements);
            final DisplayAdjustments currentAdjustments = mResources.getDisplayAdjustments();
            if (!mDisplayAdjustments.equals(currentAdjustments)) {
                mDisplayAdjustments = new DisplayAdjustments(currentAdjustments);
            }
        }

@@ -1278,6 +1279,18 @@ public final class Display {
    public void getRealSize(Point outSize) {
        synchronized (this) {
            updateDisplayInfoLocked();
            if (shouldReportMaxBounds()) {
                final Rect bounds = mResources.getConfiguration()
                        .windowConfiguration.getMaxBounds();
                outSize.x = bounds.width();
                outSize.y = bounds.height();
                if (DEBUG) {
                    Log.d(TAG, "getRealSize determined from max bounds: " + outSize);
                }
                // Skip adjusting by fixed rotation, since if it is necessary, the configuration
                // should already reflect the expected rotation.
                return;
            }
            outSize.x = mDisplayInfo.logicalWidth;
            outSize.y = mDisplayInfo.logicalHeight;
            if (mMayAdjustByFixedRotation) {
@@ -1336,6 +1349,17 @@ public final class Display {
    public void getRealMetrics(DisplayMetrics outMetrics) {
        synchronized (this) {
            updateDisplayInfoLocked();
            if (shouldReportMaxBounds()) {
                mDisplayInfo.getMaxBoundsMetrics(outMetrics,
                        CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,
                        mResources.getConfiguration());
                if (DEBUG) {
                    Log.d(TAG, "getRealMetrics determined from max bounds: " + outMetrics);
                }
                // Skip adjusting by fixed rotation, since if it is necessary, the configuration
                // should already reflect the expected rotation.
                return;
            }
            mDisplayInfo.getLogicalMetrics(outMetrics,
                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
            if (mMayAdjustByFixedRotation) {
@@ -1344,6 +1368,24 @@ public final class Display {
        }
    }

    /**
     * Determines if {@link WindowConfiguration#getMaxBounds()} should be reported as the
     * display dimensions. The max bounds field may be smaller than the logical dimensions
     * when apps need to be sandboxed.
     *
     * Depends upon {@link WindowConfiguration#getMaxBounds()} being set in
     * {@link com.android.server.wm.ConfigurationContainer#providesMaxBounds()}. In most cases, this
     * value reflects the size of the current DisplayArea.
     * @return {@code true} when max bounds should be applied.
     */
    private boolean shouldReportMaxBounds() {
        if (mResources == null) {
            return false;
        }
        final Configuration config = mResources.getConfiguration();
        return config != null && !config.windowConfiguration.getMaxBounds().isEmpty();
    }

    /**
     * Gets the state of the display, such as whether it is on or off.
     *
+19 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.view.DisplayInfoProto.LOGICAL_WIDTH;
import static android.view.DisplayInfoProto.NAME;

import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -615,11 +616,29 @@ public final class DisplayInfo implements Parcelable {
        getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
    }

    /**
     * Populates {@code outMetrics} with details of the logical display. Bounds are limited
     * by the logical size of the display.
     *
     * @param outMetrics the {@link DisplayMetrics} to be populated
     * @param compatInfo the {@link CompatibilityInfo} to be applied
     * @param configuration the {@link Configuration}
     */
    public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
            Configuration configuration) {
        getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
    }

    /**
     * Similar to {@link #getLogicalMetrics}, but the limiting bounds are determined from
     * {@link WindowConfiguration#getMaxBounds()}
     */
    public void getMaxBoundsMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
            Configuration configuration) {
        Rect bounds = configuration.windowConfiguration.getMaxBounds();
        getMetricsWithSize(outMetrics, compatInfo, configuration, bounds.width(), bounds.height());
    }

    public int getNaturalWidth() {
        return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
                logicalWidth : logicalHeight;
+531 −0

File added.

Preview size limit exceeded, changes collapsed.

+6 −0
Original line number Diff line number Diff line
@@ -1219,6 +1219,12 @@
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DragState.java"
    },
    "-681380736": {
      "message": "Sandbox max bounds for uid %s to bounds %s due to letterboxing from mismatch with parent bounds? %s size compat mode %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "-677449371": {
      "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b",
      "level": "DEBUG",
+32 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
@@ -86,6 +87,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.res.Configuration.EMPTY;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -205,6 +207,7 @@ import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainerChildProto.ACTIVITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -278,6 +281,7 @@ import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.permission.PermissionManager;
import android.service.dreams.DreamActivity;
import android.service.dreams.DreamManagerInternal;
import android.service.voice.IVoiceInteractionSession;
@@ -6955,6 +6959,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // layout traversals.
        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
        getResolvedOverrideConfiguration().seq = mConfigurationSeq;

        // Sandbox max bounds by setting it to the app bounds, if activity is letterboxed or in
        // size compat mode.
        if (providesMaxBounds()) {
            if (DEBUG_CONFIGURATION) {
                ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s "
                        + "due to letterboxing from mismatch with parent bounds? %s size compat "
                        + "mode %s", getUid(),
                        resolvedConfig.windowConfiguration.getBounds(), !matchParentBounds(),
                        inSizeCompatMode());
            }
            resolvedConfig.windowConfiguration
                    .setMaxBounds(resolvedConfig.windowConfiguration.getBounds());
        }
    }

    /**
@@ -7296,6 +7314,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return super.getBounds();
    }

    @Override
    public boolean providesMaxBounds() {
        // System and SystemUI should always be able to access the physical display bounds,
        // so do not provide it with the overridden maximum bounds.
        // TODO(b/179179513) check WindowState#mOwnerCanAddInternalSystemWindow instead
        if (getUid() == SYSTEM_UID || PermissionManager.checkPermission(INTERNAL_SYSTEM_WINDOW,
                getPid(), info.applicationInfo.uid) == PERMISSION_GRANTED) {
            return false;
        }
        // Max bounds should be sandboxed where an activity is letterboxed (activity bounds will be
        // smaller than task bounds) or put in size compat mode.
        return !matchParentBounds() || inSizeCompatMode();
    }

    @VisibleForTesting
    @Override
    Rect getAnimationBounds(int appRootTaskClipMode) {
Loading