Merge "Cache service component name in RoleControllerManager to avoid deadlock." into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1f14a727d6
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user