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

Commit 420476e0 authored by Andrei-Valentin Onea's avatar Andrei-Valentin Onea Committed by Gerrit Code Review
Browse files

Merge changes Idd7d86f9,I73569744

* changes:
  Do not enable changes newer than the current sdk
  Add support for loading a static overrides file located in /product.
parents af174a57 7bf80c14
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -31,4 +31,14 @@ public class AndroidBuildClassifier {
    public boolean isFinalBuild() {
        return "REL".equals(Build.VERSION.CODENAME);
    }

    /**
     * The current platform SDK version.
     */
    public int platformTargetSdk() {
        if (isFinalBuild()) {
            return Build.VERSION.SDK_INT;
        }
        return Build.VERSION_CODES.CUR_DEVELOPMENT;
    }
}
+13 −1
Original line number Diff line number Diff line
@@ -34,7 +34,8 @@ public final class OverrideAllowedState implements Parcelable {
            DISABLED_NON_TARGET_SDK,
            DISABLED_TARGET_SDK_TOO_HIGH,
            DEFERRED_VERIFICATION,
            LOGGING_ONLY_CHANGE
            LOGGING_ONLY_CHANGE,
            PLATFORM_TOO_OLD
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface State {
@@ -65,6 +66,10 @@ public final class OverrideAllowedState implements Parcelable {
     * Change is marked as logging only, and cannot be toggled.
     */
    public static final int LOGGING_ONLY_CHANGE = 5;
    /**
     * Change is gated by a target sdk version newer than the current platform sdk version.
     */
    public static final int PLATFORM_TOO_OLD = 6;

    @State
    public final int state;
@@ -123,6 +128,11 @@ public final class OverrideAllowedState implements Parcelable {
                throw new SecurityException(String.format(
                        "Cannot override %1$d because it is marked as a logging-only change.",
                        changeId));
            case PLATFORM_TOO_OLD:
                throw new SecurityException(String.format(
                        "Cannot override %1$d for %2$s because the change's targetSdk threshold "
                                + "(%3$d) is above the platform sdk.",
                        changeId, packageName, changeIdTargetSdk));
        }
    }

@@ -170,6 +180,8 @@ public final class OverrideAllowedState implements Parcelable {
                return "DEFERRED_VERIFICATION";
            case LOGGING_ONLY_CHANGE:
                return "LOGGING_ONLY_CHANGE";
            case PLATFORM_TOO_OLD:
                return "PLATFORM_TOO_OLD";
        }
        return "UNKNOWN";
    }
+47 −53
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;

import com.android.internal.compat.AndroidBuildClassifier;
import com.android.internal.compat.CompatibilityChangeInfo;
import com.android.internal.compat.OverrideAllowedState;
import com.android.server.compat.config.Change;
@@ -55,7 +56,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
     * A change ID to be used only in the CTS test for this SystemApi
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = 1235) // Needs to be > test APK targetSdkVersion.
    @EnabledSince(targetSdkVersion = 31) // Needs to be > test APK targetSdkVersion.
    static final long CTS_SYSTEM_API_CHANGEID = 149391281; // This is a bug id.

    /**
@@ -79,6 +80,15 @@ public final class CompatChange extends CompatibilityChangeInfo {
        this(changeId, null, -1, -1, false, false, null, false);
    }

    /**
     * @param change an object generated by services/core/xsd/platform-compat-config.xsd
     */
    public CompatChange(Change change) {
        this(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
                change.getEnableSinceTargetSdk(), change.getDisabled(), change.getLoggingOnly(),
                change.getDescription(), change.getOverridable());
    }

    /**
     * @param changeId Unique ID for the change. See {@link android.compat.Compatibility}.
     * @param name Short descriptive name.
@@ -93,15 +103,10 @@ public final class CompatChange extends CompatibilityChangeInfo {
            boolean overridable) {
        super(changeId, name, enableAfterTargetSdk, enableSinceTargetSdk, disabled, loggingOnly,
              description, overridable);
    }

    /**
     * @param change an object generated by services/core/xsd/platform-compat-config.xsd
     */
    public CompatChange(Change change) {
        super(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
                change.getEnableSinceTargetSdk(), change.getDisabled(), change.getLoggingOnly(),
                change.getDescription(), change.getOverridable());
        // Initialize override maps.
        mEvaluatedOverrides = new HashMap<>();
        mRawOverrides = new HashMap<>();
    }

    void registerListener(ChangeListener listener) {
@@ -127,20 +132,15 @@ public final class CompatChange extends CompatibilityChangeInfo {
            throw new IllegalArgumentException(
                    "Can't add overrides for a logging only change " + toString());
        }
        if (mEvaluatedOverrides == null) {
            mEvaluatedOverrides = new HashMap<>();
        }
        mEvaluatedOverrides.put(pname, enabled);
        notifyListener(pname);
    }

    private void removePackageOverrideInternal(String pname) {
        if (mEvaluatedOverrides != null) {
        if (mEvaluatedOverrides.remove(pname) != null) {
            notifyListener(pname);
        }
    }
    }

    /**
     * Tentatively set the state of this change for a given package name.
@@ -157,9 +157,6 @@ public final class CompatChange extends CompatibilityChangeInfo {
            throw new IllegalArgumentException(
                    "Can't add overrides for a logging only change " + toString());
        }
        if (mRawOverrides == null) {
            mRawOverrides = new HashMap<>();
        }
        mRawOverrides.put(packageName, override);
        recheckOverride(packageName, allowedState, context);
    }
@@ -212,7 +209,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
    }

    boolean hasPackageOverride(String pname) {
        return mRawOverrides != null && mRawOverrides.containsKey(pname);
        return mRawOverrides.containsKey(pname);
    }
    /**
     * Remove any package override for the given package name, restoring the default behaviour.
@@ -223,7 +220,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
     */
    boolean removePackageOverride(String pname, OverrideAllowedState allowedState,
            Context context) {
        if (mRawOverrides != null && (mRawOverrides.remove(pname) != null)) {
        if (mRawOverrides.remove(pname) != null) {
            recheckOverride(pname, allowedState, context);
            return true;
        }
@@ -237,18 +234,24 @@ public final class CompatChange extends CompatibilityChangeInfo {
     * @param app Info about the app in question
     * @return {@code true} if the change should be enabled for the package.
     */
    boolean isEnabled(ApplicationInfo app) {
    boolean isEnabled(ApplicationInfo app, AndroidBuildClassifier buildClassifier) {
        if (app == null) {
            return defaultValue();
        }
        if (mEvaluatedOverrides != null && mEvaluatedOverrides.containsKey(app.packageName)) {
        if (mEvaluatedOverrides.containsKey(app.packageName)) {
            return mEvaluatedOverrides.get(app.packageName);
        }
        if (getDisabled()) {
            return false;
        }
        if (getEnableSinceTargetSdk() != -1) {
            return app.targetSdkVersion >= getEnableSinceTargetSdk();
            // If the change is gated by a platform version newer than the one currently installed
            // on the device, disregard the app's target sdk version.
            int compareSdk = Math.min(app.targetSdkVersion, buildClassifier.platformTargetSdk());
            if (compareSdk != app.targetSdkVersion) {
                compareSdk = app.targetSdkVersion;
            }
            return compareSdk >= getEnableSinceTargetSdk();
        }
        return true;
    }
@@ -289,7 +292,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
     * @return true if there is such override
     */
    private boolean hasOverride(String packageName) {
        return mEvaluatedOverrides != null && mEvaluatedOverrides.containsKey(packageName);
        return mEvaluatedOverrides.containsKey(packageName);
    }

    /**
@@ -298,20 +301,15 @@ public final class CompatChange extends CompatibilityChangeInfo {
     * @return true if there is such a deferred override
     */
    private boolean hasRawOverride(String packageName) {
        return mRawOverrides != null && mRawOverrides.containsKey(packageName);
        return mRawOverrides.containsKey(packageName);
    }

    void loadOverrides(ChangeOverrides changeOverrides) {
        if (mRawOverrides == null) {
            mRawOverrides = new HashMap<>();
        }
    void clearOverrides() {
        mRawOverrides.clear();

        if (mEvaluatedOverrides == null) {
            mEvaluatedOverrides = new HashMap<>();
        }
        mEvaluatedOverrides.clear();
    }

    void loadOverrides(ChangeOverrides changeOverrides) {
        // Load deferred overrides for backwards compatibility
        if (changeOverrides.getDeferred() != null) {
            for (OverrideValue override : changeOverrides.getDeferred().getOverrideValue()) {
@@ -345,14 +343,13 @@ public final class CompatChange extends CompatibilityChangeInfo {
    }

    ChangeOverrides saveOverrides() {
        if (mRawOverrides == null || mRawOverrides.isEmpty()) {
        if (mRawOverrides.isEmpty()) {
            return null;
        }
        ChangeOverrides changeOverrides = new ChangeOverrides();
        changeOverrides.setChangeId(getId());
        ChangeOverrides.Raw rawOverrides = new ChangeOverrides.Raw();
        List<RawOverrideValue> rawList = rawOverrides.getRawOverrideValue();
        if (mRawOverrides != null) {
        for (Map.Entry<String, PackageOverride> entry : mRawOverrides.entrySet()) {
            RawOverrideValue override = new RawOverrideValue();
            override.setPackageName(entry.getKey());
@@ -361,19 +358,16 @@ public final class CompatChange extends CompatibilityChangeInfo {
            override.setEnabled(entry.getValue().getEnabled());
            rawList.add(override);
        }
        }
        changeOverrides.setRaw(rawOverrides);

        ChangeOverrides.Validated validatedOverrides = new ChangeOverrides.Validated();
        List<OverrideValue> validatedList = validatedOverrides.getOverrideValue();
        if (mEvaluatedOverrides != null) {
        for (Map.Entry<String, Boolean> entry : mEvaluatedOverrides.entrySet()) {
            OverrideValue override = new OverrideValue();
            override.setPackageName(entry.getKey());
            override.setEnabled(entry.getValue());
            validatedList.add(override);
        }
        }
        changeOverrides.setValidated(validatedOverrides);
        return changeOverrides;
    }
@@ -394,10 +388,10 @@ public final class CompatChange extends CompatibilityChangeInfo {
        if (getLoggingOnly()) {
            sb.append("; loggingOnly");
        }
        if (mEvaluatedOverrides != null && mEvaluatedOverrides.size() > 0) {
        if (!mEvaluatedOverrides.isEmpty()) {
            sb.append("; packageOverrides=").append(mEvaluatedOverrides);
        }
        if (mRawOverrides != null && mRawOverrides.size() > 0) {
        if (!mRawOverrides.isEmpty()) {
            sb.append("; rawOverrides=").append(mRawOverrides);
        }
        if (getOverridable()) {
+34 −9
Original line number Diff line number Diff line
@@ -67,18 +67,21 @@ final class CompatConfig {

    private static final String TAG = "CompatConfig";
    private static final String APP_COMPAT_DATA_DIR = "/data/misc/appcompat";
    private static final String STATIC_OVERRIDES_PRODUCT_DIR = "/product/etc/appcompat";
    private static final String OVERRIDES_FILE = "compat_framework_overrides.xml";

    @GuardedBy("mChanges")
    private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>();

    private final OverrideValidatorImpl mOverrideValidator;
    private final AndroidBuildClassifier mAndroidBuildClassifier;
    private Context mContext;
    private File mOverridesFile;

    @VisibleForTesting
    CompatConfig(AndroidBuildClassifier androidBuildClassifier, Context context) {
        mOverrideValidator = new OverrideValidatorImpl(androidBuildClassifier, context, this);
        mAndroidBuildClassifier = androidBuildClassifier;
        mContext = context;
    }

@@ -94,8 +97,7 @@ final class CompatConfig {
            config.initConfigFromLib(Environment.buildPath(
                    apex.apexDirectory, "etc", "compatconfig"));
        }
        File overridesFile = new File(APP_COMPAT_DATA_DIR, OVERRIDES_FILE);
        config.initOverrides(overridesFile);
        config.initOverrides();
        config.invalidateCache();
        return config;
    }
@@ -133,7 +135,7 @@ final class CompatConfig {
        synchronized (mChanges) {
            for (int i = 0; i < mChanges.size(); ++i) {
                CompatChange c = mChanges.valueAt(i);
                if (!c.isEnabled(app)) {
                if (!c.isEnabled(app, mAndroidBuildClassifier)) {
                    disabled.add(c.getId());
                }
            }
@@ -175,7 +177,7 @@ final class CompatConfig {
                // we know nothing about this change: default behaviour is enabled.
                return true;
            }
            return c.isEnabled(app);
            return c.isEnabled(app, mAndroidBuildClassifier);
        }
    }

@@ -475,7 +477,7 @@ final class CompatConfig {
        synchronized (mChanges) {
            for (int i = 0; i < mChanges.size(); ++i) {
                CompatChange c = mChanges.valueAt(i);
                if (c.isEnabled(applicationInfo)) {
                if (c.isEnabled(applicationInfo, mAndroidBuildClassifier)) {
                    enabled.add(c.getId());
                } else {
                    disabled.add(c.getId());
@@ -525,10 +527,34 @@ final class CompatConfig {
        }
    }

    void initOverrides(File overridesFile) {
    private void initOverrides() {
        initOverrides(new File(APP_COMPAT_DATA_DIR, OVERRIDES_FILE),
                new File(STATIC_OVERRIDES_PRODUCT_DIR, OVERRIDES_FILE));
    }

    @VisibleForTesting
    void initOverrides(File dynamicOverridesFile, File staticOverridesFile) {
        // Clear overrides from all changes before loading.
        synchronized (mChanges) {
            for (int i = 0; i < mChanges.size(); ++i) {
                mChanges.valueAt(i).clearOverrides();
            }
        }

        loadOverrides(staticOverridesFile);

        mOverridesFile = dynamicOverridesFile;
        loadOverrides(dynamicOverridesFile);

        if (staticOverridesFile.exists()) {
            // Only save overrides if there is a static overrides file.
            saveOverrides();
        }
    }

    private void loadOverrides(File overridesFile) {
        if (!overridesFile.exists()) {
            mOverridesFile = overridesFile;
            // There have not been any overrides added yet.
            // Overrides file doesn't exist.
            return;
        }

@@ -548,7 +574,6 @@ final class CompatConfig {
            Slog.w(TAG, "Error processing " + overridesFile + " " + e.toString());
            return;
        }
        mOverridesFile = overridesFile;
    }

    /**
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.internal.compat.OverrideAllowedState.DISABLED_NON_TARG
import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE;
import static com.android.internal.compat.OverrideAllowedState.DISABLED_TARGET_SDK_TOO_HIGH;
import static com.android.internal.compat.OverrideAllowedState.LOGGING_ONLY_CHANGE;
import static com.android.internal.compat.OverrideAllowedState.PLATFORM_TOO_OLD;

import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -85,6 +86,9 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub {
        if (debuggableBuild) {
            return new OverrideAllowedState(ALLOWED, -1, -1);
        }
        if (maxTargetSdk >= mAndroidBuildClassifier.platformTargetSdk()) {
            return new OverrideAllowedState(PLATFORM_TOO_OLD, -1, maxTargetSdk);
        }
        PackageManager packageManager = mContext.getPackageManager();
        if (packageManager == null) {
            throw new IllegalStateException("No PackageManager!");
Loading