From 430b94bbc113b5751833bb438fd5e6294c8f0b6e Mon Sep 17 00:00:00 2001 From: shafik Date: Mon, 6 Jan 2020 13:50:10 +0000 Subject: [PATCH] Add settings UI for MANAGE_EXTERNAL_STORAGE Adds a Special App Access setting for the app-op OP_MANAGE_EXTERNAL_STORAGE. All apps requesting the corresponding permission will be displayed in the settings page. Toggling the preference switch for an app will grant/revoke the app-op. All of the external references to the permission, app-op and their corresponding activities and logic use the name "Manage External Storage". All of the external displays and strings use the name "All files access" Test: * Install app with uses-permission MANAGE_EXTERNAL_STORAGE * Observe it appearing the All files access page * Toggle the switch and observe the change in 'adb shell dumpsys appops' Bug: 146425146 Change-Id: If5c9c5daa3616a3310c090283acfda933bf9df26 --- res/values/strings.xml | 12 ++ ...ge_external_storage_permission_details.xml | 29 +++ res/xml/special_access.xml | 9 + src/com/android/settings/Settings.java | 1 + .../applications/AppStateAppOpsBridge.java | 2 +- .../AppStateManageExternalStorageBridge.java | 72 +++++++ .../appinfo/ManageExternalStorageDetails.java | 180 ++++++++++++++++++ .../manageapplications/AppFilterRegistry.java | 13 +- .../ManageApplications.java | 19 ++ 9 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 res/xml/manage_external_storage_permission_details.xml create mode 100644 src/com/android/settings/applications/AppStateManageExternalStorageBridge.java create mode 100644 src/com/android/settings/applications/appinfo/ManageExternalStorageDetails.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 74f4621e338..b1d8febd0c4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6954,6 +6954,8 @@ + + @@ -9429,6 +9431,16 @@ Allow this app to display on top of other apps you\u2019re using. It may interfere with your use of those apps or change the way they seem to appear or behave. + + All files access + + Allow access to manage all files + + Allow this app to read, modify and delete all files on this device or any connected storage volumes. If granted, app may access files without your explicit knowledge. + + Can access all files + vr virtual reality listener stereo helper service diff --git a/res/xml/manage_external_storage_permission_details.xml b/res/xml/manage_external_storage_permission_details.xml new file mode 100644 index 00000000000..b540ff6687c --- /dev/null +++ b/res/xml/manage_external_storage_permission_details.xml @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml index 25422bf1805..e511d178682 100644 --- a/res/xml/special_access.xml +++ b/res/xml/special_access.xml @@ -20,6 +20,15 @@ android:key="special_app_access_screen" android:title="@string/special_access"> + + + + This string is used in the "All files access" page that displays all apps requesting + * {@link android.Manifest.permission#MANAGE_EXTERNAL_STORAGE} + */ + public static CharSequence getSummary(Context context, AppEntry entry) { + final PermissionState state; + if (entry.extraInfo instanceof PermissionState) { + state = (PermissionState) entry.extraInfo; + } else { + state = new AppStateManageExternalStorageBridge(context, null, null) + .getManageExternalStoragePermState(entry.info.packageName, entry.info.uid); + } + + return getSummary(context, state); + } + + private static CharSequence getSummary(Context context, PermissionState state) { + return context.getString(state.isPermissible() + ? R.string.app_permission_summary_allowed + : R.string.app_permission_summary_not_allowed); + } +} diff --git a/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java b/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java index 250dce07f31..58907a7bb71 100644 --- a/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java +++ b/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java @@ -20,6 +20,7 @@ import androidx.annotation.IntDef; import com.android.settings.R; import com.android.settings.applications.AppStateInstallAppsBridge; +import com.android.settings.applications.AppStateManageExternalStorageBridge; import com.android.settings.applications.AppStateNotificationBridge; import com.android.settings.applications.AppStateOverlayBridge; import com.android.settings.applications.AppStatePowerBridge; @@ -71,14 +72,15 @@ public class AppFilterRegistry { public static final int FILTER_APPS_INSTALL_SOURCES = 13; public static final int FILTER_APP_CAN_CHANGE_WIFI_STATE = 15; public static final int FILTER_APPS_BLOCKED = 16; - // Next id: 17 + public static final int FILTER_MANAGE_EXTERNAL_STORAGE = 17; + // Next id: 18. If you add an entry here, length of mFilters should be updated private static AppFilterRegistry sRegistry; private final AppFilterItem[] mFilters; private AppFilterRegistry() { - mFilters = new AppFilterItem[17]; + mFilters = new AppFilterItem[18]; // High power whitelist, on mFilters[FILTER_APPS_POWER_WHITELIST] = new AppFilterItem( @@ -178,6 +180,11 @@ public class AppFilterRegistry { AppStateNotificationBridge.FILTER_APP_NOTIFICATION_BLOCKED, FILTER_APPS_BLOCKED, R.string.filter_notif_blocked_apps); + + mFilters[FILTER_MANAGE_EXTERNAL_STORAGE] = new AppFilterItem( + AppStateManageExternalStorageBridge.FILTER_MANAGE_EXTERNAL_STORAGE, + FILTER_MANAGE_EXTERNAL_STORAGE, + R.string.filter_manage_external_storage); } public static AppFilterRegistry getInstance() { @@ -204,6 +211,8 @@ public class AppFilterRegistry { return FILTER_APP_CAN_CHANGE_WIFI_STATE; case ManageApplications.LIST_TYPE_NOTIFICATION: return FILTER_APPS_RECENT; + case ManageApplications.LIST_MANAGE_EXTERNAL_STORAGE: + return FILTER_MANAGE_EXTERNAL_STORAGE; default: return FILTER_APPS_ALL; } diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index 02e42e2ee61..d38893f26d1 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -88,6 +88,7 @@ import com.android.settings.Settings.WriteSettingsActivity; import com.android.settings.SettingsActivity; import com.android.settings.Utils; import com.android.settings.applications.AppInfoBase; +import com.android.settings.applications.AppStateManageExternalStorageBridge; import com.android.settings.applications.AppStateAppOpsBridge.PermissionState; import com.android.settings.applications.AppStateBaseBridge; import com.android.settings.applications.AppStateInstallAppsBridge; @@ -100,6 +101,7 @@ import com.android.settings.applications.AppStateUsageBridge.UsageState; import com.android.settings.applications.AppStateWriteSettingsBridge; import com.android.settings.applications.AppStorageSettings; import com.android.settings.applications.UsageAccessDetails; +import com.android.settings.applications.appinfo.ManageExternalStorageDetails; import com.android.settings.applications.appinfo.AppInfoDashboardFragment; import com.android.settings.applications.appinfo.DrawOverlayDetails; import com.android.settings.applications.appinfo.ExternalSourcesDetails; @@ -224,6 +226,7 @@ public class ManageApplications extends InstrumentedFragment public static final int LIST_TYPE_MOVIES = 10; public static final int LIST_TYPE_PHOTOGRAPHY = 11; public static final int LIST_TYPE_WIFI_ACCESS = 13; + public static final int LIST_MANAGE_EXTERNAL_STORAGE = 14; // List types that should show instant apps. public static final Set LIST_TYPES_WITH_INSTANT = new ArraySet<>(Arrays.asList( @@ -311,6 +314,9 @@ public class ManageApplications extends InstrumentedFragment } else if (className.equals(Settings.ChangeWifiStateActivity.class.getName())) { mListType = LIST_TYPE_WIFI_ACCESS; screenTitle = R.string.change_wifi_state_title; + } else if (className.equals(Settings.ManageExternalStorageActivity.class.getName())) { + mListType = LIST_MANAGE_EXTERNAL_STORAGE; + screenTitle = R.string.manage_external_storage_title; } else if (className.equals(Settings.NotificationAppListActivity.class.getName())) { mListType = LIST_TYPE_NOTIFICATION; mUsageStatsManager = IUsageStatsManager.Stub.asInterface( @@ -538,6 +544,8 @@ public class ManageApplications extends InstrumentedFragment return SettingsEnums.MANAGE_EXTERNAL_SOURCES; case LIST_TYPE_WIFI_ACCESS: return SettingsEnums.CONFIGURE_WIFI; + case LIST_MANAGE_EXTERNAL_STORAGE: + return SettingsEnums.MANAGE_EXTERNAL_STORAGE; default: return SettingsEnums.PAGE_UNKNOWN; } @@ -640,6 +648,10 @@ public class ManageApplications extends InstrumentedFragment startAppInfoFragment(ChangeWifiStateDetails.class, R.string.change_wifi_state_title); break; + case LIST_MANAGE_EXTERNAL_STORAGE: + startAppInfoFragment(ManageExternalStorageDetails.class, + R.string.manage_external_storage_title); + break; // TODO: Figure out if there is a way where we can spin up the profile's settings // process ahead of time, to avoid a long load of data when user clicks on a managed // app. Maybe when they load the list of apps that contains managed profile apps. @@ -713,6 +725,8 @@ public class ManageApplications extends InstrumentedFragment return R.string.help_uri_apps_photography; case LIST_TYPE_WIFI_ACCESS: return R.string.help_uri_apps_wifi_access; + case LIST_MANAGE_EXTERNAL_STORAGE: + return R.string.help_uri_manage_external_storage; default: case LIST_TYPE_MAIN: return R.string.help_uri_apps; @@ -1031,6 +1045,8 @@ public class ManageApplications extends InstrumentedFragment mExtraInfoBridge = new AppStateInstallAppsBridge(mContext, mState, this); } else if (mManageApplications.mListType == LIST_TYPE_WIFI_ACCESS) { mExtraInfoBridge = new AppStateChangeWifiStateBridge(mContext, mState, this); + } else if (mManageApplications.mListType == LIST_MANAGE_EXTERNAL_STORAGE) { + mExtraInfoBridge = new AppStateManageExternalStorageBridge(mContext, mState, this); } else { mExtraInfoBridge = null; } @@ -1486,6 +1502,9 @@ public class ManageApplications extends InstrumentedFragment case LIST_TYPE_WIFI_ACCESS: holder.setSummary(ChangeWifiStateDetails.getSummary(mContext, entry)); break; + case LIST_MANAGE_EXTERNAL_STORAGE: + holder.setSummary(ManageExternalStorageDetails.getSummary(mContext, entry)); + break; default: holder.updateSizeText(entry, mManageApplications.mInvalidSizeStr, mWhichSize); break;