Check for fixed permissions when restoring notification permissions
Ensure that REVIEW_REQUIRED is not set on system or policy fixed
permissions, or on GRANTED_BY_DEFAULT and GRANTED_BY_ROLE permissions.
Also removes Droidfooder-only state
Fixes: 218593876
Test: PermissionHelperTest
Change-Id: Ia830aa0fe4e60292d5808f29f126392e52883596
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index 86ac7c1..d80d9f3 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -178,6 +178,12 @@
boolean userSet, boolean reviewRequired) {
assertFlag();
final long callingId = Binder.clearCallingIdentity();
+ // Do not change fixed permissions, and do not change non-user set permissions that are
+ // granted by default, or granted by role.
+ if (isPermissionFixed(packageName, userId)
+ || (isPermissionGrantedByDefaultOrRole(packageName, userId) && !userSet)) {
+ return;
+ }
try {
if (grant && !reviewRequired) {
mPermManager.grantRuntimePermission(packageName, NOTIFICATION_PERMISSION, userId);
@@ -252,6 +258,24 @@
}
}
+ boolean isPermissionGrantedByDefaultOrRole(String packageName, @UserIdInt int userId) {
+ assertFlag();
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ try {
+ int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION,
+ userId);
+ return (flags & (PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT
+ | PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE)) != 0;
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Could not reach system server", e);
+ }
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
private void assertFlag() {
if (!mMigrationEnabled) {
throw new IllegalStateException("Method called without checking flag value");
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index e9074c4..8c3466e 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -3170,44 +3170,12 @@
inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms, newPerm, ps,
pkg);
}
- } else if (NOTIFICATION_PERMISSIONS.contains(newPerm)) {
- //&& (origPs.getPermissionState(newPerm) == null) {
- // TODO(b/205888750): add back line about origPs once all TODO sections below are
- // propagated through droidfood
- Permission bp = mRegistry.getPermission(newPerm);
- if (bp == null) {
- throw new IllegalStateException("Unknown new permission " + newPerm);
- }
- if (!isUserSetOrPregrantedOrFixed(ps.getPermissionFlags(newPerm))) {
- updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
- int setFlag = ps.isPermissionGranted(newPerm)
- ? 0 : FLAG_PERMISSION_REVIEW_REQUIRED;
- ps.updatePermissionFlags(bp, FLAG_PERMISSION_REVIEW_REQUIRED, setFlag);
- // TODO(b/205888750): remove if/else block once propagated through droidfood
- if (ps.isPermissionGranted(newPerm)
- && pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
- ps.revokePermission(bp);
- } else if (!ps.isPermissionGranted(newPerm)
- && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
- ps.grantPermission(bp);
- }
- } else {
- // TODO(b/205888750): remove once propagated through droidfood
- ps.updatePermissionFlags(bp, FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
- | FLAG_PERMISSION_REVIEW_REQUIRED, 0);
- }
}
}
return updatedUserIds;
}
- private boolean isUserSetOrPregrantedOrFixed(int flags) {
- return (flags & (FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED
- | FLAG_PERMISSION_POLICY_FIXED | FLAG_PERMISSION_SYSTEM_FIXED
- | FLAG_PERMISSION_GRANTED_BY_DEFAULT | FLAG_PERMISSION_GRANTED_BY_ROLE)) != 0;
- }
-
@NonNull
@Override
public List<SplitPermissionInfoParcelable> getSplitPermissions() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index a3440b4..b71323b4 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -15,6 +15,7 @@
*/
package com.android.server.notification;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
@@ -252,6 +253,39 @@
}
@Test
+ public void testSetNotificationPermission_pkgPerm_notUserSet_grantedByDefaultPermNotSet()
+ throws Exception {
+ when(mPermManager.getPermissionFlags(anyString(),
+ eq(Manifest.permission.POST_NOTIFICATIONS),
+ anyInt())).thenReturn(FLAG_PERMISSION_GRANTED_BY_DEFAULT);
+ PermissionHelper.PackagePermission pkgPerm = new PermissionHelper.PackagePermission(
+ "pkg", 10, true, false);
+
+ mPermissionHelper.setNotificationPermission(pkgPerm);
+ verify(mPermManager, never()).revokeRuntimePermission(
+ anyString(), anyString(), anyInt(), anyString());
+ verify(mPermManager, never()).updatePermissionFlags(
+ anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
+ }
+
+ @Test
+ public void testSetNotificationPermission_pkgPerm_userSet_grantedByDefaultPermSet()
+ throws Exception {
+ when(mPermManager.getPermissionFlags(anyString(),
+ eq(Manifest.permission.POST_NOTIFICATIONS),
+ anyInt())).thenReturn(FLAG_PERMISSION_GRANTED_BY_DEFAULT);
+ PermissionHelper.PackagePermission pkgPerm = new PermissionHelper.PackagePermission(
+ "pkg", 10, true, true);
+
+ mPermissionHelper.setNotificationPermission(pkgPerm);
+ verify(mPermManager).grantRuntimePermission(
+ "pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
+ verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
+ FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_REVIEW_REQUIRED,
+ FLAG_PERMISSION_USER_SET, true, 10);
+ }
+
+ @Test
public void testSetNotificationPermission_revokeUserSet() throws Exception {
mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
@@ -283,6 +317,32 @@
}
@Test
+ public void testSetNotificationPermission_SystemFixedPermNotSet() throws Exception {
+ when(mPermManager.getPermissionFlags(anyString(),
+ eq(Manifest.permission.POST_NOTIFICATIONS),
+ anyInt())).thenReturn(FLAG_PERMISSION_SYSTEM_FIXED);
+
+ mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
+ verify(mPermManager, never()).revokeRuntimePermission(
+ anyString(), anyString(), anyInt(), anyString());
+ verify(mPermManager, never()).updatePermissionFlags(
+ anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
+ }
+
+ @Test
+ public void testSetNotificationPermission_PolicyFixedPermNotSet() throws Exception {
+ when(mPermManager.getPermissionFlags(anyString(),
+ eq(Manifest.permission.POST_NOTIFICATIONS),
+ anyInt())).thenReturn(FLAG_PERMISSION_POLICY_FIXED);
+
+ mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
+ verify(mPermManager, never()).revokeRuntimePermission(
+ anyString(), anyString(), anyInt(), anyString());
+ verify(mPermManager, never()).updatePermissionFlags(
+ anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
+ }
+
+ @Test
public void testIsPermissionFixed() throws Exception {
when(mPermManager.getPermissionFlags(anyString(),
eq(Manifest.permission.POST_NOTIFICATIONS),