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

Commit 8bca9a43 authored by Jay Thomas Sullivan's avatar Jay Thomas Sullivan Committed by Jay Sullivan
Browse files

[ECM] Defer changing op mode to MODE_DEFAULT

In Android V, we changed the default mode of
OP_ACCESS_RESTRICTED_SETTINGS from MODE_ALLOWED to MODE_DEFAULT. This
means all apps will, immediately upon being installed, have this op's
mode set to MODE_DEFAULT.

But, this resulted in a bug: an app with this op set to MODE_ALLOWED
on Android pre-V will, as soon as the device upgrades to Android V,
suddenly change to MODE_DEFAULT. This is due to a pre-existing bug
with the app op system.

This change changes the default mode back to MODE_ALLOWED to avoid
this, and updates to MODE_DEFAULT upon app installation.

Bug: 349456985
Flag: android.permission.flags.enhanced_confirmation_mode_apis_enabled
Test: atest CtsPermissionUiTestCases:android.permissionui.cts.EnhancedConfirmationManagerTest
Change-Id: I504449fa81219d9399fa6122952b01cbf2f94d7f
parent ceae196f
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -2981,9 +2981,7 @@ public class AppOpsManager {
        new AppOpInfo.Builder(OP_ESTABLISH_VPN_MANAGER, OPSTR_ESTABLISH_VPN_MANAGER,
                "ESTABLISH_VPN_MANAGER").setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
        new AppOpInfo.Builder(OP_ACCESS_RESTRICTED_SETTINGS, OPSTR_ACCESS_RESTRICTED_SETTINGS,
                "ACCESS_RESTRICTED_SETTINGS").setDefaultMode(
                        android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()
                                ? MODE_DEFAULT : MODE_ALLOWED)
                "ACCESS_RESTRICTED_SETTINGS").setDefaultMode(AppOpsManager.MODE_ALLOWED)
            .setDisableReset(true).setRestrictRead(true).build(),
        new AppOpInfo.Builder(OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO,
                "RECEIVE_SOUNDTRIGGER_AUDIO").setDefaultMode(AppOpsManager.MODE_ALLOWED)
+20 −5
Original line number Diff line number Diff line
@@ -2504,13 +2504,13 @@ final class InstallPackageHelper {
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }

    private void enableRestrictedSettings(String pkgName, int appId, int userId) {
    private void setAccessRestrictedSettingsMode(String pkgName, int appId, int userId, int mode) {
        final AppOpsManager appOpsManager = mPm.mContext.getSystemService(AppOpsManager.class);
        final int uid = UserHandle.getUid(userId, appId);
        appOpsManager.setMode(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
                uid,
                pkgName,
                AppOpsManager.MODE_ERRORED);
                mode);
    }

    /**
@@ -2888,8 +2888,21 @@ final class InstallPackageHelper {
                mPm.notifyPackageChanged(packageName, request.getAppId());
            }

            if (!android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()
                    || !android.security.Flags.extendEcmToAllSettings()) {
            // Set the OP_ACCESS_RESTRICTED_SETTINGS op, which is used by ECM (see {@link
            // EnhancedConfirmationManager}) as a persistent state denoting whether an app is
            // currently guarded by ECM, not guarded by ECM, or (in Android V+) that this should
            // be decided later.
            if (android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()
                    && android.security.Flags.extendEcmToAllSettings()) {
                final int appId = request.getAppId();
                mPm.mHandler.post(() -> {
                    for (int userId : firstUserIds) {
                        // MODE_DEFAULT means that the app's guardedness will be decided lazily
                        setAccessRestrictedSettingsMode(packageName, appId, userId,
                                AppOpsManager.MODE_DEFAULT);
                    }
                });
            } else {
                // Apply restricted settings on potentially dangerous packages. Needs to happen
                // after appOpsManager is notified of the new package
                if (request.getPackageSource() == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE
@@ -2898,7 +2911,9 @@ final class InstallPackageHelper {
                    final int appId = request.getAppId();
                    mPm.mHandler.post(() -> {
                        for (int userId : firstUserIds) {
                            enableRestrictedSettings(packageName, appId, userId);
                            // MODE_ERRORED means that the app is explicitly guarded
                            setAccessRestrictedSettingsMode(packageName, appId, userId,
                                    AppOpsManager.MODE_ERRORED);
                        }
                    });
                }