Loading src/com/android/documentsui/ScopedAccessProvider.java +33 −5 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static com.android.documentsui.base.SharedMinimal.getUriPermission; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_ASK_AGAIN; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_GRANTED; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_NEVER_ASK; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.clearScopedAccessPreferences; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getAllPackages; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getAllPermissions; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.setScopedAccessPermissionStatus; Loading Loading @@ -351,10 +352,20 @@ public class ScopedAccessProvider extends ContentProvider { Log.w(TAG, "could not parse uuid and directory on " + uri); continue; } final String uuid = Providers.ROOT_ID_DEVICE.equals(uuidAndDir[0]) // TODO(b/72055774): to make things uglier, the Documents directory in the primary // storage is a special case as its URI is "$ROOT_ID_HOME", instead of // "${ROOT_ID_DEVICE}/Documents. This is another reason to move this logic to the // provider... final String uuid, dir; if (Providers.ROOT_ID_HOME.equals(uuidAndDir[0])) { uuid = null; dir = Environment.DIRECTORY_DOCUMENTS; } else { uuid = Providers.ROOT_ID_DEVICE.equals(uuidAndDir[0]) ? null // primary : uuidAndDir[0]; // external volume final String dir = uuidAndDir.length == 1 ? null : uuidAndDir[1]; dir = uuidAndDir.length == 1 ? null : uuidAndDir[1]; } permissions .add(new Permission(uriPermission.packageName, uuid, dir, PERMISSION_GRANTED)); } Loading @@ -373,9 +384,26 @@ public class ScopedAccessProvider extends ContentProvider { @Override public int delete(Uri uri, String selection, String[] selectionArgs) { if (sMatcher.match(uri) != URI_PERMISSIONS) { throw new UnsupportedOperationException("delete(): unsupported " + uri); } if (DEBUG) { Log.v(TAG, "delete(" + uri + "): " + Arrays.toString(selectionArgs)); } // TODO(b/72055774): add unit tests for invalid input checkArgument(selectionArgs != null && selectionArgs.length == 1, "Must have exactly 1 args: package_name" + Arrays.toString(selectionArgs)); final String packageName = selectionArgs[0]; // Delete just our preferences - the URI permissions is handled externally // TODO(b/72055774): move logic to revoke permissions here, so AppStorageSettings does // not need to call am.clearGrantedUriPermissions(packageName) (then we could remove that // method from ActivityManager) return clearScopedAccessPreferences(getContext(), packageName); } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { if (sMatcher.match(uri) != URI_PERMISSIONS) { Loading src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java +4 −1 Original line number Diff line number Diff line Loading @@ -100,21 +100,24 @@ public class ScopedAccessLocalPreferences { getPrefs(context).edit().putInt(key, status).apply(); } public static void clearScopedAccessPreferences(Context context, String packageName) { public static int clearScopedAccessPreferences(Context context, String packageName) { final String keySubstring = "|" + packageName + "|"; final SharedPreferences prefs = getPrefs(context); Editor editor = null; int removed = 0; for (final String key : prefs.getAll().keySet()) { if (key.contains(keySubstring)) { if (editor == null) { editor = prefs.edit(); } editor.remove(key); removed ++; } } if (editor != null) { editor.apply(); } return removed; } private static String getScopedAccessDenialsKey(String packageName, @Nullable String uuid, Loading Loading
src/com/android/documentsui/ScopedAccessProvider.java +33 −5 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static com.android.documentsui.base.SharedMinimal.getUriPermission; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_ASK_AGAIN; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_GRANTED; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_NEVER_ASK; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.clearScopedAccessPreferences; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getAllPackages; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getAllPermissions; import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.setScopedAccessPermissionStatus; Loading Loading @@ -351,10 +352,20 @@ public class ScopedAccessProvider extends ContentProvider { Log.w(TAG, "could not parse uuid and directory on " + uri); continue; } final String uuid = Providers.ROOT_ID_DEVICE.equals(uuidAndDir[0]) // TODO(b/72055774): to make things uglier, the Documents directory in the primary // storage is a special case as its URI is "$ROOT_ID_HOME", instead of // "${ROOT_ID_DEVICE}/Documents. This is another reason to move this logic to the // provider... final String uuid, dir; if (Providers.ROOT_ID_HOME.equals(uuidAndDir[0])) { uuid = null; dir = Environment.DIRECTORY_DOCUMENTS; } else { uuid = Providers.ROOT_ID_DEVICE.equals(uuidAndDir[0]) ? null // primary : uuidAndDir[0]; // external volume final String dir = uuidAndDir.length == 1 ? null : uuidAndDir[1]; dir = uuidAndDir.length == 1 ? null : uuidAndDir[1]; } permissions .add(new Permission(uriPermission.packageName, uuid, dir, PERMISSION_GRANTED)); } Loading @@ -373,9 +384,26 @@ public class ScopedAccessProvider extends ContentProvider { @Override public int delete(Uri uri, String selection, String[] selectionArgs) { if (sMatcher.match(uri) != URI_PERMISSIONS) { throw new UnsupportedOperationException("delete(): unsupported " + uri); } if (DEBUG) { Log.v(TAG, "delete(" + uri + "): " + Arrays.toString(selectionArgs)); } // TODO(b/72055774): add unit tests for invalid input checkArgument(selectionArgs != null && selectionArgs.length == 1, "Must have exactly 1 args: package_name" + Arrays.toString(selectionArgs)); final String packageName = selectionArgs[0]; // Delete just our preferences - the URI permissions is handled externally // TODO(b/72055774): move logic to revoke permissions here, so AppStorageSettings does // not need to call am.clearGrantedUriPermissions(packageName) (then we could remove that // method from ActivityManager) return clearScopedAccessPreferences(getContext(), packageName); } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { if (sMatcher.match(uri) != URI_PERMISSIONS) { Loading
src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java +4 −1 Original line number Diff line number Diff line Loading @@ -100,21 +100,24 @@ public class ScopedAccessLocalPreferences { getPrefs(context).edit().putInt(key, status).apply(); } public static void clearScopedAccessPreferences(Context context, String packageName) { public static int clearScopedAccessPreferences(Context context, String packageName) { final String keySubstring = "|" + packageName + "|"; final SharedPreferences prefs = getPrefs(context); Editor editor = null; int removed = 0; for (final String key : prefs.getAll().keySet()) { if (key.contains(keySubstring)) { if (editor == null) { editor = prefs.edit(); } editor.remove(key); removed ++; } } if (editor != null) { editor.apply(); } return removed; } private static String getScopedAccessDenialsKey(String packageName, @Nullable String uuid, Loading