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

Commit 173704e5 authored by Naomi Musgrave's avatar Naomi Musgrave Committed by Android (Google) Code Review
Browse files

Merge "Sandbox letterbox and size compat apps" into sc-dev

parents 61e00321 4d3f1c56
Loading
Loading
Loading
Loading
+54 −26
Original line number Diff line number Diff line
@@ -25,8 +25,8 @@ 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.Context;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -59,12 +59,8 @@ import java.util.List;
 * an application window, excluding the system decorations.  The application display area may
 * be smaller than the real display area because the system subtracts the space needed
 * for decor elements such as the status bar.  Use {@link WindowMetrics#getBounds()} to query the
 * application window bounds.</li>
 * <li>The real display area specifies the part of the display that contains content
 * including the system decorations.  Even so, the real display area may be smaller than the
 * physical size of the display if the window manager is emulating a smaller display
 * using (adb shell wm size).  Use the following methods to query the
 * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li>
 * application window bounds. Generally, use {@link WindowManager#getCurrentWindowMetrics()} to
 * query the metrics and perform UI-related actions.</li>
 * </ul>
 * </p><p>
 * A logical display does not necessarily represent a particular physical display device
@@ -677,9 +673,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);
            }
        }

@@ -1191,30 +1187,34 @@ public final class Display {
    }

    /**
     * Gets the real size of the display without subtracting any window decor or
     * applying any compatibility scale factors.
     * Provides the largest {@link Point outSize} an app may expect in the current system state,
     * without subtracting any window decor.
     * <p>
     * The size is adjusted based on the current rotation of the display.
     * The size describes the largest potential area the window might occupy. The size is adjusted
     * based on the current rotation of the display.
     * </p><p>
     * The real size may be smaller than the physical size of the screen when the
     * window manager is emulating a smaller display (using adb shell wm size).
     * </p><p>
     * In general, {@link #getRealSize(Point)} and {@link WindowManager#getMaximumWindowMetrics()}
     * report the same bounds except that certain areas of the display may not be available to
     * windows created in the {@link WindowManager}'s {@link Context}.
     *
     * For example, imagine a device which has a multi-task mode that limits windows to half of the
     * screen. In this case, {@link WindowManager#getMaximumWindowMetrics()} reports the
     * bounds of the screen half where the window is located, while {@link #getRealSize(Point)}
     * still reports the bounds of the whole display.
     * </p>
     *
     * @param outSize Set to the real size of the display.
     *
     * @see WindowManager#getMaximumWindowMetrics()
     */
    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
                            + " for uid " + Process.myUid());
                }
                // 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) {
@@ -1224,9 +1224,11 @@ public final class Display {
    }

    /**
     * Gets display metrics based on the real size of this display.
     * Provides the largest {@link DisplayMetrics outMetrics} an app may expect in the current
     * system state, without subtracting any window decor.
     * <p>
     * The size is adjusted based on the current rotation of the display.
     * The size describes the largest potential area the window might occupy. The size is adjusted
     * based on the current rotation of the display.
     * </p><p>
     * The real size may be smaller than the physical size of the screen when the
     * window manager is emulating a smaller display (using adb shell wm size).
@@ -1237,6 +1239,18 @@ 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
                            + " for uid " + Process.myUid());
                }
                // 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) {
@@ -1245,6 +1259,20 @@ 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.
     * @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;
@@ -605,11 +606,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;
+527 −0

File added.

Preview size limit exceeded, changes collapsed.

+12 −6
Original line number Diff line number Diff line
@@ -1903,12 +1903,6 @@
      "group": "WM_DEBUG_FOCUS_LIGHT",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "123161180": {
      "message": "SEVER CHILDREN",
      "level": "INFO",
      "group": "WM_SHOW_TRANSACTIONS",
      "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
    },
    "140319294": {
      "message": "IME target changed within ActivityRecord",
      "level": "DEBUG",
@@ -2143,6 +2137,12 @@
      "group": "WM_ERROR",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "332390227": {
      "message": "Sandbox max bounds for uid %s to bounds %s due to letterboxing? %s mismatch with parent bounds? %s size compat mode %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "342460966": {
      "message": "DRAG %s: pos=(%d,%d)",
      "level": "INFO",
@@ -2623,6 +2623,12 @@
      "group": "WM_DEBUG_WINDOW_ORGANIZER",
      "at": "com\/android\/server\/wm\/WindowOrganizerController.java"
    },
    "910200295": {
      "message": "Sandbox max bounds due to mismatched orientation with parent, to %s vs DisplayArea %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/Task.java"
    },
    "913494177": {
      "message": "removeAllWindowsIfPossible: removing win=%s",
      "level": "WARN",
+31 −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;
@@ -81,6 +82,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;
@@ -201,6 +203,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;
@@ -266,6 +269,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;
@@ -6737,6 +6741,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? %s mismatch with parent bounds? %s size compat "
                        + "mode %s", getUid(),
                        resolvedConfig.windowConfiguration.getBounds(), mLetterbox != null,
                        !matchParentBounds(), inSizeCompatMode());
            }
            resolvedConfig.windowConfiguration
                    .setMaxBounds(resolvedConfig.windowConfiguration.getBounds());
        }
    }

    /**
@@ -6920,6 +6938,19 @@ 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 when this is letterboxed or in size compat mode.
        return mLetterbox != null || !matchParentBounds() || inSizeCompatMode();
    }

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