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

Commit 7bf80c14 authored by Andrei Onea's avatar Andrei Onea Committed by Andrei-Valentin Onea
Browse files

Do not enable changes newer than the current sdk

Do not allow enabling compat changes in APEX gated on an sdk version
greater than the current one.

Test: atest OverrideValidatorImplTest
Test: atest PlatformCompatTest
Bug: 175790344
Bug: 179149558
Change-Id: Idd7d86f96a380bfe01940f356d38ad49d3f27678
parent ed60ceba
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";
    }
+10 −3
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.

    /**
@@ -233,7 +234,7 @@ 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();
        }
@@ -244,7 +245,13 @@ public final class CompatChange extends CompatibilityChangeInfo {
            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;
    }
+5 −3
Original line number Diff line number Diff line
@@ -74,12 +74,14 @@ final class CompatConfig {
    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;
    }

@@ -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());
+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