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

Commit ad32bfe3 authored by Saeid Farivar Asanjan's avatar Saeid Farivar Asanjan Committed by Android (Google) Code Review
Browse files

Merge "Add CompatScaleProvider interface" into main

parents 39b23df7 f2bcb596
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import static android.view.Display.INVALID_DISPLAY;
import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;
import static android.window.ConfigurationHelper.isDifferentDisplay;
import static android.window.ConfigurationHelper.shouldUpdateResources;

import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.os.SafeZipPathValidatorCallback.VALIDATE_ZIP_PATH_FOR_PATH_TRAVERSAL;

@@ -1286,8 +1285,13 @@ public final class ActivityThread extends ClientTransactionHandler
        }

        private void updateCompatOverrideScale(CompatibilityInfo info) {
            CompatibilityInfo.setOverrideInvertedScale(
                    info.hasOverrideScaling() ? info.applicationInvertedScale : 1f);
            if (info.hasOverrideScaling()) {
                CompatibilityInfo.setOverrideInvertedScale(info.applicationInvertedScale,
                        info.applicationDensityInvertedScale);
            } else {
                CompatibilityInfo.setOverrideInvertedScale(/* invertScale */ 1f,
                        /* densityInvertScale */1f);
            }
        }

        public final void runIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) {
+151 −29
Original line number Diff line number Diff line
@@ -112,9 +112,27 @@ public class CompatibilityInfo implements Parcelable {
     */
    public final float applicationInvertedScale;

    /**
     * Application's density scale.
     *
     * <p>In most cases this is equal to {@link #applicationScale}, but in some cases e.g.
     * Automotive the requirement is to just scale the density and keep the resolution the same.
     * This is used for artificially making apps look zoomed in to compensate for the user distance
     * from the screen.
     */
    public final float applicationDensityScale;

    /**
     * Application's density inverted scale.
     */
    public final float applicationDensityInvertedScale;

    /** The process level override inverted scale. See {@link #HAS_OVERRIDE_SCALING}. */
    private static float sOverrideInvertedScale = 1f;

    /** The process level override inverted density scale. See {@link #HAS_OVERRIDE_SCALING}. */
    private static float sOverrideDensityInvertScale = 1f;

    @UnsupportedAppUsage
    @Deprecated
    public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
@@ -123,17 +141,24 @@ public class CompatibilityInfo implements Parcelable {
    }

    public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
            boolean forceCompat, float overrideScale) {
            boolean forceCompat, float scaleFactor) {
        this(appInfo, screenLayout, sw, forceCompat, scaleFactor, scaleFactor);
    }

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

        if (appInfo.targetSdkVersion < VERSION_CODES.O) {
            compatFlags |= NEEDS_COMPAT_RES;
        }
        if (overrideScale != 1.0f) {
            applicationScale = overrideScale;
            applicationInvertedScale = 1.0f / overrideScale;
        if (scaleFactor != 1f || densityScaleFactor != 1f) {
            applicationScale = scaleFactor;
            applicationInvertedScale = 1f / scaleFactor;
            applicationDensityScale = densityScaleFactor;
            applicationDensityInvertedScale = 1f / densityScaleFactor;
            applicationDensity = (int) ((DisplayMetrics.DENSITY_DEVICE_STABLE
                    * applicationInvertedScale) + .5f);
                    * applicationDensityInvertedScale) + .5f);
            mCompatibilityFlags = NEVER_NEEDS_COMPAT | HAS_OVERRIDE_SCALING;
            // Override scale has the highest priority. So ignore other compatibility attributes.
            return;
@@ -181,7 +206,8 @@ public class CompatibilityInfo implements Parcelable {
            applicationDensity = DisplayMetrics.DENSITY_DEVICE;
            applicationScale = 1.0f;
            applicationInvertedScale = 1.0f;

            applicationDensityScale = 1.0f;
            applicationDensityInvertedScale = 1.0f;
        } else {
            /**
             * Has the application said that its UI is expandable?  Based on the
@@ -271,11 +297,16 @@ public class CompatibilityInfo implements Parcelable {
                applicationDensity = DisplayMetrics.DENSITY_DEVICE;
                applicationScale = 1.0f;
                applicationInvertedScale = 1.0f;
                applicationDensityScale = 1.0f;
                applicationDensityInvertedScale = 1.0f;
            } else {
                applicationDensity = DisplayMetrics.DENSITY_DEFAULT;
                applicationScale = DisplayMetrics.DENSITY_DEVICE
                        / (float) DisplayMetrics.DENSITY_DEFAULT;
                applicationInvertedScale = 1.0f / applicationScale;
                applicationDensityScale = DisplayMetrics.DENSITY_DEVICE
                        / (float) DisplayMetrics.DENSITY_DEFAULT;
                applicationDensityInvertedScale = 1f / applicationDensityScale;
                compatFlags |= SCALING_REQUIRED;
            }
        }
@@ -289,6 +320,8 @@ public class CompatibilityInfo implements Parcelable {
        applicationDensity = dens;
        applicationScale = scale;
        applicationInvertedScale = invertedScale;
        applicationDensityScale = (float) DisplayMetrics.DENSITY_DEVICE_STABLE / dens;
        applicationDensityInvertedScale = 1f / applicationDensityScale;
    }

    @UnsupportedAppUsage
@@ -528,7 +561,8 @@ public class CompatibilityInfo implements Parcelable {
    /** Applies the compatibility adjustment to the display metrics. */
    public void applyDisplayMetricsIfNeeded(DisplayMetrics inoutDm, boolean applyToSize) {
        if (hasOverrideScale()) {
            scaleDisplayMetrics(sOverrideInvertedScale, inoutDm, applyToSize);
            scaleDisplayMetrics(sOverrideInvertedScale, sOverrideDensityInvertScale, inoutDm,
                    applyToSize);
            return;
        }
        if (!equals(DEFAULT_COMPATIBILITY_INFO)) {
@@ -548,15 +582,17 @@ public class CompatibilityInfo implements Parcelable {
        }

        if (isScalingRequired()) {
            scaleDisplayMetrics(applicationInvertedScale, inoutDm, true /* applyToSize */);
            scaleDisplayMetrics(applicationInvertedScale, applicationDensityInvertedScale, inoutDm,
                    true /* applyToSize */);
        }
    }

    /** Scales the density of the given display metrics. */
    private static void scaleDisplayMetrics(float invertedRatio, DisplayMetrics inoutDm,
            boolean applyToSize) {
        inoutDm.density = inoutDm.noncompatDensity * invertedRatio;
        inoutDm.densityDpi = (int) ((inoutDm.noncompatDensityDpi * invertedRatio) + .5f);
    private static void scaleDisplayMetrics(float invertScale, float densityInvertScale,
            DisplayMetrics inoutDm, boolean applyToSize) {
        inoutDm.density = inoutDm.noncompatDensity * densityInvertScale;
        inoutDm.densityDpi = (int) ((inoutDm.noncompatDensityDpi
                * densityInvertScale) + .5f);
        // Note: since this is changing the scaledDensity, you might think we also need to change
        // inoutDm.fontScaleConverter to accurately calculate non-linear font scaling. But we're not
        // going to do that, for a couple of reasons (see b/265695259 for details):
@@ -570,12 +606,12 @@ public class CompatibilityInfo implements Parcelable {
        //    b. Sometime later by WindowManager in onResume or other windowing events. In this case
        //       the DisplayMetrics object is never used by the app/resources, so it's ok if
        //       fontScaleConverter is null because it's not being used to scale fonts anyway.
        inoutDm.scaledDensity = inoutDm.noncompatScaledDensity * invertedRatio;
        inoutDm.xdpi = inoutDm.noncompatXdpi * invertedRatio;
        inoutDm.ydpi = inoutDm.noncompatYdpi * invertedRatio;
        inoutDm.scaledDensity = inoutDm.noncompatScaledDensity * densityInvertScale;
        inoutDm.xdpi = inoutDm.noncompatXdpi * densityInvertScale;
        inoutDm.ydpi = inoutDm.noncompatYdpi * densityInvertScale;
        if (applyToSize) {
            inoutDm.widthPixels = (int) (inoutDm.widthPixels * invertedRatio + 0.5f);
            inoutDm.heightPixels = (int) (inoutDm.heightPixels * invertedRatio + 0.5f);
            inoutDm.widthPixels = (int) (inoutDm.widthPixels * invertScale + 0.5f);
            inoutDm.heightPixels = (int) (inoutDm.heightPixels * invertScale + 0.5f);
        }
    }

@@ -594,38 +630,55 @@ public class CompatibilityInfo implements Parcelable {
        }
        inoutConfig.densityDpi = displayDensity;
        if (isScalingRequired()) {
            scaleConfiguration(applicationInvertedScale, inoutConfig);
            scaleConfiguration(applicationInvertedScale, applicationDensityInvertedScale,
                    inoutConfig);
        }
    }

    /** Scales the density and bounds of the given configuration. */
    public static void scaleConfiguration(float invertScale, Configuration inoutConfig) {
        scaleConfiguration(invertScale, invertScale, inoutConfig);
    }

    /** Scales the density and bounds of the given configuration. */
    public static void scaleConfiguration(float invertedRatio, Configuration inoutConfig) {
        inoutConfig.densityDpi = (int) ((inoutConfig.densityDpi * invertedRatio) + .5f);
        inoutConfig.windowConfiguration.scale(invertedRatio);
    public static void scaleConfiguration(float invertScale, float densityInvertScale,
            Configuration inoutConfig) {
        inoutConfig.densityDpi = (int) ((inoutConfig.densityDpi
                * densityInvertScale) + .5f);
        inoutConfig.windowConfiguration.scale(invertScale);
    }

    /** @see #sOverrideInvertedScale */
    public static void applyOverrideScaleIfNeeded(Configuration config) {
        if (!hasOverrideScale()) return;
        scaleConfiguration(sOverrideInvertedScale, config);
        scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale, config);
    }

    /** @see #sOverrideInvertedScale */
    public static void applyOverrideScaleIfNeeded(MergedConfiguration mergedConfig) {
        if (!hasOverrideScale()) return;
        scaleConfiguration(sOverrideInvertedScale, mergedConfig.getGlobalConfiguration());
        scaleConfiguration(sOverrideInvertedScale, mergedConfig.getOverrideConfiguration());
        scaleConfiguration(sOverrideInvertedScale, mergedConfig.getMergedConfiguration());
        scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale,
                mergedConfig.getGlobalConfiguration());
        scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale,
                mergedConfig.getOverrideConfiguration());
        scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale,
                mergedConfig.getMergedConfiguration());
    }

    /** Returns {@code true} if this process is in a environment with override scale. */
    private static boolean hasOverrideScale() {
        return sOverrideInvertedScale != 1f;
        return sOverrideInvertedScale != 1f || sOverrideDensityInvertScale != 1f;
    }

    /** @see #sOverrideInvertedScale */
    public static void setOverrideInvertedScale(float invertedRatio) {
        sOverrideInvertedScale = invertedRatio;
    public static void setOverrideInvertedScale(float invertScale) {
        setOverrideInvertedScale(invertScale, invertScale);
    }

    /** @see #sOverrideInvertedScale */
    public static void setOverrideInvertedScale(float invertScale, float densityInvertScale) {
        sOverrideInvertedScale = invertScale;
        sOverrideDensityInvertScale = densityInvertScale;
    }

    /** @see #sOverrideInvertedScale */
@@ -633,6 +686,11 @@ public class CompatibilityInfo implements Parcelable {
        return sOverrideInvertedScale;
    }

    /** @see #sOverrideDensityInvertScale */
    public static float getOverrideDensityInvertedScale() {
        return sOverrideDensityInvertScale;
    }

    /**
     * Compute the frame Rect for applications runs under compatibility mode.
     *
@@ -693,6 +751,8 @@ public class CompatibilityInfo implements Parcelable {
            if (applicationDensity != oc.applicationDensity) return false;
            if (applicationScale != oc.applicationScale) return false;
            if (applicationInvertedScale != oc.applicationInvertedScale) return false;
            if (applicationDensityScale != oc.applicationDensityScale) return false;
            if (applicationDensityInvertedScale != oc.applicationDensityInvertedScale) return false;
            return true;
        } catch (ClassCastException e) {
            return false;
@@ -713,6 +773,8 @@ public class CompatibilityInfo implements Parcelable {
        if (hasOverrideScaling()) {
            sb.append(" overrideInvScale=");
            sb.append(applicationInvertedScale);
            sb.append(" overrideDensityInvScale=");
            sb.append(applicationDensityInvertedScale);
        }
        if (!supportsScreen()) {
            sb.append(" resizing");
@@ -734,6 +796,8 @@ public class CompatibilityInfo implements Parcelable {
        result = 31 * result + applicationDensity;
        result = 31 * result + Float.floatToIntBits(applicationScale);
        result = 31 * result + Float.floatToIntBits(applicationInvertedScale);
        result = 31 * result + Float.floatToIntBits(applicationDensityScale);
        result = 31 * result + Float.floatToIntBits(applicationDensityInvertedScale);
        return result;
    }

@@ -748,6 +812,8 @@ public class CompatibilityInfo implements Parcelable {
        dest.writeInt(applicationDensity);
        dest.writeFloat(applicationScale);
        dest.writeFloat(applicationInvertedScale);
        dest.writeFloat(applicationDensityScale);
        dest.writeFloat(applicationDensityInvertedScale);
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -769,5 +835,61 @@ public class CompatibilityInfo implements Parcelable {
        applicationDensity = source.readInt();
        applicationScale = source.readFloat();
        applicationInvertedScale = source.readFloat();
        applicationDensityScale = source.readFloat();
        applicationDensityInvertedScale = source.readFloat();
    }

    /**
     * A data class for holding scale factor for width, height, and density.
     */
    public static final class CompatScale {

        public final float mScaleFactor;
        public final float mDensityScaleFactor;

        public CompatScale(float scaleFactor) {
            this(scaleFactor, scaleFactor);
        }

        public CompatScale(float scaleFactor, float densityScaleFactor) {
            mScaleFactor = scaleFactor;
            mDensityScaleFactor = densityScaleFactor;
        }

        @Override
        public boolean equals(@Nullable Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof CompatScale)) {
                return false;
            }
            try {
                CompatScale oc = (CompatScale) o;
                if (mScaleFactor != oc.mScaleFactor) return false;
                if (mDensityScaleFactor != oc.mDensityScaleFactor) return false;
                return true;
            } catch (ClassCastException e) {
                return false;
            }
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(128);
            sb.append("mScaleFactor= ");
            sb.append(mScaleFactor);
            sb.append(" mDensityScaleFactor= ");
            sb.append(mDensityScaleFactor);
            return sb.toString();
        }

        @Override
        public int hashCode() {
            int result = 17;
            result = 31 * result + Float.floatToIntBits(mScaleFactor);
            result = 31 * result + Float.floatToIntBits(mDensityScaleFactor);
            return result;
        }
    }
}
+9 −1
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@ import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;

