Fix granting default roles timeout.
The RoleControllerManager takes a Handler for service connection callbacks, and that Handler has to be a thread other than the main thread inside system server because we need to block the main thread before necessary permissions are granted via role. However, since a recent change that exposed RoleControllerManager APIs on RoleManager instead to hide this implementation detail from API, we are creating the RoleControllerManager instance upon RoleManager creation and implicitly initializing it with the main thread Handler. This may result in the RoleControllerManager getting the main thread handler instead of the desired foreground thread handler if someone else in the system server created RoleManager first, and that would create a deadlock when we block the main thread. So revert to the original timing for RoleControllerManager creation by creating it lazily, so that it gets the correct handler as the only user of it inside system server is RoleManagerService, and other services who only need the RoleManager won't affect RoleControllerManager. Fixes: 177251364 Test: manual Change-Id: I649a23fa3b88fbd9120b3de408eee8a590d50a17
This commit is contained in:
@@ -174,8 +174,10 @@ public final class RoleManager {
|
||||
@NonNull
|
||||
private final Object mListenersLock = new Object();
|
||||
|
||||
@NonNull
|
||||
private final RoleControllerManager mRoleControllerManager;
|
||||
@GuardedBy("mRoleControllerManagerLock")
|
||||
@Nullable
|
||||
private RoleControllerManager mRoleControllerManager;
|
||||
private final Object mRoleControllerManagerLock = new Object();
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@@ -184,7 +186,6 @@ public final class RoleManager {
|
||||
mContext = context;
|
||||
mService = IRoleManager.Stub.asInterface(ServiceManager.getServiceOrThrow(
|
||||
Context.ROLE_SERVICE));
|
||||
mRoleControllerManager = new RoleControllerManager(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -693,7 +694,7 @@ public final class RoleManager {
|
||||
@TestApi
|
||||
public void isRoleVisible(@NonNull String roleName,
|
||||
@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
|
||||
mRoleControllerManager.isRoleVisible(roleName, executor, callback);
|
||||
getRoleControllerManager().isRoleVisible(roleName, executor, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -714,10 +715,20 @@ public final class RoleManager {
|
||||
@TestApi
|
||||
public void isApplicationVisibleForRole(@NonNull String roleName, @NonNull String packageName,
|
||||
@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
|
||||
mRoleControllerManager.isApplicationVisibleForRole(roleName, packageName, executor,
|
||||
getRoleControllerManager().isApplicationVisibleForRole(roleName, packageName, executor,
|
||||
callback);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private RoleControllerManager getRoleControllerManager() {
|
||||
synchronized (mRoleControllerManagerLock) {
|
||||
if (mRoleControllerManager == null) {
|
||||
mRoleControllerManager = new RoleControllerManager(mContext);
|
||||
}
|
||||
return mRoleControllerManager;
|
||||
}
|
||||
}
|
||||
|
||||
private static class OnRoleHoldersChangedListenerDelegate
|
||||
extends IOnRoleHoldersChangedListener.Stub {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user