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

Commit 8567a784 authored by Aseem Kumar's avatar Aseem Kumar
Browse files

Use `android` as packageName instead of `null` for methods

used by system to fetch accounts.

When `null` is used with getAccountsFromCache method, there is
conversion from calling UID to packageName (call getPackageNameForUid in
filterAccounts), and then another conversion using packageName to UID in
resolveAccountVisbility). Sometimes (as determined by PackageManager), a package which is installed in primary profile but is not installed in work profile is used to fetch accounts for work profile. This causes fetching accounts in work profile to fail.

The fix uses "android" as packageName for all methods used by system
process. This ensures that this conversion always works.

Test: atest AccountManagerServiceTest

Bug: 246257147
Change-Id: Id2e4b860f49366db5a85a3fd83b3fedeeabc9cbb
(cherry picked from commit 33f942c2)
parent 3bd6c98b
Loading
Loading
Loading
Loading
+23 −14
Original line number Original line Diff line number Diff line
@@ -528,7 +528,7 @@ public class AccountManagerService
    private Map<Account, Integer> getAccountsAndVisibilityForPackage(String packageName,
    private Map<Account, Integer> getAccountsAndVisibilityForPackage(String packageName,
            List<String> accountTypes, Integer callingUid, UserAccounts accounts) {
            List<String> accountTypes, Integer callingUid, UserAccounts accounts) {
        if (!packageExistsForUser(packageName, accounts.userId)) {
        if (!packageExistsForUser(packageName, accounts.userId)) {
            Log.d(TAG, "Package not found " + packageName);
            Log.w(TAG, "getAccountsAndVisibilityForPackage#Package not found " + packageName);
            return new LinkedHashMap<>();
            return new LinkedHashMap<>();
        }
        }


@@ -677,7 +677,7 @@ public class AccountManagerService
                restoreCallingIdentity(identityToken);
                restoreCallingIdentity(identityToken);
            }
            }
        } catch (NameNotFoundException e) {
        } catch (NameNotFoundException e) {
            Log.d(TAG, "Package not found " + e.getMessage());
            Log.w(TAG, "resolveAccountVisibility#Package not found " + e.getMessage());
            return AccountManager.VISIBILITY_NOT_VISIBLE;
            return AccountManager.VISIBILITY_NOT_VISIBLE;
        }
        }


@@ -756,7 +756,7 @@ public class AccountManagerService
            }
            }
            return true;
            return true;
        } catch (NameNotFoundException e) {
        } catch (NameNotFoundException e) {
            Log.d(TAG, "Package not found " + e.getMessage());
            Log.w(TAG, "isPreOApplication#Package not found " + e.getMessage());
            return true;
            return true;
        }
        }
    }
    }
@@ -4063,7 +4063,7 @@ public class AccountManagerService
            int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
            int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
            return hasAccountAccess(account, packageName, uid);
            return hasAccountAccess(account, packageName, uid);
        } catch (NameNotFoundException e) {
        } catch (NameNotFoundException e) {
            Log.d(TAG, "Package not found " + e.getMessage());
            Log.w(TAG, "hasAccountAccess#Package not found " + e.getMessage());
            return false;
            return false;
        }
        }
    }
    }
