Couple more Scoped Directory Access changes.
- Moved DirectoryAccessDetails rendering logic to refreshUi so it's updated. - Call ScopedAccessProvider to reset preferences on "Clear access" UI. Test: manual verification Test: atest CtsAppSecurityHostTestCases:ScopedDirectoryAccessTest#testResetDoNotAskAgain,testResetGranted Bug: 72055774 Change-Id: I4a6bf187cacfb59d948abbe71afc3b7500cb15aa
This commit is contained in:
@@ -18,12 +18,19 @@ package com.android.settings.applications;
|
|||||||
|
|
||||||
import static android.content.pm.ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
|
import static android.content.pm.ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
|
||||||
import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
|
import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
|
||||||
|
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.AUTHORITY;
|
||||||
|
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.COL_GRANTED;
|
||||||
|
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS;
|
||||||
|
|
||||||
|
import static com.android.settings.applications.AppStateDirectoryAccessBridge.DEBUG;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.AppGlobals;
|
import android.app.AppGlobals;
|
||||||
import android.app.GrantedUriPermission;
|
import android.app.GrantedUriPermission;
|
||||||
import android.app.LoaderManager;
|
import android.app.LoaderManager;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -32,6 +39,7 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.IPackageDataObserver;
|
import android.content.pm.IPackageDataObserver;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ProviderInfo;
|
import android.content.pm.ProviderInfo;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
@@ -369,7 +377,7 @@ public class AppStorageSettings extends AppInfoWithHeader
|
|||||||
boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
|
boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
// Clearing data failed for some obscure reason. Just log error for now
|
// Clearing data failed for some obscure reason. Just log error for now
|
||||||
Log.i(TAG, "Couldnt clear application user data for package:" + packageName);
|
Log.i(TAG, "Couldn't clear application user data for package:" + packageName);
|
||||||
showDialogInner(DLG_CANNOT_CLEAR_DATA, 0);
|
showDialogInner(DLG_CANNOT_CLEAR_DATA, 0);
|
||||||
} else {
|
} else {
|
||||||
mButtonsPref.setButton1Text(R.string.recompute_size);
|
mButtonsPref.setButton1Text(R.string.recompute_size);
|
||||||
@@ -449,10 +457,23 @@ public class AppStorageSettings extends AppInfoWithHeader
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void clearUriPermissions() {
|
private void clearUriPermissions() {
|
||||||
|
final Context context = getActivity();
|
||||||
|
final String packageName = mAppEntry.info.packageName;
|
||||||
// Synchronously revoke the permissions.
|
// Synchronously revoke the permissions.
|
||||||
final ActivityManager am = (ActivityManager) getActivity().getSystemService(
|
final ActivityManager am = (ActivityManager) context.getSystemService(
|
||||||
Context.ACTIVITY_SERVICE);
|
Context.ACTIVITY_SERVICE);
|
||||||
am.clearGrantedUriPermissions(mAppEntry.info.packageName);
|
am.clearGrantedUriPermissions(packageName);
|
||||||
|
|
||||||
|
|
||||||
|
// Also update the Scoped Directory Access UI permissions
|
||||||
|
final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
|
||||||
|
.authority(AUTHORITY).appendPath(TABLE_PERMISSIONS).appendPath("*")
|
||||||
|
.build();
|
||||||
|
Log.v(TAG, "Asking " + providerUri + " to delete permissions for " + packageName);
|
||||||
|
final int deleted = context.getContentResolver().delete(providerUri, null, new String[] {
|
||||||
|
packageName
|
||||||
|
});
|
||||||
|
Log.d(TAG, "Deleted " + deleted + " entries for package " + packageName);
|
||||||
|
|
||||||
// Update UI
|
// Update UI
|
||||||
refreshGrantedUriPermissions();
|
refreshGrantedUriPermissions();
|
||||||
|
@@ -121,9 +121,15 @@ public class DirectoryAccessDetails extends AppInfoBase {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
final Context context = getPrefContext();
|
|
||||||
addPreferencesFromResource(R.xml.directory_access_details);
|
addPreferencesFromResource(R.xml.directory_access_details);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean refreshUi() {
|
||||||
|
final Context context = getPrefContext();
|
||||||
final PreferenceScreen prefsGroup = getPreferenceScreen();
|
final PreferenceScreen prefsGroup = getPreferenceScreen();
|
||||||
|
prefsGroup.removeAll();
|
||||||
|
|
||||||
final Map<String, ExternalVolume> externalVolumes = new HashMap<>();
|
final Map<String, ExternalVolume> externalVolumes = new HashMap<>();
|
||||||
|
|
||||||
@@ -135,14 +141,14 @@ public class DirectoryAccessDetails extends AppInfoBase {
|
|||||||
TABLE_PERMISSIONS_COLUMNS, null, new String[] { mPackageName }, null)) {
|
TABLE_PERMISSIONS_COLUMNS, null, new String[] { mPackageName }, null)) {
|
||||||
if (cursor == null) {
|
if (cursor == null) {
|
||||||
Log.w(TAG, "Didn't get cursor for " + mPackageName);
|
Log.w(TAG, "Didn't get cursor for " + mPackageName);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
final int count = cursor.getCount();
|
final int count = cursor.getCount();
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
// This setting screen should not be reached if there was no permission, so just
|
// This setting screen should not be reached if there was no permission, so just
|
||||||
// ignore it
|
// ignore it
|
||||||
Log.w(TAG, "No permissions for " + mPackageName);
|
Log.w(TAG, "No permissions for " + mPackageName);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
@@ -163,9 +169,14 @@ public class DirectoryAccessDetails extends AppInfoBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
// Primary storage entry: add right away
|
if (dir == null) {
|
||||||
prefsGroup.addPreference(newPreference(context, dir, providerUri,
|
// Sanity check, shouldn't happen
|
||||||
/* uuid= */ null, dir, granted, /* children= */ null));
|
Log.wtf(TAG, "Ignoring permission on primary storage root");
|
||||||
|
} else {
|
||||||
|
// Primary storage entry: add right away
|
||||||
|
prefsGroup.addPreference(newPreference(context, dir, providerUri,
|
||||||
|
/* uuid= */ null, dir, granted, /* children= */ null));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// External volume entry: save it for later.
|
// External volume entry: save it for later.
|
||||||
ExternalVolume externalVolume = externalVolumes.get(uuid);
|
ExternalVolume externalVolume = externalVolumes.get(uuid);
|
||||||
@@ -190,7 +201,7 @@ public class DirectoryAccessDetails extends AppInfoBase {
|
|||||||
|
|
||||||
if (externalVolumes.isEmpty()) {
|
if (externalVolumes.isEmpty()) {
|
||||||
// We're done!
|
// We're done!
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add entries from external volumes
|
// Add entries from external volumes
|
||||||
@@ -200,7 +211,7 @@ public class DirectoryAccessDetails extends AppInfoBase {
|
|||||||
final List<VolumeInfo> volumes = sm.getVolumes();
|
final List<VolumeInfo> volumes = sm.getVolumes();
|
||||||
if (volumes.isEmpty()) {
|
if (volumes.isEmpty()) {
|
||||||
Log.w(TAG, "StorageManager returned no secondary volumes");
|
Log.w(TAG, "StorageManager returned no secondary volumes");
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
final Map<String, String> volumeNames = new HashMap<>(volumes.size());
|
final Map<String, String> volumeNames = new HashMap<>(volumes.size());
|
||||||
for (VolumeInfo volume : volumes) {
|
for (VolumeInfo volume : volumes) {
|
||||||
@@ -243,6 +254,7 @@ public class DirectoryAccessDetails extends AppInfoBase {
|
|||||||
children.add(childPref);
|
children.add(childPref);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwitchPreference newPreference(Context context, String title, Uri providerUri,
|
private SwitchPreference newPreference(Context context, String title, Uri providerUri,
|
||||||
@@ -287,11 +299,6 @@ public class DirectoryAccessDetails extends AppInfoBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean refreshUi() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AlertDialog createDialog(int id, int errorCode) {
|
protected AlertDialog createDialog(int id, int errorCode) {
|
||||||
return null;
|
return null;
|
||||||
|
Reference in New Issue
Block a user