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

Commit 76735f66 authored by shafik's avatar shafik
Browse files

Make OP_LEGACY_STORAGE stickiness configurable

OP_LEGACY_STORAGE is sticky for apps targeting <= Q.
This change makes this behaviour configurable via DeviceConfig, by
introducing a new property "legacy_storage_op_sticky" to existing
namespace "storage_native_boot". If the property is set to true, then
we get the default behaviour (app-op sticky for SDK<=Q). If it's set to
true, then the app-op is not sticky for SDK<=Q.

Apps targeting > Q remain unaffected: always not sticky.

Test: manual:
    * adb shell dumpsys appops --package com.android.vending
    * Observe LEGACY_STORAGE mode=allowed
    * adb shell device_config put storage_native_boot legacy_storage_op_sticky false
    * adb reboot
    * adb shell dumpsys appops --package com.android.vending
    * Observe LEGACY_STORAGE mode=ignored
Bug: 151735608
Change-Id: I06d115a0c85c44b5a6d1054f74a00d8fa674dfa7
parent 3cfc4d04
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -162,7 +162,12 @@ public class StorageManager {
    /** {@hide} */
    public static final String PROP_SETTINGS_FUSE = FeatureFlagUtils.PERSIST_PREFIX
            + FeatureFlagUtils.SETTINGS_FUSE_FLAG;

    /**
     * Property that determines whether {@link OP_LEGACY_STORAGE} is sticky for
     * legacy apps.
     * @hide
     */
    public static final String PROP_LEGACY_OP_STICKY = "persist.sys.legacy_storage_sticky";

    /** {@hide} */
    public static final String UUID_PRIVATE_INTERNAL = null;
+9 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import static android.os.storage.OnObbStateChangeListener.ERROR_PERMISSION_DENIE
import static android.os.storage.OnObbStateChangeListener.MOUNTED;
import static android.os.storage.OnObbStateChangeListener.UNMOUNTED;
import static android.os.storage.StorageManager.PROP_FUSE;
import static android.os.storage.StorageManager.PROP_LEGACY_OP_STICKY;
import static android.os.storage.StorageManager.PROP_SETTINGS_FUSE;

import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -896,6 +897,7 @@ class StorageManagerService extends IStorageManager.Stub
                    refreshIsolatedStorageSettings();
                }
            });
        updateLegacyStorageOpSticky();
        // For now, simply clone property when it changes
        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
                mContext.getMainExecutor(), (properties) -> {
@@ -1757,6 +1759,13 @@ class StorageManagerService extends IStorageManager.Stub
        }
    }

    private void updateLegacyStorageOpSticky() {
        final boolean propertyValue = DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
                "legacy_storage_op_sticky", true);
        SystemProperties.set(PROP_LEGACY_OP_STICKY, propertyValue ? "true" : "false");
    }

    private void start() {
        connectStoraged();
        connectVold();
+10 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INST
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.storage.StorageManager.PROP_LEGACY_OP_STICKY;

import static java.lang.Integer.min;

@@ -36,6 +37,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.storage.StorageManagerInternal;

@@ -63,6 +65,9 @@ public abstract class SoftRestrictedPermissionPolicy {
                }
            };

    private static final boolean isLegacyStorageAppOpStickyGlobal = SystemProperties.getBoolean(
            PROP_LEGACY_OP_STICKY, /*defaultValue*/true);

    /**
     * TargetSDK is per package. To make sure two apps int the same shared UID do not fight over
     * what to set, always compute the combined targetSDK.
@@ -136,9 +141,12 @@ public abstract class SoftRestrictedPermissionPolicy {
                    shouldPreserveLegacyExternalStorage = pkg.hasPreserveLegacyExternalStorage()
                            && smInternal.hasLegacyExternalStorage(appInfo.uid);
                    targetSDK = getMinimumTargetSDK(context, appInfo, user);
                    // LEGACY_STORAGE op is normally sticky for apps targetig <= Q.
                    // However, this device can be configured to make it non-sticky.
                    boolean isLegacyAppOpSticky = isLegacyStorageAppOpStickyGlobal
                            && targetSDK <= Build.VERSION_CODES.Q;
                    shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0
                            || (targetSDK > Build.VERSION_CODES.Q
                            && !shouldPreserveLegacyExternalStorage);
                            || (!isLegacyAppOpSticky && !shouldPreserveLegacyExternalStorage);
                } else {
                    isWhiteListed = false;
                    shouldApplyRestriction = false;