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

Commit b441d90f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Changed DirectoryAccessDetails to handle children directory on external volumes."

parents bb2a2b9b 025883da
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -9211,6 +9211,10 @@
    <!-- Keywords for Directory Access settings -->
    <string name="keywords_directory_access">directory access</string>
    <!-- String used to describe the name of a directory in a volume; it must
         show both names, with the directory name wrapped in parenthesis -->
    <string name="directory_on_volume"><xliff:g id="volume" example="SD Card">%1$s</xliff:g> (<xliff:g id="directory" example="Movies">%2$s</xliff:g>)</string>
    <!-- Account type associated with the backup account. Empty for AOSP. [DO NOT TRANSLATE] -->
    <string name="account_type" translatable="false"></string>
    <!-- Package to target for Account credential confirmation. This will allow users to
+4 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AppGlobals;
import android.app.GrantedUriPermission;
import android.app.LoaderManager;
import android.content.Context;
import android.content.DialogInterface;
@@ -399,7 +400,7 @@ public class AppStorageSettings extends AppInfoWithHeader
        // Gets all URI permissions from am.
        ActivityManager am = (ActivityManager) getActivity().getSystemService(
                Context.ACTIVITY_SERVICE);
        List<UriPermission> perms =
        List<GrantedUriPermission> perms =
                am.getGrantedUriPermissions(mAppEntry.info.packageName).getList();

        if (perms.isEmpty()) {
@@ -411,8 +412,8 @@ public class AppStorageSettings extends AppInfoWithHeader

        // Group number of URIs by app.
        Map<CharSequence, MutableInt> uriCounters = new TreeMap<>();
        for (UriPermission perm : perms) {
            String authority = perm.getUri().getAuthority();
        for (GrantedUriPermission perm : perms) {
            String authority = perm.uri.getAuthority();
            ProviderInfo provider = pm.resolveContentProvider(authority, 0);
            CharSequence app = provider.applicationInfo.loadLabel(pm);
            MutableInt count = uriCounters.get(app);
+87 −41
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.os.storage.StorageVolume.ScopedAccessProviderContract.COL_
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS;
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COLUMNS;
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_DIRECTORY;
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_GRANTED;
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_PACKAGE;
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_VOLUME_UUID;

@@ -120,8 +121,7 @@ public class DirectoryAccessDetails extends AppInfoBase {
        addPreferencesFromResource(R.xml.directory_access_details);
        final PreferenceScreen prefsGroup = getPreferenceScreen();

        // Set external directory UUIDs.
        ArraySet<String> externalDirectoryUuids = null;
        final Map<String, ExternalVolume> externalVolumes = new HashMap<>();

        final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(AUTHORITY).appendPath(TABLE_PERMISSIONS).appendPath("*")
@@ -146,8 +146,10 @@ public class DirectoryAccessDetails extends AppInfoBase {
                final String pkg = cursor.getString(TABLE_PERMISSIONS_COL_PACKAGE);
                final String uuid = cursor.getString(TABLE_PERMISSIONS_COL_VOLUME_UUID);
                final String dir = cursor.getString(TABLE_PERMISSIONS_COL_DIRECTORY);
                final boolean granted = cursor.getInt(TABLE_PERMISSIONS_COL_GRANTED) == 1;
                if (VERBOSE) {
                    Log.v(TAG, "Pkg:"  + pkg + " uuid: " + uuid + " dir: " + dir);
                    Log.v(TAG, "Pkg:"  + pkg + " uuid: " + uuid + " dir: " + dir
                            + " granted:" + granted);
                }

                if (!mPackageName.equals(pkg)) {
@@ -159,24 +161,37 @@ public class DirectoryAccessDetails extends AppInfoBase {

                if (uuid == null) {
                    // Primary storage entry: add right away
                    prefsGroup.addPreference(
                            newPreference(context, dir, providerUri, /* uuid= */ null, dir));
                    prefsGroup.addPreference(newPreference(context, dir, providerUri,
                            /* uuid= */ null, dir, granted));
                } else {
                    // External volume entry: save it for later.
                    if (externalDirectoryUuids == null) {
                        externalDirectoryUuids = new ArraySet<>(1);
                    ExternalVolume externalVolume = externalVolumes.get(uuid);
                    if (externalVolume == null) {
                        externalVolume = new ExternalVolume(uuid);
                        externalVolumes.put(uuid, externalVolume);
                    }
                    if (dir == null) {
                        // Whole volume
                        externalVolume.granted = granted;
                    } else {
                        // Directory only
                        externalVolume.children.add(new Pair<>(dir, granted));
                    }
                    externalDirectoryUuids.add(uuid);
                }
            }
        }

        // Add entries from external volumes
        if (externalDirectoryUuids != null) {
        if (VERBOSE) {
                Log.v(TAG, "adding external directories: " + externalDirectoryUuids);
            Log.v(TAG, "external volumes: " + externalVolumes);
        }

        if (externalVolumes.isEmpty()) {
            // We're done!
            return;
        }

        // Add entries from external volumes

        // Query StorageManager to get the user-friendly volume names.
        final StorageManager sm = context.getSystemService(StorageManager.class);
        final List<VolumeInfo> volumes = sm.getVolumes();
@@ -200,23 +215,38 @@ public class DirectoryAccessDetails extends AppInfoBase {
            Log.v(TAG, "UUID -> name mapping: " + volumeNames);
        }

            externalDirectoryUuids.forEach((uuid) ->{
                final String name = volumeNames.get(uuid);
        for (ExternalVolume volume : externalVolumes.values()) {
            final String volumeName = volumeNames.get(volume.uuid);
            if (volumeName == null) {
                Log.w(TAG, "Ignoring entry for invalid UUID: " + volume.uuid);
                continue;
            }
            // First add the pref for the whole volume...
            // TODO(b/72055774): add separator
                prefsGroup.addPreference(
                        newPreference(context, name, providerUri, uuid, /* dir= */ null));
            prefsGroup.addPreference(newPreference(context, volumeName, providerUri, volume.uuid,
                    /* dir= */ null, volume.granted));
            // TODO(b/72055774): make sure children are gone when parent is toggled on - should be
            // handled automatically if we're refreshing the activity on change, otherwise we'll
            // need to explicitly remove them

            // ... then the children prefs
            volume.children.forEach((pair) -> {
                final String dir = pair.first;
                final String name = context.getResources()
                        .getString(R.string.directory_on_volume, volumeName, dir);
                prefsGroup
                        .addPreference(newPreference(context, name, providerUri, volume.uuid,
                                dir, pair.second));
            });
        }
        return;
    }


    private SwitchPreference newPreference(Context context, String title, Uri providerUri,
            String uuid, String dir) {
            String uuid, String dir, boolean granted) {
        final SwitchPreference pref = new SwitchPreference(context);
        pref.setKey(String.format("%s:%s", uuid, dir));
        pref.setTitle(title);
        pref.setChecked(false);
        pref.setChecked(granted);
        pref.setOnPreferenceChangeListener((unused, value) -> {
            resetDoNotAskAgain(context, value, providerUri, uuid, dir);
            return true;
@@ -259,4 +289,20 @@ public class DirectoryAccessDetails extends AppInfoBase {
    public int getMetricsCategory() {
        return MetricsEvent.APPLICATIONS_DIRECTORY_ACCESS_DETAIL;
    }

    private static class ExternalVolume {
        final String uuid;
        final List<Pair<String, Boolean>> children = new ArrayList<>();
        boolean granted;

        ExternalVolume(String uuid) {
            this.uuid = uuid;
        }

        @Override
        public String toString() {
            return "ExternalVolume: [uuid=" + uuid + ", granted=" + granted +
                    ", children=" + children + "]";
        }
    }
}