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

Commit e3e1d327 authored by Jonathan Scott's avatar Jonathan Scott
Browse files

Allow use of #hasFeatures across users.

Test: btest CtsAccountManagerMultiuserTestCases
Fixes: 263343877
Change-Id: Ic028b3541183feda1f8445e84bf1b0763b3e3bc4
parent 78e45296
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.accounts;

import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;

import android.annotation.BroadcastBehavior;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -891,15 +893,24 @@ public class AccountManager {
     * @return An {@link AccountManagerFuture} which resolves to a Boolean, true if the account
     *         exists and has all of the specified features.
     */
    @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
            requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS_FULL)
    public AccountManagerFuture<Boolean> hasFeatures(final Account account,
            final String[] features,
            AccountManagerCallback<Boolean> callback, Handler handler) {
        return hasFeaturesAsUser(account, features, callback, handler, mContext.getUserId());
    }

    private AccountManagerFuture<Boolean> hasFeaturesAsUser(
            final Account account, final String[] features,
            AccountManagerCallback<Boolean> callback, Handler handler, int userId) {
        if (account == null) throw new IllegalArgumentException("account is null");
        if (features == null) throw new IllegalArgumentException("features is null");
        return new Future2Task<Boolean>(handler, callback) {
            @Override
            public void doWork() throws RemoteException {
                mService.hasFeatures(mResponse, account, features, mContext.getOpPackageName());
                mService.hasFeatures(
                        mResponse, account, features, userId, mContext.getOpPackageName());
            }
            @Override
            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
@@ -3319,7 +3330,7 @@ public class AccountManager {
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
    @RequiresPermission(INTERACT_ACROSS_USERS_FULL)
    public AccountManagerFuture<Bundle> finishSessionAsUser(
            final Bundle sessionBundle,
            final Activity activity,
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ interface IAccountManager {
    Account[] getAccountsByTypeForPackage(String type, String packageName, String opPackageName);
    Account[] getAccountsAsUser(String accountType, int userId, String opPackageName);
    void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features,
        String opPackageName);
        int userId, String opPackageName);
    void getAccountByTypeAndFeatures(in IAccountManagerResponse response, String accountType,
        in String[] features, String opPackageName);
    void getAccountsByFeatures(in IAccountManagerResponse response, String accountType,
+12 −2
Original line number Diff line number Diff line
@@ -2010,7 +2010,7 @@ public class AccountManagerService

    @Override
    public void hasFeatures(IAccountManagerResponse response,
            Account account, String[] features, String opPackageName) {
            Account account, String[] features, int userId, String opPackageName) {
        int callingUid = Binder.getCallingUid();
        mAppOpsManager.checkPackage(callingUid, opPackageName);
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -2018,12 +2018,22 @@ public class AccountManagerService
                    + ", response " + response
                    + ", features " + Arrays.toString(features)
                    + ", caller's uid " + callingUid
                    + ", userId " + userId
                    + ", pid " + Binder.getCallingPid());
        }
        Preconditions.checkArgument(account != null, "account cannot be null");
        Preconditions.checkArgument(response != null, "response cannot be null");
        Preconditions.checkArgument(features != null, "features cannot be null");
        int userId = UserHandle.getCallingUserId();

        if (userId != UserHandle.getCallingUserId()
                && callingUid != Process.SYSTEM_UID
                && mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("User " + UserHandle.getCallingUserId()
                    + " trying to check account features for " + userId);
        }

        checkReadAccountsPermitted(callingUid, account.type, userId,
                opPackageName);

+13 −8
Original line number Diff line number Diff line
@@ -1295,6 +1295,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {
                    null, // response
                    AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
                    new String[] {"feature1", "feature2"}, // features
                    0, // userId
                    "testPackage"); // opPackageName
            fail("IllegalArgumentException expected. But no exception was thrown.");
        } catch (IllegalArgumentException e) {
@@ -1310,6 +1311,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {
                    mMockAccountManagerResponse, // response
                    null, // account
                    new String[] {"feature1", "feature2"}, // features
                    0, // userId
                    "testPackage"); // opPackageName
            fail("IllegalArgumentException expected. But no exception was thrown.");
        } catch (IllegalArgumentException e) {
@@ -1325,6 +1327,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {
                    mMockAccountManagerResponse, // response
                    AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, // account
                    null, // features
                    0, // userId
                    "testPackage"); // opPackageName
            fail("IllegalArgumentException expected. But no exception was thrown.");
        } catch (IllegalArgumentException e) {
@@ -1341,6 +1344,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {
                response, // response
                AccountManagerServiceTestFixtures.ACCOUNT_ERROR, // account
                AccountManagerServiceTestFixtures.ACCOUNT_FEATURES, // features
                0, // userId
                "testPackage"); // opPackageName
        waitForLatch(latch);
        verify(mMockAccountManagerResponse).onError(
@@ -1357,6 +1361,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {
                response, // response
                AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, // account
                AccountManagerServiceTestFixtures.ACCOUNT_FEATURES, // features
                0, // userId
                "testPackage"); // opPackageName
        waitForLatch(latch);
        verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());