From fee785645b57c519a31ed403e60e8f76dcc8abbb Mon Sep 17 00:00:00 2001 From: Billy Lau Date: Mon, 27 Jul 2015 12:57:07 +0100 Subject: [PATCH] Bug: 22718745 Intents to 'draw over other apps' should go direct to the package's page instead of the top level one Settings: Added two activities to handle app-specific Intent when app invoke permission management UI. SettingsActivity: Added two fragment classes to handle app-specific Intent when app invoke permission management UI. AndroidManifest.xml: We handle both Intent to top level settings and app-specific management UI for app ops protected permissions. AppStateAppOpsBridge: Added a new field to PermissionState to keep track of permission declared vs one that is actually granted during install time. AppState{Overlay/Usage/WriteSettings}Bridge: Updated the fields affected by changes in PermissionState. {DrawOverlay/UsageAccess/WriteSettings}Details: Disabled the toggling of permission if the app did not declare for the asked permission. Change-Id: Ibf63e4d9a4fbf7899a93d2176abb1204c4f75557 --- AndroidManifest.xml | 24 +++++++++++++++++++ src/com/android/settings/Settings.java | 2 ++ .../android/settings/SettingsActivity.java | 4 ++++ .../applications/AppStateAppOpsBridge.java | 15 +++++++----- .../applications/AppStateOverlayBridge.java | 1 + .../applications/AppStateUsageBridge.java | 1 + .../AppStateWriteSettingsBridge.java | 1 + .../applications/DrawOverlayDetails.java | 2 ++ .../applications/UsageAccessDetails.java | 1 + .../applications/WriteSettingsDetails.java | 2 ++ 10 files changed, 47 insertions(+), 6 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 1fef2337b4e..ce5308aff73 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2541,6 +2541,18 @@ android:value="com.android.settings.applications.ManageApplications" /> + + + + + + + + + @@ -2552,5 +2564,17 @@ android:value="com.android.settings.applications.ManageApplications" /> + + + + + + + + + diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index f606193a7b3..7b94d795edf 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -116,4 +116,6 @@ public class Settings extends SettingsActivity { public static class MemorySettingsActivity extends SettingsActivity { /* empty */ } public static class OverlaySettingsActivity extends SettingsActivity { /* empty */ } public static class WriteSettingsActivity extends SettingsActivity { /* empty */ } + public static class AppDrawOverlaySettingsActivity extends SettingsActivity { /* empty */ } + public static class AppWriteSettingsActivity extends SettingsActivity { /* empty */ } } diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 442ce60ef46..8edec09f5f5 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -70,12 +70,14 @@ import com.android.settings.accessibility.AccessibilitySettings; import com.android.settings.accessibility.CaptionPropertiesFragment; import com.android.settings.accounts.AccountSettings; import com.android.settings.accounts.AccountSyncSettings; +import com.android.settings.applications.DrawOverlayDetails; import com.android.settings.applications.InstalledAppDetails; import com.android.settings.applications.ManageApplications; import com.android.settings.applications.ManageAssist; import com.android.settings.applications.ProcessStatsSummary; import com.android.settings.applications.ProcessStatsUi; import com.android.settings.applications.UsageAccessDetails; +import com.android.settings.applications.WriteSettingsDetails; import com.android.settings.bluetooth.BluetoothSettings; import com.android.settings.dashboard.DashboardCategory; import com.android.settings.dashboard.DashboardSummary; @@ -350,6 +352,8 @@ public class SettingsActivity extends Activity ProcessStatsUi.class.getName(), PowerUsageDetail.class.getName(), ProcessStatsSummary.class.getName(), + DrawOverlayDetails.class.getName(), + WriteSettingsDetails.class.getName(), }; diff --git a/src/com/android/settings/applications/AppStateAppOpsBridge.java b/src/com/android/settings/applications/AppStateAppOpsBridge.java index 20a00bdb0a6..1a693223f31 100644 --- a/src/com/android/settings/applications/AppStateAppOpsBridge.java +++ b/src/com/android/settings/applications/AppStateAppOpsBridge.java @@ -88,10 +88,12 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge { int[] permissionFlags = permissionState.packageInfo.requestedPermissionsFlags; if (requestedPermissions != null) { for (int i = 0; i < requestedPermissions.length; i++) { - if (mPermissions[0].equals(requestedPermissions[i]) && - (permissionFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) { + if (mPermissions[0].equals(requestedPermissions[i])) { permissionState.permissionDeclared = true; - break; + if ((permissionFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) { + permissionState.staticPermissionGranted = true; + break; + } } } } @@ -164,7 +166,7 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge { } /* - * This method will set the packageInfo and permissionDeclared field of the associated + * This method will set the packageInfo and staticPermissionGranted field of the associated * PermissionState, which describes a particular package. */ private void loadPermissionsStates(SparseArray> entries) { @@ -185,7 +187,7 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge { final PermissionState pe = entriesForProfile.get(packageInfo.packageName); if (pe != null) { pe.packageInfo = packageInfo; - pe.permissionDeclared = true; + pe.staticPermissionGranted = true; } } } @@ -279,6 +281,7 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge { public final String packageName; public final UserHandle userHandle; public PackageInfo packageInfo; + public boolean staticPermissionGranted; public boolean permissionDeclared; public int appOpMode; @@ -293,7 +296,7 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge { // permission (this means pre-M gets approval during install time; M apps gets approval // during runtime. if (appOpMode == AppOpsManager.MODE_DEFAULT) { - return permissionDeclared; + return staticPermissionGranted; } return appOpMode == AppOpsManager.MODE_ALLOWED; } diff --git a/src/com/android/settings/applications/AppStateOverlayBridge.java b/src/com/android/settings/applications/AppStateOverlayBridge.java index 75900a43a30..c6030280762 100644 --- a/src/com/android/settings/applications/AppStateOverlayBridge.java +++ b/src/com/android/settings/applications/AppStateOverlayBridge.java @@ -66,6 +66,7 @@ public class AppStateOverlayBridge extends AppStateAppOpsBridge { this.packageInfo = permissionState.packageInfo; this.appOpMode = permissionState.appOpMode; this.permissionDeclared = permissionState.permissionDeclared; + this.staticPermissionGranted = permissionState.staticPermissionGranted; } } diff --git a/src/com/android/settings/applications/AppStateUsageBridge.java b/src/com/android/settings/applications/AppStateUsageBridge.java index a1529017ea9..ef5a2c75382 100644 --- a/src/com/android/settings/applications/AppStateUsageBridge.java +++ b/src/com/android/settings/applications/AppStateUsageBridge.java @@ -57,6 +57,7 @@ public class AppStateUsageBridge extends AppStateAppOpsBridge { this.packageInfo = permissionState.packageInfo; this.appOpMode = permissionState.appOpMode; this.permissionDeclared = permissionState.permissionDeclared; + this.staticPermissionGranted = permissionState.staticPermissionGranted; } } diff --git a/src/com/android/settings/applications/AppStateWriteSettingsBridge.java b/src/com/android/settings/applications/AppStateWriteSettingsBridge.java index e43b5f56fb1..9dbe13bc543 100644 --- a/src/com/android/settings/applications/AppStateWriteSettingsBridge.java +++ b/src/com/android/settings/applications/AppStateWriteSettingsBridge.java @@ -66,6 +66,7 @@ public class AppStateWriteSettingsBridge extends AppStateAppOpsBridge { this.packageInfo = permissionState.packageInfo; this.appOpMode = permissionState.appOpMode; this.permissionDeclared = permissionState.permissionDeclared; + this.staticPermissionGranted = permissionState.staticPermissionGranted; } } diff --git a/src/com/android/settings/applications/DrawOverlayDetails.java b/src/com/android/settings/applications/DrawOverlayDetails.java index 4ea45b1dce7..ef92c21c5b5 100644 --- a/src/com/android/settings/applications/DrawOverlayDetails.java +++ b/src/com/android/settings/applications/DrawOverlayDetails.java @@ -143,6 +143,8 @@ public class DrawOverlayDetails extends AppInfoWithHeader implements OnPreferenc boolean isAllowed = mOverlayState.isPermissible(); mSwitchPref.setChecked(isAllowed); + // you cannot ask a user to grant you a permission you did not have! + mSwitchPref.setEnabled(mOverlayState.permissionDeclared); mOverlayPrefs.setEnabled(isAllowed); getPreferenceScreen().removePreference(mOverlayPrefs); diff --git a/src/com/android/settings/applications/UsageAccessDetails.java b/src/com/android/settings/applications/UsageAccessDetails.java index 5317282cd94..7af1d9bfe5a 100644 --- a/src/com/android/settings/applications/UsageAccessDetails.java +++ b/src/com/android/settings/applications/UsageAccessDetails.java @@ -130,6 +130,7 @@ public class UsageAccessDetails extends AppInfoWithHeader implements OnPreferenc boolean hasAccess = mUsageState.isPermissible(); mSwitchPref.setChecked(hasAccess); + mSwitchPref.setEnabled(mUsageState.permissionDeclared); mUsagePrefs.setEnabled(hasAccess); ResolveInfo resolveInfo = mPm.resolveActivityAsUser(mSettingsIntent, diff --git a/src/com/android/settings/applications/WriteSettingsDetails.java b/src/com/android/settings/applications/WriteSettingsDetails.java index 30533c66d6a..c89e7b34d58 100644 --- a/src/com/android/settings/applications/WriteSettingsDetails.java +++ b/src/com/android/settings/applications/WriteSettingsDetails.java @@ -142,6 +142,8 @@ public class WriteSettingsDetails extends AppInfoWithHeader implements OnPrefere boolean canWrite = mWriteSettingsState.isPermissible(); mSwitchPref.setChecked(canWrite); + // you can't ask a user for a permission you didn't even declare! + mSwitchPref.setEnabled(mWriteSettingsState.permissionDeclared); mWriteSettingsPrefs.setEnabled(canWrite); getPreferenceScreen().removePreference(mWriteSettingsPrefs);