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

Commit 91b5aafd authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Use compat flags to reflect the current status of legacy storage." into...

Merge "Use compat flags to reflect the current status of legacy storage." into rvc-dev am: 6838c0ef am: 60d85a42

Change-Id: I690fc66bd4f1c84ee7f87b1d263f2e3e6632689a
parents 0acbc2aa 60d85a42
Loading
Loading
Loading
Loading
+42 −20
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ import android.annotation.TestApi;
import android.app.AppGlobals;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager;
import android.compat.Compatibility;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
@@ -88,6 +89,16 @@ public class Environment {
    private static final File DIR_APEX_ROOT = getDirectory(ENV_APEX_ROOT,
    private static final File DIR_APEX_ROOT = getDirectory(ENV_APEX_ROOT,
            "/apex");
            "/apex");


    /**
     * See definition in com.android.providers.media.LocalCallingIdentity
     */
    private static final long DEFAULT_SCOPED_STORAGE = 149924527L;

    /**
     * See definition in com.android.providers.media.LocalCallingIdentity
     */
    private static final long FORCE_ENABLE_SCOPED_STORAGE = 132649864L;

    @UnsupportedAppUsage
    @UnsupportedAppUsage
    private static UserEnvironment sCurrentUser;
    private static UserEnvironment sCurrentUser;
    private static boolean sUserRequired;
    private static boolean sUserRequired;
@@ -1191,12 +1202,13 @@ public class Environment {
    }
    }


    /**
    /**
     * Returns whether the primary shared/external storage media is a legacy
     * Returns whether the shared/external storage media is a
     * view that includes files not owned by the app.
     * legacy view that includes files not owned by the app.
     * <p>
     * <p>
     * This value may be different from the value requested by
     * This value may be different from the value requested by
     * {@code requestLegacyExternalStorage} in the app's manifest, since an app
     * {@code requestLegacyExternalStorage} in the app's manifest, since an app
     * may inherit its legacy state based on when it was first installed.
     * may inherit its legacy state based on when it was first installed, target sdk and other
     * factors.
     * <p>
     * <p>
     * Non-legacy apps can continue to discover and read media belonging to
     * Non-legacy apps can continue to discover and read media belonging to
     * other apps via {@link android.provider.MediaStore}.
     * other apps via {@link android.provider.MediaStore}.
@@ -1207,12 +1219,13 @@ public class Environment {
    }
    }


    /**
    /**
     * Returns whether the shared/external storage media at the given path is a
     * Returns whether the shared/external storage media is a
     * legacy view that includes files not owned by the app.
     * legacy view that includes files not owned by the app.
     * <p>
     * <p>
     * This value may be different from the value requested by
     * This value may be different from the value requested by
     * {@code requestLegacyExternalStorage} in the app's manifest, since an app
     * {@code requestLegacyExternalStorage} in the app's manifest, since an app
     * may inherit its legacy state based on when it was first installed.
     * may inherit its legacy state based on when it was first installed, target sdk and other
     * factors.
     * <p>
     * <p>
     * Non-legacy apps can continue to discover and read media belonging to
     * Non-legacy apps can continue to discover and read media belonging to
     * other apps via {@link android.provider.MediaStore}.
     * other apps via {@link android.provider.MediaStore}.
@@ -1232,24 +1245,23 @@ public class Environment {
            return false;
            return false;
        }
        }


        if (packageManager.checkPermission(Manifest.permission.WRITE_MEDIA_STORAGE,
        // TODO(b/150672994): Compat flags do not override instant app and isolated process's
                context.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
        //  behavior.
            return true;
        boolean defaultScopedStorage = Compatibility.isChangeEnabled(DEFAULT_SCOPED_STORAGE);
        }
        boolean forceEnableScopedStorage = Compatibility.isChangeEnabled(

                FORCE_ENABLE_SCOPED_STORAGE);
        if (packageManager.checkPermission(Manifest.permission.INSTALL_PACKAGES,
        // if Scoped Storage is strictly enforced, the app does *not* have legacy storage access
                context.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
        // Note: does not require packagename/uid as this is directly called from an app process
            return true;
        if (isScopedStorageEnforced(defaultScopedStorage, forceEnableScopedStorage)) {
            return false;
        }
        }
        final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
        // if Scoped Storage is strictly disabled, the app has legacy storage access
        final String[] packagesForUid = packageManager.getPackagesForUid(uid);
        // Note: does not require packagename/uid as this is directly called from an app process
        for (String packageName : packagesForUid) {
        if (isScopedStorageDisabled(defaultScopedStorage, forceEnableScopedStorage)) {
            if (appOps.checkOpNoThrow(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
                    uid, packageName) == AppOpsManager.MODE_ALLOWED) {
            return true;
            return true;
        }
        }
        }


        final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
        return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE,
        return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE,
                uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED;
                uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED;
    }
    }
@@ -1298,6 +1310,16 @@ public class Environment {
        }
        }
    }
    }


    private static boolean isScopedStorageEnforced(boolean defaultScopedStorage,
            boolean forceEnableScopedStorage) {
        return defaultScopedStorage && forceEnableScopedStorage;
    }

    private static boolean isScopedStorageDisabled(boolean defaultScopedStorage,
            boolean forceEnableScopedStorage) {
        return !defaultScopedStorage && !forceEnableScopedStorage;
    }

    static File getDirectory(String variableName, String defaultPath) {
    static File getDirectory(String variableName, String defaultPath) {
        String path = System.getenv(variableName);
        String path = System.getenv(variableName);
        return path == null ? new File(defaultPath) : new File(path);
        return path == null ? new File(defaultPath) : new File(path);