@@ -4195,7 +4195,7 @@ public class AccountManagerService
        }
        }
        final long token = Binder.clearCallingIdentity();
        final long token = Binder.clearCallingIdentity();
        try {
        try {
            AccountAndUser[] allAccounts = getAllAccounts();
            AccountAndUser[] allAccounts = getAllAccountsForSystemProcess();
            for (int i = allAccounts.length - 1; i >= 0; i--) {
            for (int i = allAccounts.length - 1; i >= 0; i--) {
                if (allAccounts[i].account.equals(account)) {
                if (allAccounts[i].account.equals(account)) {
                    return true;
                    return true;
@@ -4345,10 +4345,11 @@ public class AccountManagerService
    /**
    /**
     * Returns accounts for all running users, ignores visibility values.
     * Returns accounts for all running users, ignores visibility values.
     *
     *
     * Should only be called by System process.
     * @hide
     * @hide
     */
     */
    @NonNull
    @NonNull
    public AccountAndUser[] getRunningAccounts() {
    public AccountAndUser[] getRunningAccountsForSystem() {
        final int[] runningUserIds;
        final int[] runningUserIds;
        try {
        try {
            runningUserIds = ActivityManager.getService().getRunningUserIds();
            runningUserIds = ActivityManager.getService().getRunningUserIds();
@@ -4356,26 +4357,34 @@ public class AccountManagerService
            // Running in system_server; should never happen
            // Running in system_server; should never happen
            throw new RuntimeException(e);
            throw new RuntimeException(e);
        }
        }
        return getAccounts(runningUserIds);
        return getAccountsForSystem(runningUserIds);
    }
    }


    /**
    /**
     * Returns accounts for all users, ignores visibility values.
     * Returns accounts for all users, ignores visibility values.
     *
     *
     * Should only be called by system process
     *
     * @hide
     * @hide
     */
     */
    @NonNull
    @NonNull
    public AccountAndUser[] getAllAccounts() {
    public AccountAndUser[] getAllAccountsForSystemProcess() {
        final List<UserInfo> users = getUserManager().getAliveUsers();
        final List<UserInfo> users = getUserManager().getAliveUsers();
        final int[] userIds = new int[users.size()];
        final int[] userIds = new int[users.size()];
        for (int i = 0; i < userIds.length; i++) {
        for (int i = 0; i < userIds.length; i++) {
            userIds[i] = users.get(i).id;
            userIds[i] = users.get(i).id;
        }
        }
        return getAccounts(userIds);
        return getAccountsForSystem(userIds);
    }
    }


    /**
     * Returns all accounts for the given user, ignores all visibility checks.
     * This should only be called by system process.
     *
     * @hide
     */
    @NonNull
    @NonNull
    private AccountAndUser[] getAccounts(int[] userIds) {
    private AccountAndUser[] getAccountsForSystem(int[] userIds) {
        final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList();
        final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList();
        for (int userId : userIds) {
        for (int userId : userIds) {
            UserAccounts userAccounts = getUserAccounts(userId);
            UserAccounts userAccounts = getUserAccounts(userId);
@@ -4384,7 +4393,7 @@ public class AccountManagerService
                    userAccounts,
                    userAccounts,
                    null /* type */,
                    null /* type */,
                    Binder.getCallingUid(),
                    Binder.getCallingUid(),
                    null /* packageName */,
                    "android"/* packageName */,
                    false /* include managed not visible*/);
                    false /* include managed not visible*/);
            for (Account account : accounts) {
            for (Account account : accounts) {
                runningAccounts.add(new AccountAndUser(account, userId));
                runningAccounts.add(new AccountAndUser(account, userId));
@@ -5355,7 +5364,7 @@ public class AccountManagerService
            }
            }
        } else {
        } else {
            Account[] accounts = getAccountsFromCache(userAccounts, null /* type */,
            Account[] accounts = getAccountsFromCache(userAccounts, null /* type */,
                    Process.SYSTEM_UID, null /* packageName */, false);
                    Process.SYSTEM_UID, "android" /* packageName */, false);
            fout.println("Accounts: " + accounts.length);
            fout.println("Accounts: " + accounts.length);
            for (Account account : accounts) {
            for (Account account : accounts) {
                fout.println("  " + account.toString());
                fout.println("  " + account.toString());
@@ -5550,7 +5559,7 @@ public class AccountManagerService
                        return true;
                        return true;
                    }
                    }
                } catch (PackageManager.NameNotFoundException e) {
                } catch (PackageManager.NameNotFoundException e) {
                    Log.d(TAG, "Package not found " + e.getMessage());
                    Log.w(TAG, "isPrivileged#Package not found " + e.getMessage());
                }
                }
            }
            }
        } finally {
        } finally {
@@ -6074,7 +6083,7 @@ public class AccountManagerService
                    }
                    }
                }
                }
            } catch (NameNotFoundException e) {
            } catch (NameNotFoundException e) {
                Log.d(TAG, "Package not found " + e.getMessage());
                Log.w(TAG, "filterSharedAccounts#Package not found " + e.getMessage());
            }
            }
            Map<Account, Integer> filtered = new LinkedHashMap<>();
            Map<Account, Integer> filtered = new LinkedHashMap<>();
            for (Map.Entry<Account, Integer> entry : unfiltered.entrySet()) {
            for (Map.Entry<Account, Integer> entry : unfiltered.entrySet()) {
+6 −3
Original line number Original line Diff line number Diff line
@@ -2215,7 +2215,8 @@ public class SyncManager {
        pw.print("Storage low: "); pw.println(storageLowIntent != null);
        pw.print("Storage low: "); pw.println(storageLowIntent != null);
        pw.print("Clock valid: "); pw.println(mSyncStorageEngine.isClockValid());
        pw.print("Clock valid: "); pw.println(mSyncStorageEngine.isClockValid());


        final AccountAndUser[] accounts = AccountManagerService.getSingleton().getAllAccounts();
        final AccountAndUser[] accounts =
                AccountManagerService.getSingleton().getAllAccountsForSystemProcess();


        pw.print("Accounts: ");
        pw.print("Accounts: ");
        if (accounts != INITIAL_ACCOUNTS_ARRAY) {
        if (accounts != INITIAL_ACCOUNTS_ARRAY) {
@@ -3274,7 +3275,8 @@ public class SyncManager {
        private void updateRunningAccountsH(EndPoint syncTargets) {
        private void updateRunningAccountsH(EndPoint syncTargets) {
            synchronized (mAccountsLock) {
            synchronized (mAccountsLock) {
                AccountAndUser[] oldAccounts = mRunningAccounts;
                AccountAndUser[] oldAccounts = mRunningAccounts;
                mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts();
                mRunningAccounts =
                        AccountManagerService.getSingleton().getRunningAccountsForSystem();
                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                    Slog.v(TAG, "Accounts list: ");
                    Slog.v(TAG, "Accounts list: ");
                    for (AccountAndUser acc : mRunningAccounts) {
                    for (AccountAndUser acc : mRunningAccounts) {
@@ -3316,7 +3318,8 @@ public class SyncManager {
            }
            }


            // Cancel all jobs from non-existent accounts.
            // Cancel all jobs from non-existent accounts.
            AccountAndUser[] allAccounts = AccountManagerService.getSingleton().getAllAccounts();
            AccountAndUser[] allAccounts =
                    AccountManagerService.getSingleton().getAllAccountsForSystemProcess();
            List<SyncOperation> ops = getAllPendingSyncs();
            List<SyncOperation> ops = getAllPendingSyncs();
            for (int i = 0, opsSize = ops.size(); i < opsSize; i++) {
            for (int i = 0, opsSize = ops.size(); i < opsSize; i++) {
                SyncOperation op = ops.get(i);
                SyncOperation op = ops.get(i);