Merge "Cache service component name in RoleControllerManager to avoid deadlock." into qt-dev

am: 1f14a727d6

Change-Id: Ie4fff39cf2a706f0baa760a9ddfe6fac64ca706c
This commit is contained in:
Hai Zhang
2019-04-16 23:04:37 -07:00
committed by android-build-merger
2 changed files with 53 additions and 20 deletions

View File

@@ -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();
}
/**

View File

@@ -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);
}
}