Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f14a727 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents b45d24e3 48f36c6a
Loading
Loading
Loading
Loading
+38 −8
Original line number Diff line number Diff line
@@ -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();
    }

    /**
+15 −12
Original line number Diff line number Diff line
@@ -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);
            }
        }