diff --git a/src/com/android/settings/applications/DirectoryAccessDetails.java b/src/com/android/settings/applications/DirectoryAccessDetails.java index 3e9bf47c66e..8346e78138c 100644 --- a/src/com/android/settings/applications/DirectoryAccessDetails.java +++ b/src/com/android/settings/applications/DirectoryAccessDetails.java @@ -44,8 +44,10 @@ import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceGroupAdapter; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.Preference.OnPreferenceClickListener; +import android.support.v7.preference.PreferenceCategory; import android.text.TextUtils; import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.PreferenceScreen; @@ -63,8 +65,10 @@ import com.android.settingslib.applications.AppUtils; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** * Detailed settings for an app's directory access permissions (A.K.A Scoped Directory Access). @@ -135,10 +139,9 @@ public class DirectoryAccessDetails extends AppInfoBase { } final int count = cursor.getCount(); if (count == 0) { - if (DEBUG) { - Log.d(TAG, "No permissions for " + mPackageName); - } - // TODO(b/72055774): display empty message + // This setting screen should not be reached if there was no permission, so just + // ignore it + Log.w(TAG, "No permissions for " + mPackageName); return; } @@ -162,7 +165,7 @@ public class DirectoryAccessDetails extends AppInfoBase { if (uuid == null) { // Primary storage entry: add right away prefsGroup.addPreference(newPreference(context, dir, providerUri, - /* uuid= */ null, dir, granted)); + /* uuid= */ null, dir, granted, /* children= */ null)); } else { // External volume entry: save it for later. ExternalVolume externalVolume = externalVolumes.get(uuid); @@ -222,46 +225,55 @@ public class DirectoryAccessDetails extends AppInfoBase { continue; } // First add the pref for the whole volume... - // TODO(b/72055774): add separator - 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 + final PreferenceCategory category = new PreferenceCategory(context); + prefsGroup.addPreference(category); + final Set children = new HashSet<>(volume.children.size()); + category.addPreference(newPreference(context, volumeName, providerUri, volume.uuid, + /* dir= */ null, volume.granted, children)); // ... 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)); + final SwitchPreference childPref = + newPreference(context, name, providerUri, volume.uuid, dir, pair.second, + /* children= */ null); + category.addPreference(childPref); + children.add(childPref); }); } } private SwitchPreference newPreference(Context context, String title, Uri providerUri, - String uuid, String dir, boolean granted) { + String uuid, String dir, boolean granted, @Nullable Set children) { final SwitchPreference pref = new SwitchPreference(context); pref.setKey(String.format("%s:%s", uuid, dir)); pref.setTitle(title); pref.setChecked(granted); pref.setOnPreferenceChangeListener((unused, value) -> { - resetDoNotAskAgain(context, value, providerUri, uuid, dir); + if (!Boolean.class.isInstance(value)) { + // Sanity check + Log.wtf(TAG, "Invalid value from switch: " + value); + return true; + } + final boolean newValue = ((Boolean) value).booleanValue(); + + resetDoNotAskAgain(context, newValue, providerUri, uuid, dir); + if (children != null) { + // When parent is granted, children should be hidden; and vice versa + final boolean newChildValue = !newValue; + for (SwitchPreference child : children) { + child.setVisible(newChildValue); + } + } return true; }); return pref; } - private void resetDoNotAskAgain(Context context, Object value, Uri providerUri, + private void resetDoNotAskAgain(Context context, boolean newValue, Uri providerUri, @Nullable String uuid, @Nullable String directory) { - if (!Boolean.class.isInstance(value)) { - // Sanity check - Log.wtf(TAG, "Invalid value from switch: " + value); - return; - } - final boolean newValue = ((Boolean) value).booleanValue(); if (DEBUG) { Log.d(TAG, "Asking " + providerUri + " to update " + uuid + "/" + directory + " to " + newValue);