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

Commit 46111c8e authored by Andrei Onea's avatar Andrei Onea
Browse files

Add force_non_debuggable_final_build_for_compat

This flag forces the compat framework to assume we're on a
non-debuggable build, and use stricter rules for enforcing
the change id override policy.
On a non-debuggable build, this flag has no effect.

Test: atest OverrideValidatorImplTest
Bug: 158696818
Change-Id: I3b13f1898e7ff00580140debe2ced9f8074502ea
parent 224f8c01
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -13283,6 +13283,16 @@ public final class Settings {
        @TestApi
        public static final String HIDDEN_API_POLICY = "hidden_api_policy";
         /**
         * Flag for forcing {@link com.android.server.compat.OverrideValidatorImpl}
         * to consider this a non-debuggable build.
         *
         * @hide
         */
        public static final String FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT =
                "force_non_debuggable_final_build_for_compat";
        /**
         * Current version of signed configuration applied.
         *
+1 −0
Original line number Diff line number Diff line
@@ -300,6 +300,7 @@ public class SettingsBackupTest {
                    Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
                    Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
                    Settings.Global.HIDDEN_API_POLICY,
                    Settings.Global.FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT,
                    Settings.Global.HIDE_ERROR_DIALOGS,
                    Settings.Global.HTTP_PROXY,
                    HYBRID_SYSUI_BATTERY_WARNING_FLAGS,
+1 −0
Original line number Diff line number Diff line
@@ -9481,6 +9481,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
        mHiddenApiBlacklist.registerObserver();
        mPlatformCompat.registerContentObserver();
        final long pssDeferralMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                ACTIVITY_START_PSS_DEFER_CONFIG, 0L);
+26 −27
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ final class CompatConfig {
    @GuardedBy("mChanges")
    private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>();

    private IOverrideValidator mOverrideValidator;
    private OverrideValidatorImpl mOverrideValidator;

    @VisibleForTesting
    CompatConfig(AndroidBuildClassifier androidBuildClassifier, Context context) {
@@ -161,7 +161,7 @@ final class CompatConfig {
     * @return {@code true} if the change existed before adding the override.
     */
    boolean addOverride(long changeId, String packageName, boolean enabled)
            throws RemoteException, SecurityException {
            throws SecurityException {
        boolean alreadyKnown = true;
        OverrideAllowedState allowedState =
                mOverrideValidator.getOverrideAllowedState(changeId, packageName);
@@ -254,7 +254,7 @@ final class CompatConfig {
     * @return {@code true} if an override existed;
     */
    boolean removeOverride(long changeId, String packageName)
            throws RemoteException, SecurityException {
            throws SecurityException {
        boolean overrideExists = false;
        synchronized (mChanges) {
            CompatChange c = mChanges.get(changeId);
@@ -307,7 +307,7 @@ final class CompatConfig {
     *
     * @param packageName The package for which the overrides should be purged.
     */
    void removePackageOverrides(String packageName) throws RemoteException, SecurityException {
    void removePackageOverrides(String packageName) throws SecurityException {
        synchronized (mChanges) {
            for (int i = 0; i < mChanges.size(); ++i) {
                CompatChange change = mChanges.valueAt(i);
@@ -323,7 +323,6 @@ final class CompatConfig {
        LongArray allowed = new LongArray();
        synchronized (mChanges) {
            for (int i = 0; i < mChanges.size(); ++i) {
                try {
                CompatChange change = mChanges.valueAt(i);
                if (change.getEnableSinceTargetSdk() != targetSdkVersion) {
                    continue;
@@ -334,10 +333,6 @@ final class CompatConfig {
                if (allowedState.state == OverrideAllowedState.ALLOWED) {
                    allowed.add(change.getId());
                }
                } catch (RemoteException e) {
                    // Should never occur, since validator is in the same process.
                    throw new AssertionError("Unable to call override validator!", e);
                }
            }
        }
        return allowed.toArray();
@@ -396,6 +391,11 @@ final class CompatConfig {
        return c.defaultValue();
    }

    @VisibleForTesting
    void forceNonDebuggableFinalForTest(boolean value) {
        mOverrideValidator.forceNonDebuggableFinalForTest(value);
    }

    @VisibleForTesting
    void clearChanges() {
        synchronized (mChanges) {
@@ -515,19 +515,18 @@ final class CompatConfig {
            boolean shouldInvalidateCache = false;
            for (int idx = 0; idx < mChanges.size(); ++idx) {
                CompatChange c = mChanges.valueAt(idx);
                try {
                OverrideAllowedState allowedState =
                        mOverrideValidator.getOverrideAllowedState(c.getId(), packageName);
                boolean allowedOverride = (allowedState.state == OverrideAllowedState.ALLOWED);
                shouldInvalidateCache |= c.recheckOverride(packageName, allowedOverride);
                } catch (RemoteException e) {
                    // Should never occur, since validator is in the same process.
                    throw new AssertionError("Unable to call override validator!", e);
                }
            }
            if (shouldInvalidateCache) {
                invalidateCache();
            }
        }
    }

    void registerContentObserver() {
        mOverrideValidator.registerContentObserver();
    }
}
+35 −2
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.ContentObserver;
import android.os.Handler;
import android.provider.Settings;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.AndroidBuildClassifier;
@@ -41,6 +44,20 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub {
    private AndroidBuildClassifier mAndroidBuildClassifier;
    private Context mContext;
    private CompatConfig mCompatConfig;
    private boolean mForceNonDebuggableFinalBuild;

    private class SettingsObserver extends ContentObserver {
        SettingsObserver() {
            super(new Handler());
        }
        @Override
        public void onChange(boolean selfChange) {
            mForceNonDebuggableFinalBuild = Settings.Global.getInt(
                mContext.getContentResolver(),
                Settings.Global.FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT,
                0) == 1;
        }
    }

    @VisibleForTesting
    OverrideValidatorImpl(AndroidBuildClassifier androidBuildClassifier,
@@ -48,6 +65,7 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub {
        mAndroidBuildClassifier = androidBuildClassifier;
        mContext = context;
        mCompatConfig = config;
        mForceNonDebuggableFinalBuild = false;
    }

    @Override
@@ -56,8 +74,10 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub {
            return new OverrideAllowedState(LOGGING_ONLY_CHANGE, -1, -1);
        }

        boolean debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild();
        boolean finalBuild = mAndroidBuildClassifier.isFinalBuild();
        boolean debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild()
                                    && !mForceNonDebuggableFinalBuild;
        boolean finalBuild = mAndroidBuildClassifier.isFinalBuild()
                                || mForceNonDebuggableFinalBuild;
        int maxTargetSdk = mCompatConfig.maxTargetSdkForChangeIdOptIn(changeId);
        boolean disabled = mCompatConfig.isDisabled(changeId);

@@ -94,4 +114,17 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub {
        }
        return new OverrideAllowedState(DISABLED_TARGET_SDK_TOO_HIGH, appTargetSdk, maxTargetSdk);
    }

    void registerContentObserver() {
        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(
                    Settings.Global.FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT),
                false,
                new SettingsObserver());
    }

    void forceNonDebuggableFinalForTest(boolean value) {
        mForceNonDebuggableFinalBuild = value;
    }

}
Loading