Improved CarUserService.dump():
* Included getPassengers() info
* Fixed permissions so it can be dump without 'adb root'
Test: adb shell dumpsys car_service | grep -3 NumberOfDrivers
Bug: 143815470
Change-Id: If9b3bf130348cd08d6959da222a559eaa9a11f0c
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index 025eda1..778bdb3 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -45,6 +45,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -122,13 +123,35 @@
@Override
public void dump(@NonNull PrintWriter writer) {
+ checkAtLeastOnePermission("dump()", android.Manifest.permission.DUMP);
writer.println("*CarUserService*");
synchronized (mLock) {
writer.println("User0Unlocked: " + mUser0Unlocked);
writer.println("MaxRunningUsers: " + mMaxRunningUsers);
writer.println("BackgroundUsersToRestart: " + mBackgroundUsersToRestart);
writer.println("BackgroundUsersRestarted: " + mBackgroundUsersRestartedHere);
- writer.println("NumberOfDrivers: " + getAllDrivers().size());
+ List<UserInfo> allDrivers = getAllDrivers();
+ int driversSize = allDrivers.size();
+ writer.println("NumberOfDrivers: " + driversSize);
+ String prefix = " ";
+ for (int i = 0; i < driversSize; i++) {
+ int driverId = allDrivers.get(i).id;
+ writer.print(prefix + "#" + i + ": id=" + driverId);
+ List<UserInfo> passengers = getPassengers(driverId);
+ int passengersSize = passengers.size();
+ writer.print(" NumberPassengers: " + passengersSize);
+ if (passengersSize > 0) {
+ writer.print(" [");
+ for (int j = 0; j < passengersSize; j++) {
+ writer.print(passengers.get(j).id);
+ if (j < passengersSize - 1) {
+ writer.print(" ");
+ }
+ }
+ writer.print("]");
+ }
+ writer.println();
+ }
}
}
@@ -211,7 +234,7 @@
@Override
@NonNull
public List<UserInfo> getAllDrivers() {
- checkManageUsersPermission("getAllDrivers");
+ checkManageUsersOrDumpPermission("getAllDrivers");
return getUsers((user) -> {
return !isSystemUser(user.id) && user.isEnabled() && !user.isManagedProfile()
&& !user.isEphemeral();
@@ -224,7 +247,7 @@
@Override
@NonNull
public List<UserInfo> getPassengers(@UserIdInt int driverId) {
- checkManageUsersPermission("getPassengers");
+ checkManageUsersOrDumpPermission("getPassengers");
return getUsers((user) -> {
return !isSystemUser(user.id) && user.isEnabled() && user.isManagedProfile()
&& user.profileGroupId == driverId;
@@ -544,16 +567,31 @@
* @throws SecurityException if the caller is not system or root.
*/
private static void checkManageUsersPermission(String message) {
+ checkAtLeastOnePermission(message, android.Manifest.permission.MANAGE_USERS);
+ }
+
+ private static void checkManageUsersOrDumpPermission(String message) {
+ checkAtLeastOnePermission(message,
+ android.Manifest.permission.MANAGE_USERS,
+ android.Manifest.permission.DUMP);
+ }
+
+ private static void checkAtLeastOnePermission(String message, String...permissions) {
int callingUid = Binder.getCallingUid();
- if (!hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid)) {
- throw new SecurityException(
- "You need MANAGE_USERS permission to: " + message);
+ if (!hasAtLeastOnePermissionGranted(callingUid, permissions)) {
+ throw new SecurityException("You need one of " + Arrays.toString(permissions)
+ + " to: " + message);
}
}
- private static boolean hasPermissionGranted(String permission, int uid) {
- return ActivityManager.checkComponentPermission(
- permission, uid, /* owningUid = */-1, /* exported = */ true)
- == android.content.pm.PackageManager.PERMISSION_GRANTED;
+ private static boolean hasAtLeastOnePermissionGranted(int uid, String... permissions) {
+ for (String permission : permissions) {
+ if (ActivityManager.checkComponentPermission(permission, uid, /* owningUid = */-1,
+ /* exported = */ true)
+ == android.content.pm.PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ }
+ return false;
}
}