import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_DREAM;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
@@ -5631,6 +5630,15 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        }
    }

    void registerCompatScaleProvider(@CompatScaleProvider.CompatScaleModeOrderId int id,
            @NonNull CompatScaleProvider provider) {
        mCompatModePackages.registerCompatScaleProvider(id, provider);
    }

    void unregisterCompatScaleProvider(@CompatScaleProvider.CompatScaleModeOrderId int id) {
        mCompatModePackages.unregisterCompatScaleProvider(id);
    }

    /**
     * Returns {@code true} if the process represented by the pid passed as argument is
     * instrumented and the instrumentation source was granted with the permission also
+63 −2
Original line number Diff line number Diff line
@@ -20,7 +20,10 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.CompatScaleProvider.COMPAT_SCALE_MODE_SYSTEM_FIRST;
import static com.android.server.wm.CompatScaleProvider.COMPAT_SCALE_MODE_SYSTEM_LAST;

import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.GameManagerInternal;
@@ -32,6 +35,7 @@ import android.compat.annotation.Overridable;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.res.CompatibilityInfo;
import android.content.res.CompatibilityInfo.CompatScale;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Handler;
@@ -332,6 +336,8 @@ public final class CompatModePackages {
    private final HashMap<String, Integer> mPackages = new HashMap<>();
    private final CompatHandler mHandler;

    private final SparseArray<CompatScaleProvider> mProviders = new SparseArray<>();

    public CompatModePackages(ActivityTaskManagerService service, File systemDir, Handler handler) {
        mService = service;
        mFile = new AtomicFile(new File(systemDir, "packages-compat.xml"), "compat-mode");
@@ -441,13 +447,38 @@ public final class CompatModePackages {

    public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
        final boolean forceCompat = getPackageCompatModeEnabledLocked(ai);
        final float compatScale = getCompatScale(ai.packageName, ai.uid);
        final CompatScale compatScale = getCompatScaleFromProvider(ai.packageName, ai.uid);
        final float appScale = compatScale != null
                ? compatScale.mScaleFactor
                : getCompatScale(ai.packageName, ai.uid, /* checkProvider= */ false);
        final float densityScale = compatScale != null ? compatScale.mDensityScaleFactor : 1f;
        final Configuration config = mService.getGlobalConfiguration();
        return new CompatibilityInfo(ai, config.screenLayout, config.smallestScreenWidthDp,
                forceCompat, compatScale);
                forceCompat, appScale, densityScale);
    }

    float getCompatScale(String packageName, int uid) {
        return getCompatScale(packageName, uid, /* checkProvider= */ true);
    }

    private CompatScale getCompatScaleFromProvider(String packageName, int uid) {
        for (int i = 0; i < mProviders.size(); i++) {
            final CompatScaleProvider provider = mProviders.valueAt(i);
            final CompatScale compatScale = provider.getCompatScale(packageName, uid);
            if (compatScale != null) {
                return compatScale;
            }
        }
        return null;
    }

    private float getCompatScale(String packageName, int uid, boolean checkProviders) {
        if (checkProviders) {
            final CompatScale compatScale = getCompatScaleFromProvider(packageName, uid);
            if (compatScale != null) {
                return compatScale.mScaleFactor;
            }
        }
        final UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
        if (mGameManager == null) {
            mGameManager = LocalServices.getService(GameManagerInternal.class);
@@ -487,6 +518,36 @@ public final class CompatModePackages {
        return 1f;
    }

    void registerCompatScaleProvider(@CompatScaleProvider.CompatScaleModeOrderId int id,
            @NonNull CompatScaleProvider provider) {
        synchronized (mService.mGlobalLock) {
            if (mProviders.contains(id)) {
                throw new IllegalArgumentException("Duplicate id provided: " + id);
            }
            if (provider == null) {
                throw new IllegalArgumentException("The passed CompatScaleProvider "
                        + "can not be null");
            }
            if (!CompatScaleProvider.isValidOrderId(id)) {
                throw new IllegalArgumentException(
                        "Provided id " + id + " is not in range of valid ids for system "
                                + "services [" + COMPAT_SCALE_MODE_SYSTEM_FIRST + ","
                                + COMPAT_SCALE_MODE_SYSTEM_LAST + "]");
            }
            mProviders.put(id, provider);
        }
    }

    void unregisterCompatScaleProvider(@CompatScaleProvider.CompatScaleModeOrderId int id) {
        synchronized (mService.mGlobalLock) {
            if (!mProviders.contains(id)) {
                throw new IllegalArgumentException(
                        "CompatScaleProvider with id (" + id + ") is not registered");
            }
            mProviders.remove(id);
        }
    }

    private static float getScalingFactor(String packageName, UserHandle userHandle) {
        if (CompatChanges.isChangeEnabled(DOWNSCALE_90, packageName, userHandle)) {
            return 0.9f;
+86 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.wm;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.CompatibilityInfo.CompatScale;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * An interface for services that need to provide compatibility scale different than
 * the default android compatibility.
 */
public interface CompatScaleProvider {

    /**
     * The unique id of each provider registered by a system service which determines the order
     * it will execute in.
     */
    @IntDef(prefix = { "COMPAT_SCALE_MODE_" }, value = {
        // Order Ids for system services
        COMPAT_SCALE_MODE_SYSTEM_FIRST,
        COMPAT_SCALE_MODE_GAME,
        COMPAT_SCALE_MODE_PRODUCT,
        COMPAT_SCALE_MODE_SYSTEM_LAST, // Update this when adding new ids
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface CompatScaleModeOrderId {}

    /**
     * The first id, used by the framework to determine the valid range of ids.
     * @hide
     */
    int COMPAT_SCALE_MODE_SYSTEM_FIRST = 0;

    /**
     * TODO(b/295207384)
     * The identifier for {@link android.app.GameManagerInternal} provider
     * @hide
     */
    int COMPAT_SCALE_MODE_GAME = 1;

    /**
     * The identifier for a provider which is specific to the type of android product like
     * Automotive, Wear, TV etc.
     * @hide
     */
    int COMPAT_SCALE_MODE_PRODUCT = 2;

    /**
     * The final id, used by the framework to determine the valid range of ids. Update this when
     * adding new ids.
     * @hide
     */
    int COMPAT_SCALE_MODE_SYSTEM_LAST = COMPAT_SCALE_MODE_PRODUCT;

    /**
     * Returns {@code true} if the id is in the range of valid system services
     * @hide
     */
    static boolean isValidOrderId(int id) {
        return (id >= COMPAT_SCALE_MODE_SYSTEM_FIRST && id <= COMPAT_SCALE_MODE_SYSTEM_LAST);
    }

    /**
     * @return an instance of {@link CompatScale} to apply for the given package
     */
    @Nullable
    CompatScale getCompatScale(@NonNull String packageName, int uid);
}
Loading