diff options
| -rw-r--r-- | core/java/android/app/role/RoleControllerManager.java | 46 | ||||
| -rw-r--r-- | services/core/java/com/android/server/role/RoleManagerService.java | 27 |
2 files changed, 53 insertions, 20 deletions
diff --git a/core/java/android/app/role/RoleControllerManager.java b/core/java/android/app/role/RoleControllerManager.java index 027e152ee95f..394a0d64b3e4 100644 --- a/core/java/android/app/role/RoleControllerManager.java +++ b/core/java/android/app/role/RoleControllerManager.java @@ -52,7 +52,10 @@ public class RoleControllerManager { private static final String LOG_TAG = RoleControllerManager.class.getSimpleName(); + private static volatile ComponentName sRemoteServiceComponentName; + private static final Object sRemoteServicesLock = new Object(); + /** * Global remote services (per user) used by all {@link RoleControllerManager managers}. */ @@ -62,18 +65,36 @@ public class RoleControllerManager { @NonNull private final RemoteService mRemoteService; - public RoleControllerManager(@NonNull Context context, @NonNull Handler handler) { + /** + * Initialize the remote service component name once so that we can avoid acquiring the + * PackageManagerService lock in constructor. + * + * @see #createWithInitializedRemoteServiceComponentName(Handler, Context) + */ + public static void initializeRemoteServiceComponentName(@NonNull Context context) { + sRemoteServiceComponentName = getRemoteServiceComponentName(context); + } + + /** + * Create a {@link RoleControllerManager} instance with the initialized remote service component + * name so that we can avoid acquiring the PackageManagerService lock in constructor. + * + * @see #initializeRemoteServiceComponentName(Context) + */ + @NonNull + public static RoleControllerManager createWithInitializedRemoteServiceComponentName( + @NonNull Handler handler, @NonNull Context context) { + return new RoleControllerManager(sRemoteServiceComponentName, handler, context); + } + + private RoleControllerManager(@NonNull ComponentName remoteServiceComponentName, + @NonNull Handler handler, @NonNull Context context) { synchronized (sRemoteServicesLock) { int userId = context.getUserId(); RemoteService remoteService = sRemoteServices.get(userId); if (remoteService == null) { - Intent intent = new Intent(RoleControllerService.SERVICE_INTERFACE); - PackageManager packageManager = context.getPackageManager(); - intent.setPackage(packageManager.getPermissionControllerPackageName()); - ResolveInfo resolveInfo = packageManager.resolveService(intent, 0); - remoteService = new RemoteService(context.getApplicationContext(), - resolveInfo.getComponentInfo().getComponentName(), handler, userId); + remoteServiceComponentName, handler, userId); sRemoteServices.put(userId, remoteService); } mRemoteService = remoteService; @@ -81,7 +102,16 @@ public class RoleControllerManager { } public RoleControllerManager(@NonNull Context context) { - this(context, context.getMainThreadHandler()); + this(getRemoteServiceComponentName(context), context.getMainThreadHandler(), context); + } + + @NonNull + private static ComponentName getRemoteServiceComponentName(@NonNull Context context) { + Intent intent = new Intent(RoleControllerService.SERVICE_INTERFACE); + PackageManager packageManager = context.getPackageManager(); + intent.setPackage(packageManager.getPermissionControllerPackageName()); + ResolveInfo resolveInfo = packageManager.resolveService(intent, 0); + return resolveInfo.getComponentInfo().getComponentName(); } /** diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java index b2ac1b884483..654c47780f4a 100644 --- a/services/core/java/com/android/server/role/RoleManagerService.java +++ b/services/core/java/com/android/server/role/RoleManagerService.java @@ -147,6 +147,8 @@ public class RoleManagerService extends SystemService implements RoleUserState.C mLegacyRoleResolver = legacyRoleResolver; + RoleControllerManager.initializeRemoteServiceComponentName(context); + mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); mAppOpsManager = context.getSystemService(AppOpsManager.class); @@ -231,7 +233,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C // Run grants again Slog.i(LOG_TAG, "Granting default permissions..."); CompletableFuture<Void> result = new CompletableFuture<>(); - getOrCreateControllerService(userId).grantDefaultRoles(FgThread.getExecutor(), + getOrCreateController(userId).grantDefaultRoles(FgThread.getExecutor(), successful -> { if (successful) { userState.setPackagesHash(packagesHash); @@ -318,7 +320,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C } @NonNull - private RoleControllerManager getOrCreateControllerService(@UserIdInt int userId) { + private RoleControllerManager getOrCreateController(@UserIdInt int userId) { synchronized (mLock) { RoleControllerManager controller = mControllers.get(userId); if (controller == null) { @@ -330,7 +332,8 @@ public class RoleManagerService extends SystemService implements RoleUserState.C } catch (NameNotFoundException e) { throw new RuntimeException(e); } - controller = new RoleControllerManager(context, FgThread.getHandler()); + controller = RoleControllerManager.createWithInitializedRemoteServiceComponentName( + FgThread.getHandler(), context); mControllers.put(userId, controller); } return controller; @@ -474,7 +477,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); Preconditions.checkNotNull(callback, "callback cannot be null"); - getOrCreateControllerService(userId).onAddRoleHolder(roleName, packageName, flags, + getOrCreateController(userId).onAddRoleHolder(roleName, packageName, flags, callback); } @@ -494,7 +497,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); Preconditions.checkNotNull(callback, "callback cannot be null"); - getOrCreateControllerService(userId).onRemoveRoleHolder(roleName, packageName, flags, + getOrCreateController(userId).onRemoveRoleHolder(roleName, packageName, flags, callback); } @@ -513,7 +516,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); Preconditions.checkNotNull(callback, "callback cannot be null"); - getOrCreateControllerService(userId).onClearRoleHolders(roleName, flags, callback); + getOrCreateController(userId).onClearRoleHolders(roleName, flags, callback); } @Override @@ -738,10 +741,10 @@ public class RoleManagerService extends SystemService implements RoleUserState.C } }); if (packageName != null) { - getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, + getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, packageName, 0, callback); } else { - getOrCreateControllerService(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0, + getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0, callback); } try { @@ -762,10 +765,10 @@ public class RoleManagerService extends SystemService implements RoleUserState.C } }); if (packageName != null) { - getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, + getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, packageName, 0, callback); } else { - getOrCreateControllerService(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0, + getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0, callback); } } @@ -791,10 +794,10 @@ public class RoleManagerService extends SystemService implements RoleUserState.C callback.accept(successful); }); if (packageName != null) { - getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_HOME, + getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_HOME, packageName, 0, remoteCallback); } else { - getOrCreateControllerService(userId).onClearRoleHolders(RoleManager.ROLE_HOME, 0, + getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_HOME, 0, remoteCallback); } } |