If INTERACT_ACROSS_USERS_FULL is granted, so is INTERACT_ACROSS_USERS
Bug: 77717079
Test: None
Change-Id: I9252603b5d9ec86cac1fd205a44e5d1c6b36ddcb
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index d3526f7..7b44a04 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -19,12 +19,13 @@
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
+import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+
import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
-import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import android.Manifest;
import android.annotation.NonNull;
@@ -33,9 +34,9 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.Package;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
-import android.content.pm.PackageParser.Package;
import android.metrics.LogMaker;
import android.os.Binder;
import android.os.Build;
@@ -69,17 +70,19 @@
import com.android.server.pm.PackageSetting;
import com.android.server.pm.SharedUserSetting;
import com.android.server.pm.UserManagerService;
-import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
+import com.android.server.pm.permission.DefaultPermissionGrantPolicy
+ .DefaultPermissionGrantedCallback;
import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
import com.android.server.pm.permission.PermissionsState.PermissionState;
import libcore.util.EmptyArray;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -103,6 +106,16 @@
/** Empty array to avoid allocations */
private static final int[] EMPTY_INT_ARRAY = new int[0];
+ /** If the permission of the value is granted, so is the key */
+ private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
+
+ static {
+ FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION);
+ FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ }
+
/** Lock to protect internal data access */
private final Object mLock;
@@ -233,9 +246,7 @@
return PackageManager.PERMISSION_GRANTED;
}
}
- // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
- if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
- .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
+ if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
return PackageManager.PERMISSION_GRANTED;
}
}
@@ -274,9 +285,7 @@
return PackageManager.PERMISSION_GRANTED;
}
}
- // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
- if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
- .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
+ if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
return PackageManager.PERMISSION_GRANTED;
}
} else {
@@ -285,8 +294,8 @@
if (perms.contains(permName)) {
return PackageManager.PERMISSION_GRANTED;
}
- if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
- .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
+ if (FULLER_PERMISSION_MAP.containsKey(permName)
+ && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
return PackageManager.PERMISSION_GRANTED;
}
}
@@ -294,6 +303,18 @@
return PackageManager.PERMISSION_DENIED;
}
+ /**
+ * Returns {@code true} if the permission can be implied from another granted permission.
+ * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
+ * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
+ * it access to any implied permissions.
+ */
+ private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
+ String permName, int userId) {
+ return FULLER_PERMISSION_MAP.containsKey(permName)
+ && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
+ }
+
private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
int callingUid) {
if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {