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

Commit d1ce559f authored by Peiyong Lin's avatar Peiyong Lin Committed by Automerger Merge Worker
Browse files

Merge "Implement per-app window resizing override." into sc-dev am: 277cfb35

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13438581

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I062a81166f21b5b26e769f5b0fc6ae2c31d4f3d6
parents 2156e8d4 277cfb35
Loading
Loading
Loading
Loading
+28 −3
Original line number Diff line number Diff line
@@ -88,6 +88,11 @@ public class CompatibilityInfo implements Parcelable {
     */
    private static final int NEEDS_COMPAT_RES = 16;

    /**
     * Set if the application needs to be forcibly downscaled
     */
    private static final int HAS_OVERRIDE_SCALING = 32;

    /**
     * The effective screen density we have selected for this application.
     */
@@ -107,6 +112,11 @@ public class CompatibilityInfo implements Parcelable {
    @UnsupportedAppUsage
    public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
            boolean forceCompat) {
        this(appInfo, screenLayout, sw, forceCompat, 1f);
    }

    public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
            boolean forceCompat, float overrideScale) {
        int compatFlags = 0;

        if (appInfo.targetSdkVersion < VERSION_CODES.O) {
@@ -241,7 +251,12 @@ public class CompatibilityInfo implements Parcelable {
                compatFlags |= NEVER_NEEDS_COMPAT;
            }

            if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
            if (overrideScale != 1.0f) {
                applicationDensity = DisplayMetrics.DENSITY_DEFAULT;
                applicationScale = overrideScale;
                applicationInvertedScale = 1.0f / overrideScale;
                compatFlags |= HAS_OVERRIDE_SCALING;
            } else if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
                applicationDensity = DisplayMetrics.DENSITY_DEVICE;
                applicationScale = 1.0f;
                applicationInvertedScale = 1.0f;
@@ -277,7 +292,7 @@ public class CompatibilityInfo implements Parcelable {
     */
    @UnsupportedAppUsage
    public boolean isScalingRequired() {
        return (mCompatibilityFlags&SCALING_REQUIRED) != 0;
        return (mCompatibilityFlags & (SCALING_REQUIRED | HAS_OVERRIDE_SCALING)) != 0;
    }
    
    @UnsupportedAppUsage
@@ -303,7 +318,7 @@ public class CompatibilityInfo implements Parcelable {
     */
    @UnsupportedAppUsage
    public Translator getTranslator() {
        return isScalingRequired() ? new Translator() : null;
        return (mCompatibilityFlags & SCALING_REQUIRED) != 0 ? new Translator() : null;
    }

    /**
@@ -504,6 +519,16 @@ public class CompatibilityInfo implements Parcelable {
        if (isScalingRequired()) {
            float invertedRatio = applicationInvertedScale;
            inoutConfig.densityDpi = (int)((inoutConfig.densityDpi * invertedRatio) + .5f);
            inoutConfig.screenWidthDp = (int) ((inoutConfig.screenWidthDp * invertedRatio) + .5f);
            inoutConfig.screenHeightDp = (int) ((inoutConfig.screenHeightDp * invertedRatio) + .5f);
            inoutConfig.smallestScreenWidthDp =
                    (int) ((inoutConfig.smallestScreenWidthDp * invertedRatio) + .5f);
            inoutConfig.windowConfiguration.getMaxBounds().scale(invertedRatio);
            inoutConfig.windowConfiguration.getBounds().scale(invertedRatio);
            final Rect appBounds = inoutConfig.windowConfiguration.getAppBounds();
            if (appBounds != null) {
                appBounds.scale(invertedRatio);
            }
        }
    }

+85 −1
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;

import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.res.CompatibilityInfo;
@@ -32,6 +35,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.SparseArray;
@@ -63,6 +67,58 @@ public final class CompatModePackages {
    // Compatibility state: compatibility mode is enabled.
    private static final int COMPAT_FLAG_ENABLED = 1<<1;

    /**
     * CompatModePackages#DOWNSCALED is the gatekeeper of all per-app buffer downscaling
     * changes.  Disabling this change will prevent the following scaling factors from working:
     * CompatModePackages#DOWNSCALE_87_5
     * CompatModePackages#DOWNSCALE_75
     * CompatModePackages#DOWNSCALE_62_5
     * CompatModePackages#DOWNSCALE_50
     *
     * If CompatModePackages#DOWNSCALED is enabled for an app package, then the app will be forcibly
     * resized to the highest enabled scaling factor e.g. 87.5% if both 87.5% and 75% were
     * enabled.
     */
    @ChangeId
    @Disabled
    private static final long DOWNSCALED = 168419799L;

    /**
     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
     * CompatModePackages#DOWNSCALE_87_5 for a package will force the app to assume it's
     * running on a display with 87.5% the vertical and horizontal resolution of the real display.
     */
    @ChangeId
    @Disabled
    private static final long DOWNSCALE_87_5 = 176926753L;

    /**
     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
     * CompatModePackages#DOWNSCALE_75 for a package will force the app to assume it's
     * running on a display with 75% the vertical and horizontal resolution of the real display.
     */
    @ChangeId
    @Disabled
    private static final long DOWNSCALE_75 = 176926829L;

    /**
     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
     * CompatModePackages#DOWNSCALE_62_5 for a package will force the app to assume it's
     * running on a display with 62.5% the vertical and horizontal resolution of the real display.
     */
    @ChangeId
    @Disabled
    private static final long DOWNSCALE_62_5 = 176926771L;

    /**
     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
     * CompatModePackages#DOWNSCALE_50 for a package will force the app to assume it's
     * running on a display with 50% vertical and horizontal resolution of the real display.
     */
    @ChangeId
    @Disabled
    private static final long DOWNSCALE_50 = 176926741L;

    private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();

    private static final int MSG_WRITE = 300;
@@ -191,11 +247,39 @@ public final class CompatModePackages {
        mHandler.sendMessageDelayed(msg, 10000);
    }

    float getCompatScale(String packageName, int uid) {
        if (!CompatChanges.isChangeEnabled(
                DOWNSCALED, packageName, UserHandle.getUserHandleForUid(uid))) {
            return 1f;
        }
        if (CompatChanges.isChangeEnabled(
                DOWNSCALE_87_5, packageName, UserHandle.getUserHandleForUid(uid))) {
            // 8/7 == (1 / 0.875) ~= 1.14285714286
            return 8f / 7f;
        }
        if (CompatChanges.isChangeEnabled(
                DOWNSCALE_75, packageName, UserHandle.getUserHandleForUid(uid))) {
            // 4/3 == (1 / 0.75) ~= 1.333333333
            return 4f / 3f;
        }
        if (CompatChanges.isChangeEnabled(
                DOWNSCALE_62_5, packageName, UserHandle.getUserHandleForUid(uid))) {
            // (1 / 0.625) == 1.6
            return 1.6f;
        }
        if (CompatChanges.isChangeEnabled(
                DOWNSCALE_50, packageName, UserHandle.getUserHandleForUid(uid))) {
            return 2f;
        }
        return 1f;
    }

    public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
        final Configuration globalConfig = mService.getGlobalConfiguration();
        final float requestedScale = getCompatScale(ai.packageName, ai.uid);
        CompatibilityInfo ci = new CompatibilityInfo(ai, globalConfig.screenLayout,
                globalConfig.smallestScreenWidthDp,
                (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0);
                (getPackageFlags(ai.packageName) & COMPAT_FLAG_ENABLED) != 0, requestedScale);
        //Slog.i(TAG, "*********** COMPAT FOR PKG " + ai.packageName + ": " + ci);
        return ci;
    }
+19 −4
Original line number Diff line number Diff line
@@ -438,6 +438,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    float mGlobalScale=1;
    float mLastGlobalScale=1;
    float mInvGlobalScale=1;
    float mOverrideScale = 1;
    float mHScale=1, mVScale=1;
    float mLastHScale=1, mLastVScale=1;
    final Matrix mTmpMatrix = new Matrix();
@@ -1008,6 +1009,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        mLastRequestedWidth = 0;
        mLastRequestedHeight = 0;
        mLayer = 0;
        mOverrideScale = mWmService.mAtmService.mCompatModePackages.getCompatScale(
                mAttrs.packageName, s.mUid);

        // Make sure we initial all fields before adding to parentWindow, to prevent exception
        // during onDisplayChanged.
@@ -1040,8 +1043,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        mSession.windowAddedLocked(mAttrs.packageName);
    }

    /**
     * @return {@code true} if the application runs in size compatibility mode or has an app level
     * scaling override set.
     * @see CompatModePackages#getCompatScale
     * @see android.content.res.CompatibilityInfo#supportsScreen
     * @see ActivityRecord#inSizeCompatMode()
     */
    boolean inSizeCompatMode() {
        return inSizeCompatMode(mAttrs, mActivityRecord);
        return mOverrideScale != 1f || inSizeCompatMode(mAttrs, mActivityRecord);
    }

    /**
@@ -1676,7 +1686,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

    void prelayout() {
        if (inSizeCompatMode()) {
            if (mOverrideScale != 1f) {
                mGlobalScale = mToken.hasSizeCompatBounds()
                        ? mToken.getSizeCompatScale() * mOverrideScale
                        : mOverrideScale;
            } else {
                mGlobalScale = mToken.getSizeCompatScale();
            }
            mInvGlobalScale = 1 / mGlobalScale;
        } else {
            mGlobalScale = mInvGlobalScale = 1;
@@ -2634,8 +2650,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        // scaling but the existing logic doesn't expect that. The result is that the already-
        // scaled region ends up getting sent to surfaceflinger which then applies the scale
        // (again). Until this is resolved, apply an inverse-scale here.
        if (mActivityRecord != null && mActivityRecord.hasSizeCompatBounds()
                && mGlobalScale != 1.f) {
        if (mInvGlobalScale != 1.f) {
            region.scale(mInvGlobalScale);
        }