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

Commit d82e68a6 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Cache results of getProfileParent calls

This reduces number of Binder calls that Bluetooth stack is making.

Currently some apps would call AdapterService getRemoteClass,
getRemoteName, and getRemoteAlias for each scan result. Each of those
calls would trigger the call to getProfileParent as part of permission
check. After this patch, the result is cached for two seconds.

Test: observe result of "adb shell dumpsys binder_calls_stats" during
      scan from settings
Bug: 125739276

Change-Id: Ib34525eb38688243fae88dadeb3c6cb89f676356
parent 01cb772c
Loading
Loading
Loading
Loading
+28 −3
Original line number Original line Diff line number Diff line
@@ -264,6 +264,21 @@ public final class Utils {
                || (Process.SYSTEM_UID == callingUid);
                || (Process.SYSTEM_UID == callingUid);
    }
    }


   static Context mParentUserCacheContext = null;
   // Cache location off for 10 users, cache is valid for 2 seconds.
   static LoadingCache<Integer, Integer> mParentUserCache = CacheBuilder.newBuilder()
       .maximumSize(10)
       .expireAfterWrite(2, TimeUnit.SECONDS)
       .build(
           new CacheLoader<Integer, Integer>() {
             public Integer load(Integer callingUser) {
                UserManager um = (UserManager) mParentUserCacheContext.getSystemService(Context.USER_SERVICE);
                UserInfo ui = um.getProfileParent(callingUser);
                int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
                return parentUser;
             }
           });

    public static boolean checkCallerAllowManagedProfiles(Context mContext) {
    public static boolean checkCallerAllowManagedProfiles(Context mContext) {
        if (mContext == null) {
        if (mContext == null) {
            return checkCaller();
            return checkCaller();
@@ -274,9 +289,19 @@ public final class Utils {
        // Use the Bluetooth process identity when making call to get parent user
        // Use the Bluetooth process identity when making call to get parent user
        long ident = Binder.clearCallingIdentity();
        long ident = Binder.clearCallingIdentity();
        try {
        try {

            if (mParentUserCacheContext == null)
                mParentUserCacheContext = mContext;

            int parentUser = 0;

            try {
                parentUser = mParentUserCache.get(callingUid);
            } catch (java.util.concurrent.ExecutionException e) {
                UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
                UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
                UserInfo ui = um.getProfileParent(callingUser);
                UserInfo ui = um.getProfileParent(callingUser);
            int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
                parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
            }


            // Always allow SystemUI/System access.
            // Always allow SystemUI/System access.
            return (sForegroundUserId == callingUser) || (sForegroundUserId == parentUser)
            return (sForegroundUserId == callingUser) || (sForegroundUserId == parentUser)