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

Commit 7b5bbb55 authored by Dmitry Dementyev's avatar Dmitry Dementyev Committed by Android (Google) Code Review
Browse files

Merge "Implement Account Discovery API."

parents 35089c46 01985ff6
Loading
Loading
Loading
Loading
+36 −7
Original line number Diff line number Diff line
@@ -53,9 +53,12 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.SuppressWarnings;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
@@ -864,11 +867,17 @@ public class AccountManager {
     *
     * @param account The account for which visibility data should be returned.
     *
     * @return Map from uid to visibility for given account
     * @return Map from uid to visibility for given account.
     */
    public Map<Integer, Integer> getUidsAndVisibilityForAccount(Account account) {
        // TODO implement.
        return null;
        try {
            @SuppressWarnings("unchecked")
            Map<Integer, Integer> result = (Map<Integer, Integer>) mService
                    .getUidsAndVisibilityForAccount(account);
            return result;
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
@@ -2110,8 +2119,21 @@ public class AccountManager {
                synchronized (mAccountsUpdatedListeners) {
                    try {
                        if (mAccountsUpdatedListeners.containsKey(listener)) {
                            Set<String> types = mAccountsUpdatedListenersTypes.get(listener);
                            if (types != null) {
                                // filter by account type;
                                ArrayList<Account> filtered = new ArrayList<>();
                                for (Account account : accountsCopy) {
                                    if (types.contains(account.type)) {
                                        filtered.add(account);
                                    }
                                }
                                listener.onAccountsUpdated(
                                        filtered.toArray(new Account[filtered.size()]));
                            } else {
                                listener.onAccountsUpdated(accountsCopy);
                            }
                        }
                    } catch (SQLException e) {
                        // Better luck next time. If the problem was disk-full,
                        // the STORAGE_OK intent will re-trigger the update.
@@ -2759,6 +2781,9 @@ public class AccountManager {
    private final HashMap<OnAccountsUpdateListener, Handler> mAccountsUpdatedListeners =
            Maps.newHashMap();

    private final HashMap<OnAccountsUpdateListener, Set<String> > mAccountsUpdatedListenersTypes =
            Maps.newHashMap();

    /**
     * BroadcastReceiver that listens for the LOGIN_ACCOUNTS_CHANGED_ACTION intent
     * so that it can read the updated list of accounts and send them to the listener
@@ -2784,7 +2809,7 @@ public class AccountManager {
     * accounts of any type related to the caller. This method is equivalent to
     * addOnAccountsUpdatedListener(listener, handler, updateImmediately, null)
     *
     * @see #addOnAccountsUpdatedListener(OnAccountsUpdateListener, Handler, boolean, Handler,
     * @see #addOnAccountsUpdatedListener(OnAccountsUpdateListener, Handler, boolean,
     *      String[])
     */
    public void addOnAccountsUpdatedListener(final OnAccountsUpdateListener listener,
@@ -2828,7 +2853,10 @@ public class AccountManager {
            final boolean wasEmpty = mAccountsUpdatedListeners.isEmpty();

            mAccountsUpdatedListeners.put(listener, handler);

            if (accountTypes != null) {
                mAccountsUpdatedListenersTypes.put(listener,
                        new HashSet<String>(Arrays.asList(accountTypes)));
            }

            if (wasEmpty) {
                // Register a broadcast receiver to monitor account changes
@@ -2870,6 +2898,7 @@ public class AccountManager {
                return;
            }
            mAccountsUpdatedListeners.remove(listener);
            mAccountsUpdatedListenersTypes.remove(listener);
            if (mAccountsUpdatedListeners.isEmpty()) {
                mContext.unregisterReceiver(mAccountsChangedBroadcastReceiver);
            }
+3 −1
Original line number Diff line number Diff line
@@ -52,7 +52,9 @@ public class ChooseAccountActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // TODO This activity is only used by getAuthTokenByFeatures and can not see
        // VISIBILITY_USER_MANAGED_NOT_VISIBLE accounts. It should be moved to account managed
        // service.
        mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS);
        mAccountManagerResponse =
                getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE);
+70 −36
Original line number Diff line number Diff line
@@ -40,7 +40,9 @@ import com.android.internal.R;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
@@ -110,7 +112,7 @@ public class ChooseTypeAndAccountActivity extends Activity
    private static final String KEY_INSTANCE_STATE_EXISTING_ACCOUNTS = "existingAccounts";
    private static final String KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME = "selectedAccountName";
    private static final String KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT = "selectedAddAccount";
    private static final String KEY_INSTANCE_STATE_ACCOUNT_LIST = "accountList";
    private static final String KEY_INSTANCE_STATE_ACCOUNT_LIST = "accountAndVisibilityList";

    private static final int SELECTED_ITEM_NONE = -1;

@@ -120,7 +122,11 @@ public class ChooseTypeAndAccountActivity extends Activity
    private boolean mSelectedAddNewAccount = false;
    private String mDescriptionOverride;

    private ArrayList<Account> mAccounts;
    private Map<Account, Integer> mAccounts;
    // TODO Redesign flow to show NOT_VISIBLE accounts
    // and display a warning if they are selected.
    // Currently NOT_VISBILE accounts are not shown at all.
    private ArrayList<Account> mPossiblyVisibleAccounts;
    private int mPendingRequest = REQUEST_NULL;
    private Parcelable[] mExistingAccounts = null;
    private int mSelectedItemIndex;
@@ -164,12 +170,12 @@ public class ChooseTypeAndAccountActivity extends Activity
                    savedInstanceState.getParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS);

            // Makes sure that any user selection is preserved across orientation changes.
            mSelectedAccountName = savedInstanceState.getString(
                    KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME);

            mSelectedAddNewAccount = savedInstanceState.getBoolean(
                    KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, false);
            mAccounts = savedInstanceState.getParcelableArrayList(KEY_INSTANCE_STATE_ACCOUNT_LIST);
            mSelectedAccountName =
                    savedInstanceState.getString(KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME);
            mSelectedAddNewAccount =
                    savedInstanceState.getBoolean(KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, false);
            mAccounts = (Map<Account, Integer>) savedInstanceState
                    .getSerializable(KEY_INSTANCE_STATE_ACCOUNT_LIST);
        } else {
            mPendingRequest = REQUEST_NULL;
            mExistingAccounts = null;
@@ -220,9 +226,15 @@ public class ChooseTypeAndAccountActivity extends Activity
            }
        }

        String[] listItems = getListOfDisplayableOptions(mAccounts);
        mSelectedItemIndex = getItemIndexToSelect(
            mAccounts, mSelectedAccountName, mSelectedAddNewAccount);
        mPossiblyVisibleAccounts = new ArrayList<>(mAccounts.size());
        for (Map.Entry<Account, Integer> entry : mAccounts.entrySet()) {
            if (AccountManager.VISIBILITY_NOT_VISIBLE != entry.getValue()) {
                mPossiblyVisibleAccounts.add(entry.getKey());
            }
        }
        String[] listItems = getListOfDisplayableOptions(mPossiblyVisibleAccounts);
        mSelectedItemIndex = getItemIndexToSelect(mPossiblyVisibleAccounts, mSelectedAccountName,
                mSelectedAddNewAccount);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.choose_type_and_account);
@@ -250,15 +262,18 @@ public class ChooseTypeAndAccountActivity extends Activity
            outState.putParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS, mExistingAccounts);
        }
        if (mSelectedItemIndex != SELECTED_ITEM_NONE) {
            if (mSelectedItemIndex == mAccounts.size()) {
            if (mSelectedItemIndex == mPossiblyVisibleAccounts.size()) {
                outState.putBoolean(KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, true);
            } else {
                outState.putBoolean(KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, false);
                outState.putString(KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME,
                        mAccounts.get(mSelectedItemIndex).name);
                        mPossiblyVisibleAccounts.get(mSelectedItemIndex).name);
            }
        }
        outState.putParcelableArrayList(KEY_INSTANCE_STATE_ACCOUNT_LIST, mAccounts);
        // should be HashMap by default.
        HashMap<Account, Integer> accountsHashMap = (mAccounts instanceof HashMap)
                ? (HashMap) mAccounts : new HashMap<Account, Integer>(mAccounts);
        outState.putSerializable(KEY_INSTANCE_STATE_ACCOUNT_LIST, accountsHashMap);
    }

    public void onCancelButtonClicked(View view) {
@@ -266,11 +281,11 @@ public class ChooseTypeAndAccountActivity extends Activity
    }

    public void onOkButtonClicked(View view) {
        if (mSelectedItemIndex == mAccounts.size()) {
        if (mSelectedItemIndex == mPossiblyVisibleAccounts.size()) {
            // Selected "Add New Account" option
            startChooseAccountTypeActivity();
        } else if (mSelectedItemIndex != SELECTED_ITEM_NONE) {
            onAccountSelected(mAccounts.get(mSelectedItemIndex));
            onAccountSelected(mPossiblyVisibleAccounts.get(mSelectedItemIndex));
        }
    }

@@ -321,6 +336,7 @@ public class ChooseTypeAndAccountActivity extends Activity
                }

                if (accountName == null || accountType == null) {
                    // new account was added.
                    Account[] currentAccounts = AccountManager.get(this).getAccountsForPackage(
                            mCallingPackage, mCallingUid);
                    Set<Account> preExistingAccounts = new HashSet<Account>();
@@ -328,6 +344,7 @@ public class ChooseTypeAndAccountActivity extends Activity
                        preExistingAccounts.add((Account) accountParcel);
                    }
                    for (Account account : currentAccounts) {
                        // New account is visible to the app - return it.
                        if (!preExistingAccounts.contains(account)) {
                            accountName = account.name;
                            accountType = account.type;
@@ -409,13 +426,27 @@ public class ChooseTypeAndAccountActivity extends Activity
    }

    private void setResultAndFinish(final String accountName, final String accountType) {
        // Mark account as visible since user chose it.
        Account account = new Account(accountName, accountType);
        Integer oldVisibility = mAccounts.get(account);
        // oldVisibility is null if new account was added
        if (oldVisibility == null) {
            Map<Account, Integer> accountsAndVisibility = AccountManager.get(this)
                    .getAccountsAndVisibilityForPackage(mCallingPackage, null /* type */);
            oldVisibility = accountsAndVisibility.get(account);
        }
        if (oldVisibility != null
                && oldVisibility == AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE) {
            AccountManager.get(this).setAccountVisibility(account, mCallingUid,
                    AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
        }
        Bundle bundle = new Bundle();
        bundle.putString(AccountManager.KEY_ACCOUNT_NAME, accountName);
        bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
        setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "ChooseTypeAndAccountActivity.setResultAndFinish: "
                    + "selected account " + accountName + ", " + accountType);
            Log.v(TAG, "ChooseTypeAndAccountActivity.setResultAndFinish: selected account "
                    + accountName + ", " + accountType);
        }
        finish();
    }
@@ -474,23 +505,26 @@ public class ChooseTypeAndAccountActivity extends Activity
    }

    /**
     * Create a list of Account objects for each account that is acceptable. Filter out
     * accounts that don't match the allowable types, if provided, or that don't match the
     * allowable accounts, if provided.
     * Create a list of Account objects for each account that is acceptable. Filter out accounts
     * that don't match the allowable types, if provided, or that don't match the allowable
     * accounts, if provided.
     */
    private ArrayList<Account> getAcceptableAccountChoices(AccountManager accountManager) {
      final Account[] accounts = accountManager.getAccountsForPackage(mCallingPackage,
              mCallingUid);
      ArrayList<Account> accountsToPopulate = new ArrayList<Account>(accounts.length);
      for (Account account : accounts) {
          if (mSetOfAllowableAccounts != null && !mSetOfAllowableAccounts.contains(account)) {
    private Map<Account, Integer> getAcceptableAccountChoices(AccountManager accountManager) {
        Map<Account, Integer> accountsAndVisibility =
                accountManager.getAccountsAndVisibilityForPackage(mCallingPackage, null /* type */);

        Map<Account, Integer> accountsToPopulate =
                new HashMap<Account, Integer>(accountsAndVisibility.size());
        for (Map.Entry<Account, Integer> entry : accountsAndVisibility.entrySet()) {
            if (mSetOfAllowableAccounts != null
                    && !mSetOfAllowableAccounts.contains(entry.getKey())) {
                continue;
            }
            if (mSetOfRelevantAccountTypes != null
                  && !mSetOfRelevantAccountTypes.contains(account.type)) {
                    && !mSetOfRelevantAccountTypes.contains(entry.getKey().type)) {
                continue;
            }
          accountsToPopulate.add(account);
            accountsToPopulate.put(entry.getKey(), entry.getValue());
        }
        return accountsToPopulate;
    }
+3 −3
Original line number Diff line number Diff line
@@ -108,8 +108,8 @@ interface IAccountManager {
    void isCredentialsUpdateSuggested(in IAccountManagerResponse response, in Account account,
        String statusToken);

    /* Allows Authenticator to get UIDs of packages which registered to receive updates about given account type.*/
    int[] getRequestingUidsForType(String accountType);
    /* Returns Map<Integer, Integer> from UID to visibility with all values stored for given account*/
    Map getUidsAndVisibilityForAccount(in Account account);

    boolean addAccountExplicitlyWithVisibility(in Account account, String password, in Bundle extras,
            in Map visibility);
+638 −234

File changed.

Preview size limit exceeded, changes collapsed.

Loading