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

Commit a01c0bfe authored by Hai Zhang's avatar Hai Zhang Committed by android-build-merger
Browse files

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

am: 1f14a727

Change-Id: Ie4fff39cf2a706f0baa760a9ddfe6fac64ca706c
parents f20e67cc 1f14a727
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);
            }
        }