1603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/*
2603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Copyright (C) 2009 The Android Open Source Project
3603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana *
4603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Licensed under the Apache License, Version 2.0 (the "License");
5603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * you may not use this file except in compliance with the License.
6603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * You may obtain a copy of the License at
7603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana *
8603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana *      http://www.apache.org/licenses/LICENSE-2.0
9603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana *
10603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Unless required by applicable law or agreed to in writing, software
11603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * distributed under the License is distributed on an "AS IS" BASIS,
12603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * See the License for the specific language governing permissions and
14603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * limitations under the License.
15603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */
16603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
17603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanapackage android.accounts;
18603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
19390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwanimport static android.Manifest.permission.GET_ACCOUNTS;
20390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan
2102cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolovimport android.annotation.NonNull;
2280b530afdb3c19bb664e0ff8c2b650de917305d2Tor Norbyeimport android.annotation.RequiresPermission;
2380b530afdb3c19bb664e0ff8c2b650de917305d2Tor Norbyeimport android.annotation.Size;
24a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwanimport android.annotation.SystemApi;
25603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.app.Activity;
268778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport android.content.BroadcastReceiver;
2712b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasaniimport android.content.ComponentName;
28603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.content.Context;
298778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport android.content.Intent;
30d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintanaimport android.content.IntentFilter;
3112b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasaniimport android.content.res.Resources;
32b6437245c280596d0a580b8d67189739cf793250Costin Manolacheimport android.database.SQLException;
338778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport android.os.Build;
34a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Bundle;
35a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Handler;
36a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Looper;
373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintanaimport android.os.Parcelable;
382c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasaniimport android.os.Process;
398778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport android.os.RemoteException;
402c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasaniimport android.os.UserHandle;
41f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintanaimport android.text.TextUtils;
428778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport android.util.Log;
438778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli
448778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport com.android.internal.R;
458778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport com.google.android.collect.Maps;
46603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
47a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.IOException;
481121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.ArrayList;
498778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport java.util.HashMap;
50a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdiviaimport java.util.List;
518778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport java.util.Map;
52a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.concurrent.Callable;
53a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.concurrent.CancellationException;
54a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.concurrent.ExecutionException;
55a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.concurrent.FutureTask;
56a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.concurrent.TimeUnit;
578778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohliimport java.util.concurrent.TimeoutException;
58603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
59603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/**
60661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * This class provides access to a centralized registry of the user's
618e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * online accounts.  The user enters credentials (username and password) once
628e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * per account, granting applications access to online resources with
638e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * "one-click" approval.
64603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana *
65661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <p>Different online services have different ways of handling accounts and
66661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * authentication, so the account manager uses pluggable <em>authenticator</em>
678e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * modules for different <em>account types</em>.  Authenticators (which may be
688e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * written by third parties) handle the actual details of validating account
698e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * credentials and storing account information.  For example, Google, Facebook,
708e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * and Microsoft Exchange each have their own authenticator.
71661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
72661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <p>Many servers support some notion of an <em>authentication token</em>,
73661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * which can be used to authenticate a request to the server without sending
74661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * the user's actual password.  (Auth tokens are normally created with a
75661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * separate request which does include the user's credentials.)  AccountManager
768e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * can generate auth tokens for applications, so the application doesn't need to
778e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * handle passwords directly.  Auth tokens are normally reusable and cached by
788e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * AccountManager, but must be refreshed periodically.  It's the responsibility
798e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * of applications to <em>invalidate</em> auth tokens when they stop working so
808e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * the AccountManager knows it needs to regenerate them.
81661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
82661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <p>Applications accessing a server normally go through these steps:
83661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
84661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <ul>
85661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <li>Get an instance of AccountManager using {@link #get(Context)}.
86661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
87661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <li>List the available accounts using {@link #getAccountsByType} or
88661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * {@link #getAccountsByTypeAndFeatures}.  Normally applications will only
89661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * be interested in accounts with one particular <em>type</em>, which
90661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * identifies the authenticator.  Account <em>features</em> are used to
91661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * identify particular account subtypes and capabilities.  Both the account
92661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * type and features are authenticator-specific strings, and must be known by
93661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * the application in coordination with its preferred authenticators.
94661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
95661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <li>Select one or more of the available accounts, possibly by asking the
96661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * user for their preference.  If no suitable accounts are available,
97661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * {@link #addAccount} may be called to prompt the user to create an
98661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * account of the appropriate type.
99661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
1008e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * <li><b>Important:</b> If the application is using a previously remembered
1018e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * account selection, it must make sure the account is still in the list
1028e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * of accounts returned by {@link #getAccountsByType}.  Requesting an auth token
1038e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * for an account no longer on the device results in an undefined failure.
1048e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor *
105661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <li>Request an auth token for the selected account(s) using one of the
106661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * {@link #getAuthToken} methods or related helpers.  Refer to the description
107661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * of each method for exact usage and error handling details.
108661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
109661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <li>Make the request using the auth token.  The form of the auth token,
110661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * the format of the request, and the protocol used are all specific to the
1118e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * service you are accessing.  The application may use whatever network and
1128e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * protocol libraries are useful.
113661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
114661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <li><b>Important:</b> If the request fails with an authentication error,
115661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * it could be that a cached auth token is stale and no longer honored by
116661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * the server.  The application must call {@link #invalidateAuthToken} to remove
117661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * the token from the cache, otherwise requests will continue failing!  After
118661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * invalidating the auth token, immediately go back to the "Request an auth
119661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * token" step above.  If the process fails the second time, then it can be
120661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * treated as a "genuine" authentication failure and the user notified or other
121661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * appropriate actions taken.
122661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * </ul>
123661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
1248e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * <p>Some AccountManager methods may need to interact with the user to
125661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * prompt for credentials, present options, or ask the user to add an account.
126661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * The caller may choose whether to allow AccountManager to directly launch the
127661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * necessary user interface and wait for the user, or to return an Intent which
128661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * the caller may use to launch the interface, or (in some cases) to install a
129661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * notification which the user can select at any time to launch the interface.
130661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * To have AccountManager launch the interface directly, the caller must supply
131661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * the current foreground {@link Activity} context.
132661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
133661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <p>Many AccountManager methods take {@link AccountManagerCallback} and
1348e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * {@link Handler} as parameters.  These methods return immediately and
135661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * run asynchronously. If a callback is provided then
136661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * {@link AccountManagerCallback#run} will be invoked on the Handler's
137661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * thread when the request completes, successfully or not.
1388e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * The result is retrieved by calling {@link AccountManagerFuture#getResult()}
1398e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * on the {@link AccountManagerFuture} returned by the method (and also passed
1408e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * to the callback).  This method waits for the operation to complete (if
1418e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * necessary) and either returns the result or throws an exception if an error
1428e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * occurred during the operation.  To make the request synchronously, call
143661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * {@link AccountManagerFuture#getResult()} immediately on receiving the
1448e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor * future from the method; no callback need be supplied.
145661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor *
146661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * <p>Requests which may block, including
147661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * {@link AccountManagerFuture#getResult()}, must never be called on
148661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * the application's main event thread.  These operations throw
149661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor * {@link IllegalStateException} if they are used on the main thread.
150603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */
151603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanapublic class AccountManager {
152603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    private static final String TAG = "AccountManager";
153603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
154f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final int ERROR_CODE_REMOTE_EXCEPTION = 1;
155f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final int ERROR_CODE_NETWORK_ERROR = 3;
156f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final int ERROR_CODE_CANCELED = 4;
157f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final int ERROR_CODE_INVALID_RESPONSE = 5;
158f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final int ERROR_CODE_UNSUPPORTED_OPERATION = 6;
159f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final int ERROR_CODE_BAD_ARGUMENTS = 7;
160f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final int ERROR_CODE_BAD_REQUEST = 8;
1613df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia    public static final int ERROR_CODE_BAD_AUTHENTICATION = 9;
162756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana
163df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani    /** @hide */
164df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani    public static final int ERROR_CODE_USER_RESTRICTED = 100;
165999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina    /** @hide */
166999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina    public static final int ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE = 101;
167df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani
168661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    /**
1698e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * Bundle key used for the {@link String} account name in results
170661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * from methods which return information about a particular account.
171661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     */
172f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String KEY_ACCOUNT_NAME = "authAccount";
173661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor
174661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    /**
1758e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * Bundle key used for the {@link String} account type in results
176661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * from methods which return information about a particular account.
177661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     */
178f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String KEY_ACCOUNT_TYPE = "accountType";
179661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor
180661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    /**
1818e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * Bundle key used for the auth token value in results
182661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * from {@link #getAuthToken} and friends.
183661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     */
184661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    public static final String KEY_AUTHTOKEN = "authtoken";
185661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor
186661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    /**
1878e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * Bundle key used for an {@link Intent} in results from methods that
188661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * may require the caller to interact with the user.  The Intent can
189661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * be used to start the corresponding user interface activity.
190661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     */
191f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String KEY_INTENT = "intent";
192661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor
193661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    /**
1948e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * Bundle key used to supply the password directly in options to
195661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link #confirmCredentials}, rather than prompting the user with
196661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * the standard password prompt.
197661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     */
198661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    public static final String KEY_PASSWORD = "password";
199661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor
200661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    public static final String KEY_ACCOUNTS = "accounts";
20146703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom
202f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String KEY_ACCOUNT_AUTHENTICATOR_RESPONSE = "accountAuthenticatorResponse";
203f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String KEY_ACCOUNT_MANAGER_RESPONSE = "accountManagerResponse";
204661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    public static final String KEY_AUTHENTICATOR_TYPES = "authenticator_types";
205f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String KEY_AUTH_FAILED_MESSAGE = "authFailedMessage";
206f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String KEY_AUTH_TOKEN_LABEL = "authTokenLabelKey";
207661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    public static final String KEY_BOOLEAN_RESULT = "booleanResult";
208661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    public static final String KEY_ERROR_CODE = "errorCode";
209661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    public static final String KEY_ERROR_MESSAGE = "errorMessage";
210661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    public static final String KEY_USERDATA = "userdata";
211b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache
212a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache    /**
2136c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * Bundle key used to supply the last time the credentials of the account
2146c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * were authenticated successfully. Time is specified in milliseconds since
2150b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * epoch. Associated time is updated on successful authentication of account
2160b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * on adding account, confirming credentials, or updating credentials.
2176c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     */
2181663b44cfd5fe589183dae5db769c843870cb5dbSimranjit Singh Kohli    public static final String KEY_LAST_AUTHENTICATED_TIME = "lastAuthenticatedTime";
2196c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli
2206c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli    /**
221a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache     * Authenticators using 'customTokens' option will also get the UID of the
222a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache     * caller
223a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache     */
224a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache    public static final String KEY_CALLER_UID = "callerUid";
225a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache    public static final String KEY_CALLER_PID = "callerPid";
226661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor
227d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache    /**
228ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * The Android package of the caller will be set in the options bundle by the
229ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * {@link AccountManager} and will be passed to the AccountManagerService and
230ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * to the AccountAuthenticators. The uid of the caller will be known by the
231ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * AccountManagerService as well as the AccountAuthenticators so they will be able to
232ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * verify that the package is consistent with the uid (a uid might be shared by many
233ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * packages).
234ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     */
235ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana    public static final String KEY_ANDROID_PACKAGE_NAME = "androidPackageName";
236ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana
237ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana    /**
238d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache     * Boolean, if set and 'customTokens' the authenticator is responsible for
239d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache     * notifications.
240d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache     * @hide
241d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache     */
242d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache    public static final String KEY_NOTIFY_ON_FAILURE = "notifyOnAuthFailure";
243d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache
2447881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan    /**
2457881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * Bundle key used for a {@link Bundle} in result from
2467881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * {@link #startAddAccountSession} and friends which returns session data
2477881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * for installing an account later.
248a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan     * @hide
2497881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     */
250a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan    @SystemApi
2517881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan    public static final String KEY_ACCOUNT_SESSION_BUNDLE = "accountSessionBundle";
2527881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan
2537881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan    /**
2547881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * Bundle key used for the {@link String} account status token in result
2557881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * from {@link #startAddAccountSession} and friends which returns
2567881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * information about a particular account.
257a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan     * @hide
2587881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     */
259a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan    @SystemApi
2607881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan    public static final String KEY_ACCOUNT_STATUS_TOKEN = "accountStatusToken";
2617881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan
262f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String ACTION_AUTHENTICATOR_INTENT =
263f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana            "android.accounts.AccountAuthenticator";
264f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String AUTHENTICATOR_META_DATA_NAME =
265661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor            "android.accounts.AccountAuthenticator";
266f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator";
267f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana
268603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    private final Context mContext;
269603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    private final IAccountManager mService;
270d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana    private final Handler mMainHandler;
271661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor
272f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    /**
273f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana     * Action sent as a broadcast Intent by the AccountsService
274661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * when accounts are added, accounts are removed, or an
275661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * account's credentials (saved password, etc) are changed.
276661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
277661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @see #addOnAccountsUpdatedListener
278f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana     */
279f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public static final String LOGIN_ACCOUNTS_CHANGED_ACTION =
280f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana        "android.accounts.LOGIN_ACCOUNTS_CHANGED";
281603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
2823326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana    /**
2833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana     * @hide
2843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana     */
285603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    public AccountManager(Context context, IAccountManager service) {
286603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        mContext = context;
287603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        mService = service;
288d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        mMainHandler = new Handler(mContext.getMainLooper());
289603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
290603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
2910eabf0228a17e07ef831bc1ee1951c9697d2a079Fred Quintana    /**
2920eabf0228a17e07ef831bc1ee1951c9697d2a079Fred Quintana     * @hide used for testing only
2930eabf0228a17e07ef831bc1ee1951c9697d2a079Fred Quintana     */
2940eabf0228a17e07ef831bc1ee1951c9697d2a079Fred Quintana    public AccountManager(Context context, IAccountManager service, Handler handler) {
2950eabf0228a17e07ef831bc1ee1951c9697d2a079Fred Quintana        mContext = context;
2960eabf0228a17e07ef831bc1ee1951c9697d2a079Fred Quintana        mService = service;
2970eabf0228a17e07ef831bc1ee1951c9697d2a079Fred Quintana        mMainHandler = handler;
2980eabf0228a17e07ef831bc1ee1951c9697d2a079Fred Quintana    }
2990eabf0228a17e07ef831bc1ee1951c9697d2a079Fred Quintana
300756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
301f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana     * @hide for internal use only
302f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana     */
303f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana    public static Bundle sanitizeResult(Bundle result) {
304382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (result != null) {
305382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana            if (result.containsKey(KEY_AUTHTOKEN)
306382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana                    && !TextUtils.isEmpty(result.getString(KEY_AUTHTOKEN))) {
307382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana                final Bundle newResult = new Bundle(result);
308382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana                newResult.putString(KEY_AUTHTOKEN, "<omitted for logging purposes>");
309382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana                return newResult;
310382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana            }
311f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana        }
312f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana        return result;
313f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana    }
314f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana
315f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana    /**
316661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Gets an AccountManager instance associated with a Context.
317661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * The {@link Context} will be used as long as the AccountManager is
318661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * active, so make sure to use a {@link Context} whose lifetime is
319661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * commensurate with any listeners registered to
320661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link #addOnAccountsUpdatedListener} or similar methods.
321661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
322661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
323661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
324661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>No permission is required to call this method.
325661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
326756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * @param context The {@link Context} to use when necessary
327661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManager} instance
328756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
329a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    public static AccountManager get(Context context) {
330382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (context == null) throw new IllegalArgumentException("context is null");
331a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        return (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
332a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
333a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
334756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
335661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Gets the saved password associated with the account.
336661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * This is intended for authenticators and related code; applications
337661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * should get an auth token instead.
338661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
339661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
340661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
3416eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
3426eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that owns the specified account.
343661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
344210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
345210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * AUTHENTICATE_ACCOUNTS permission is needed for those platforms. See docs for
346210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
347210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
3486eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * @param account The account to query for a password. Must not be {@code null}.
349661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return The account's password, null if none or if the account doesn't exist
350756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
351ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public String getPassword(final Account account) {
352382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
353603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
354603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana            return mService.getPassword(account);
355603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
356f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
357603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
358603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
359603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
360756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
361661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Gets the user data named by "key" associated with the account.
362661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * This is intended for authenticators and related code to store
363661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * arbitrary metadata along with accounts.  The meaning of the keys
364661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * and values is up to the authenticator for the account.
365661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
366661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
367661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
3686eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
3696eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that owns the specified account.
370661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
371210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
372210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * AUTHENTICATE_ACCOUNTS permission is needed for those platforms. See docs
373210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * for this function in API level 22.
374210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
375661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param account The account to query for user data
376661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return The user data, null if the account or key doesn't exist
377756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
378ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public String getUserData(final Account account, final String key) {
379382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
380382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (key == null) throw new IllegalArgumentException("key is null");
381603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
382603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana            return mService.getUserData(account, key);
383603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
384f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
385603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
386603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
387603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
388756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
389661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Lists the currently registered authenticators.
390661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
391661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
392661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
393661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>No permission is required to call this method.
394661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
395661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An array of {@link AuthenticatorDescription} for every
396661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     authenticator known to the AccountManager service.  Empty (never
397661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null) if no authenticators are known.
398756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
399ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public AuthenticatorDescription[] getAuthenticatorTypes() {
400603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
401c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina            return mService.getAuthenticatorTypes(UserHandle.getCallingUserId());
402c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        } catch (RemoteException e) {
403f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
404c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        }
405c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    }
406c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina
407c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    /**
408c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     * @hide
409c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     * Lists the currently registered authenticators for a given user id.
410c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     *
411c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     * <p>It is safe to call this method from the main thread.
412c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     *
413c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     * <p>The caller has to be in the same user or have the permission
414c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}.
415c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     *
416c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     * @return An array of {@link AuthenticatorDescription} for every
417c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     *     authenticator known to the AccountManager service.  Empty (never
418c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     *     null) if no authenticators are known.
419c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     */
420c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    public AuthenticatorDescription[] getAuthenticatorTypesAsUser(int userId) {
421c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        try {
422c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina            return mService.getAuthenticatorTypes(userId);
423603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
424f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
425603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
426603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
427603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
428756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
429358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * Lists all accounts of any type registered on the device.
430358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * Equivalent to getAccountsByType(null).
431661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
432358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p>It is safe to call this method from the main thread.
433661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
434358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p>Clients of this method that have not been granted the
435358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
436358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * will only see those accounts managed by AbstractAccountAuthenticators whose
437358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * signature matches the client.
438661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
439358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * @return An array of {@link Account}, one for each account.  Empty
440358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *     (never null) if no accounts have been added.
441756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
44202cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov    @NonNull
443358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz    @RequiresPermission(GET_ACCOUNTS)
444ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public Account[] getAccounts() {
445358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz        try {
446358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz            return mService.getAccounts(null, mContext.getOpPackageName());
447358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz        } catch (RemoteException e) {
448358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz            throw e.rethrowFromSystemServer();
449358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz        }
450603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
451603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
452756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
45327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani     * @hide
454358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * Lists all accounts of any type registered on the device for a given
455358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * user id. Equivalent to getAccountsByType(null).
456358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *
457358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p>It is safe to call this method from the main thread.
458358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *
459358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p>Clients of this method that have not been granted the
460358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
461358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * will only see those accounts managed by AbstractAccountAuthenticators whose
462358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * signature matches the client.
463358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *
464358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * @return An array of {@link Account}, one for each account.  Empty
465358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *     (never null) if no accounts have been added.
466c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     */
46702cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov    @NonNull
468358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz    @RequiresPermission(GET_ACCOUNTS)
469c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    public Account[] getAccountsAsUser(int userId) {
470c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        try {
471f3f02ac931d04e6ba4393e27558cd317cb1e6b44Svetoslav            return mService.getAccountsAsUser(null, userId, mContext.getOpPackageName());
472c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        } catch (RemoteException e) {
473f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
474c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina        }
475c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    }
476c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina
477c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina    /**
478c1cf161af036e0f337b58ef0739a8ff2e42f01e7Alexandra Gherghina     * @hide
47927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani     * For use by internal activities. Returns the list of accounts that the calling package
48027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani     * is authorized to use, particularly for shared accounts.
48127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani     * @param packageName package name of the calling app.
48227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani     * @param uid the uid of the calling app.
48327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani     * @return the accounts that are available to this package and user.
48427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani     */
48502cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov    @NonNull
48627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani    public Account[] getAccountsForPackage(String packageName, int uid) {
48727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani        try {
488f3f02ac931d04e6ba4393e27558cd317cb1e6b44Svetoslav            return mService.getAccountsForPackage(packageName, uid, mContext.getOpPackageName());
48927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani        } catch (RemoteException re) {
490f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw re.rethrowFromSystemServer();
4913b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani        }
4923b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani    }
4933b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani
4943b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani    /**
4953b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani     * Returns the accounts visible to the specified package, in an environment where some apps
4963b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani     * are not authorized to view all accounts. This method can only be called by system apps.
4973b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani     * @param type The type of accounts to return, null to retrieve all accounts
4983b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani     * @param packageName The package name of the app for which the accounts are to be returned
499358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * @return An array of {@link Account}, one per matching account.  Empty
500358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *     (never null) if no accounts of the specified type have been added.
5013b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani     */
50202cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov    @NonNull
5033b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani    public Account[] getAccountsByTypeForPackage(String type, String packageName) {
5043b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani        try {
505f3f02ac931d04e6ba4393e27558cd317cb1e6b44Svetoslav            return mService.getAccountsByTypeForPackage(type, packageName,
506f3f02ac931d04e6ba4393e27558cd317cb1e6b44Svetoslav                    mContext.getOpPackageName());
5073b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani        } catch (RemoteException re) {
508f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw re.rethrowFromSystemServer();
50927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani        }
51027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani    }
51127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani
51227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani    /**
513358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * Lists all accounts of a particular type.  The account type is a
514358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * string token corresponding to the authenticator and useful domain
515358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * of the account.  For example, there are types corresponding to Google
516358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * and Facebook.  The exact string token to use will be published somewhere
517358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * associated with the authenticator in question.
518358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *
519358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p>It is safe to call this method from the main thread.
520661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
521358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p>Clients of this method that have not been granted the
522358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
523358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * will only see those accounts managed by AbstractAccountAuthenticators whose
524358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * signature matches the client.
525661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
526358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
527358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
528358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * or signature match. See docs for this function in API level 22.
529bf33bd4d31cfec895c96990525b0cb856407c8d6Carlos Valdivia     *
530358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * @param type The type of accounts to return, null to retrieve all accounts
531358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * @return An array of {@link Account}, one per matching account.  Empty
532358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *     (never null) if no accounts of the specified type have been added.
533756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
53402cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov    @NonNull
535358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz    @RequiresPermission(GET_ACCOUNTS)
536ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public Account[] getAccountsByType(String type) {
5372c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani        return getAccountsByTypeAsUser(type, Process.myUserHandle());
5382c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani    }
5392c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani
5402c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani    /** @hide Same as {@link #getAccountsByType(String)} but for a specific user. */
54102cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov    @NonNull
5422c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani    public Account[] getAccountsByTypeAsUser(String type, UserHandle userHandle) {
543603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
544f3f02ac931d04e6ba4393e27558cd317cb1e6b44Svetoslav            return mService.getAccountsAsUser(type, userHandle.getIdentifier(),
545f3f02ac931d04e6ba4393e27558cd317cb1e6b44Svetoslav                    mContext.getOpPackageName());
546603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
547f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
548603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
549603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
550603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
551756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
552d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * Change whether or not an app (identified by its uid) is allowed to retrieve an authToken
553d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * for an account.
554d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * <p>
555d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * This is only meant to be used by system activities and is not in the SDK.
556d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @param account The account whose permissions are being modified
557d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @param authTokenType The type of token whose permissions are being modified
558d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @param uid The uid that identifies the app which is being granted or revoked permission.
559d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @param value true is permission is being granted, false for revoked
560d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @hide
561d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     */
562d9640ec712806508877868d08aafaa2d715ff441Fred Quintana    public void updateAppPermission(Account account, String authTokenType, int uid, boolean value) {
563d9640ec712806508877868d08aafaa2d715ff441Fred Quintana        try {
564d9640ec712806508877868d08aafaa2d715ff441Fred Quintana            mService.updateAppPermission(account, authTokenType, uid, value);
565d9640ec712806508877868d08aafaa2d715ff441Fred Quintana        } catch (RemoteException e) {
566f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
567d9640ec712806508877868d08aafaa2d715ff441Fred Quintana        }
568d9640ec712806508877868d08aafaa2d715ff441Fred Quintana    }
569d9640ec712806508877868d08aafaa2d715ff441Fred Quintana
570d9640ec712806508877868d08aafaa2d715ff441Fred Quintana    /**
571d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * Get the user-friendly label associated with an authenticator's auth token.
572d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @param accountType the type of the authenticator. must not be null.
573d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @param authTokenType the token type. must not be null.
574d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @param callback callback to invoke when the result is available. may be null.
575d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @param handler the handler on which to invoke the callback, or null for the main thread
576d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @return a future containing the label string
577d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     * @hide
578d9640ec712806508877868d08aafaa2d715ff441Fred Quintana     */
579d9640ec712806508877868d08aafaa2d715ff441Fred Quintana    public AccountManagerFuture<String> getAuthTokenLabel(
580d9640ec712806508877868d08aafaa2d715ff441Fred Quintana            final String accountType, final String authTokenType,
581d9640ec712806508877868d08aafaa2d715ff441Fred Quintana            AccountManagerCallback<String> callback, Handler handler) {
582d9640ec712806508877868d08aafaa2d715ff441Fred Quintana        if (accountType == null) throw new IllegalArgumentException("accountType is null");
583d9640ec712806508877868d08aafaa2d715ff441Fred Quintana        if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
584d9640ec712806508877868d08aafaa2d715ff441Fred Quintana        return new Future2Task<String>(handler, callback) {
5850b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
586d9640ec712806508877868d08aafaa2d715ff441Fred Quintana            public void doWork() throws RemoteException {
587d9640ec712806508877868d08aafaa2d715ff441Fred Quintana                mService.getAuthTokenLabel(mResponse, accountType, authTokenType);
588d9640ec712806508877868d08aafaa2d715ff441Fred Quintana            }
589d9640ec712806508877868d08aafaa2d715ff441Fred Quintana
590d9640ec712806508877868d08aafaa2d715ff441Fred Quintana            @Override
591d9640ec712806508877868d08aafaa2d715ff441Fred Quintana            public String bundleToResult(Bundle bundle) throws AuthenticatorException {
592d9640ec712806508877868d08aafaa2d715ff441Fred Quintana                if (!bundle.containsKey(KEY_AUTH_TOKEN_LABEL)) {
593d9640ec712806508877868d08aafaa2d715ff441Fred Quintana                    throw new AuthenticatorException("no result in response");
594d9640ec712806508877868d08aafaa2d715ff441Fred Quintana                }
595d9640ec712806508877868d08aafaa2d715ff441Fred Quintana                return bundle.getString(KEY_AUTH_TOKEN_LABEL);
596d9640ec712806508877868d08aafaa2d715ff441Fred Quintana            }
597d9640ec712806508877868d08aafaa2d715ff441Fred Quintana        }.start();
598d9640ec712806508877868d08aafaa2d715ff441Fred Quintana    }
599d9640ec712806508877868d08aafaa2d715ff441Fred Quintana
600d9640ec712806508877868d08aafaa2d715ff441Fred Quintana    /**
601661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Finds out whether a particular account has all the specified features.
602661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Account features are authenticator-specific string tokens identifying
603661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * boolean account properties.  For example, features are used to tell
604661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * whether Google accounts have a particular service (such as Google
605661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Calendar or Google Talk) enabled.  The feature names and their meanings
606661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * are published somewhere associated with the authenticator in question.
607661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
608661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may be called from any thread, but the returned
609661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManagerFuture} must not be used on the main thread.
610661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
611358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p>This method requires the caller to hold the permission
612358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * {@link android.Manifest.permission#GET_ACCOUNTS} or be a signature
613358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * match with the AbstractAccountAuthenticator that manages the account.
614bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana     *
615bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana     * @param account The {@link Account} to test
616661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param features An array of the account features to check
617661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
618661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
619661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
620661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
621661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManagerFuture} which resolves to a Boolean,
622358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * true if the account exists and has all of the specified features.
623bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana     */
624358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz    @RequiresPermission(GET_ACCOUNTS)
6253084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana    public AccountManagerFuture<Boolean> hasFeatures(final Account account,
626bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana            final String[] features,
627bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana            AccountManagerCallback<Boolean> callback, Handler handler) {
628382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
629382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (features == null) throw new IllegalArgumentException("features is null");
630bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana        return new Future2Task<Boolean>(handler, callback) {
6310b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
632bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana            public void doWork() throws RemoteException {
633f3f02ac931d04e6ba4393e27558cd317cb1e6b44Svetoslav                mService.hasFeatures(mResponse, account, features, mContext.getOpPackageName());
634bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana            }
6350b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
636bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
637bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana                if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
638bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana                    throw new AuthenticatorException("no result in response");
639bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana                }
640bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana                return bundle.getBoolean(KEY_BOOLEAN_RESULT);
641bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana            }
642bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana        }.start();
643bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana    }
644bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana
645bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana    /**
646661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Lists all accounts of a type which have certain features.  The account
647358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * type identifies the authenticator (see {@link #getAccountsByType}).
648358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * Account features are authenticator-specific string tokens identifying
649358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * boolean account properties (see {@link #hasFeatures}).
650661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
651661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>Unlike {@link #getAccountsByType}, this method calls the authenticator,
652661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * which may contact the server or do other work to check account features,
653661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * so the method returns an {@link AccountManagerFuture}.
654661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
655661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may be called from any thread, but the returned
656661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManagerFuture} must not be used on the main thread.
657661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
658358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p>Clients of this method that have not been granted the
659358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
660358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * will only see those accounts managed by AbstractAccountAuthenticators whose
661358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * signature matches the client.
662661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
663661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param type The type of accounts to return, must not be null
664661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param features An array of the account features to require,
665661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     may be null or empty
666358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *
667358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
668358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
669358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     * or signature match. See docs for this function in API level 22.
670358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz     *
671661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
672661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
673661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
674661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
675661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManagerFuture} which resolves to an array of
676661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     {@link Account}, one per account of the specified type which
677661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     matches the requested features.
678661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     */
679358e51f3d186719a6a5b1f346f55c5426925055fIan Pedowitz    @RequiresPermission(GET_ACCOUNTS)
680661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
681661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor            final String type, final String[] features,
682661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor            AccountManagerCallback<Account[]> callback, Handler handler) {
683382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (type == null) throw new IllegalArgumentException("type is null");
684661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor        return new Future2Task<Account[]>(handler, callback) {
6850b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
686661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor            public void doWork() throws RemoteException {
687f3f02ac931d04e6ba4393e27558cd317cb1e6b44Svetoslav                mService.getAccountsByFeatures(mResponse, type, features,
688f3f02ac931d04e6ba4393e27558cd317cb1e6b44Svetoslav                        mContext.getOpPackageName());
689661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor            }
6900b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
691661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor            public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException {
692661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                if (!bundle.containsKey(KEY_ACCOUNTS)) {
693661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                    throw new AuthenticatorException("no result in response");
694661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                }
695661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                final Parcelable[] parcelables = bundle.getParcelableArray(KEY_ACCOUNTS);
696661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                Account[] descs = new Account[parcelables.length];
697661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                for (int i = 0; i < parcelables.length; i++) {
698661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                    descs[i] = (Account) parcelables[i];
699661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                }
700661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                return descs;
701661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor            }
702661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor        }.start();
703661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    }
704661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor
705661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor    /**
7060b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * Adds an account directly to the AccountManager. Normally used by sign-up
707661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * wizards associated with authenticators, not directly by applications.
7080b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * <p>Calling this method does not update the last authenticated timestamp,
7090b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * referred by {@link #KEY_LAST_AUTHENTICATED_TIME}. To update it, call
7100b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * {@link #notifyAccountAuthenticated(Account)} after getting success.
7110b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * However, if this method is called when it is triggered by addAccount() or
7120b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * addAccountAsUser() or similar functions, then there is no need to update
7130b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * timestamp manually as it is updated automatically by framework on
7140b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * successful completion of the mentioned functions.
715661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
7166eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
7176eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that owns the specified account.
718661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
719210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
720210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * AUTHENTICATE_ACCOUNTS permission is needed for those platforms. See docs
721210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * for this function in API level 22.
722210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
723661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param account The {@link Account} to add
724661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param password The password to associate with the account, null for none
7250b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * @param userdata String values to use for the account's userdata, null for
7260b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     *            none
7278e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * @return True if the account was successfully added, false if the account
7280b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     *         already exists, the account is null, or another error occurs.
729756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
73031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana    public boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
731382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
732603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
73327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani            return mService.addAccountExplicitly(account, password, userdata);
734603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
735f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
736603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
737603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
738603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
739756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
7401663b44cfd5fe589183dae5db769c843870cb5dbSimranjit Singh Kohli     * Notifies the system that the account has just been authenticated. This
7411663b44cfd5fe589183dae5db769c843870cb5dbSimranjit Singh Kohli     * information may be used by other applications to verify the account. This
7426c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * should be called only when the user has entered correct credentials for
7436c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * the account.
7446c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * <p>
7456c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * It is not safe to call this method from the main thread. As such, call it
7466c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * from another thread.
7476eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
7486eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that owns the specified account.
7496c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     *
7506c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * @param account The {@link Account} to be updated.
7516eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * @return boolean {@code true} if the authentication of the account has been successfully
7526eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     *         acknowledged. Otherwise {@code false}.
7536c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     */
7541663b44cfd5fe589183dae5db769c843870cb5dbSimranjit Singh Kohli    public boolean notifyAccountAuthenticated(Account account) {
7556c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli        if (account == null)
7566c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli            throw new IllegalArgumentException("account is null");
7576c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli        try {
7586c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli            return mService.accountAuthenticated(account);
7596c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli        } catch (RemoteException e) {
760f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
7616c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli        }
7626c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli    }
7636c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli
7646c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli    /**
765f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * Rename the specified {@link Account}.  This is equivalent to removing
766f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * the existing account and adding a new renamed account with the old
767f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * account's user data.
768f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *
769f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * <p>It is safe to call this method from the main thread.
770f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *
7716eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
7726eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that manages the specified account.
773f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *
774210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
775210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
776210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * is needed for those platforms. See docs for this function in API level 22.
777210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
778f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * @param account The {@link Account} to rename
779f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * @param newName String name to be associated with the account.
780f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * @param callback Callback to invoke when the request completes, null for
781f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *     no callback
782f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * @param handler {@link Handler} identifying the callback thread, null for
783f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *     the main thread
784f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * @return An {@link AccountManagerFuture} which resolves to the Account
785f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *     after the name change. If successful the account's name will be the
786f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *     specified new name.
787f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     */
788f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia    public AccountManagerFuture<Account> renameAccount(
789f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            final Account account,
79080b530afdb3c19bb664e0ff8c2b650de917305d2Tor Norbye            @Size(min = 1) final String newName,
791f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            AccountManagerCallback<Account> callback,
792f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            Handler handler) {
793f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia        if (account == null) throw new IllegalArgumentException("account is null.");
794f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia        if (TextUtils.isEmpty(newName)) {
795f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia              throw new IllegalArgumentException("newName is empty or null.");
796f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia        }
797f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia        return new Future2Task<Account>(handler, callback) {
798f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            @Override
799f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            public void doWork() throws RemoteException {
800f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia                mService.renameAccount(mResponse, account, newName);
801f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            }
802f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            @Override
803f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            public Account bundleToResult(Bundle bundle) throws AuthenticatorException {
804f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia                String name = bundle.getString(KEY_ACCOUNT_NAME);
805f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia                String type = bundle.getString(KEY_ACCOUNT_TYPE);
806f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia                return new Account(name, type);
807f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            }
808f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia        }.start();
809f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia    }
810f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia
811f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia    /**
812f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * Gets the previous name associated with the account or {@code null}, if
813f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * none. This is intended so that clients of {@link
814f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * #LOGIN_ACCOUNTS_CHANGED_ACTION} broadcasts can determine if an
815f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * authenticator has renamed an account.
816f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *
817f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * <p>It is safe to call this method from the main thread.
818f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *
819f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * @param account The account to query for a previous name.
820f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     * @return The account's previous name, null if the account has never been
821f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     *         renamed.
822f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia     */
823f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia    public String getPreviousName(final Account account) {
824f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia        if (account == null) throw new IllegalArgumentException("account is null");
825f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia        try {
826f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia            return mService.getPreviousName(account);
827f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia        } catch (RemoteException e) {
828f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
829f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia        }
830f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia    }
831f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia
832f193b9a61d0b14d13bb7f8aec42a21154672e5ecCarlos Valdivia    /**
833661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Removes an account from the AccountManager.  Does nothing if the account
834661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * does not exist.  Does not delete the account from the server.
835661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * The authenticator may have its own policies preventing account
836661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * deletion, in which case the account will not be deleted.
837661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
8386eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
8396eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that manages the specified account.
840756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     *
841210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
842210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
843210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
844210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
845756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * @param account The {@link Account} to remove
846661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
847661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
848661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
849661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
850661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManagerFuture} which resolves to a Boolean,
851999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina     *     true if the account has been successfully removed
8528778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @deprecated use
8538778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     {@link #removeAccount(Account, Activity, AccountManagerCallback, Handler)}
8548778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     instead
855756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
8568778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    @Deprecated
857ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public AccountManagerFuture<Boolean> removeAccount(final Account account,
858ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            AccountManagerCallback<Boolean> callback, Handler handler) {
859382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
860ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        return new Future2Task<Boolean>(handler, callback) {
8616eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia            @Override
862ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            public void doWork() throws RemoteException {
8638778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli                mService.removeAccount(mResponse, account, false);
864a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
8656eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia            @Override
866ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
867f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
868ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    throw new AuthenticatorException("no result in response");
869ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                }
870f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                return bundle.getBoolean(KEY_BOOLEAN_RESULT);
871a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
872ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        }.start();
873a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
874a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
875756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
8768778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * Removes an account from the AccountManager. Does nothing if the account
8778778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * does not exist.  Does not delete the account from the server.
8788778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * The authenticator may have its own policies preventing account
8798778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * deletion, in which case the account will not be deleted.
8808778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *
8818778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * <p>This method may be called from any thread, but the returned
8828778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * {@link AccountManagerFuture} must not be used on the main thread.
8838778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *
8846eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
8856eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that manages the specified account.
8868778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *
887210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
888210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
889210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
890210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
8918778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @param account The {@link Account} to remove
8928778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @param activity The {@link Activity} context to use for launching a new
8938778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     authenticator-defined sub-Activity to prompt the user to delete an
8948778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     account; used only to call startActivity(); if null, the prompt
8958778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     will not be launched directly, but the {@link Intent} may be
8968778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     returned to the caller instead
8978778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @param callback Callback to invoke when the request completes,
8988778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     null for no callback
8998778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @param handler {@link Handler} identifying the callback thread,
9008778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     null for the main thread
9018778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @return An {@link AccountManagerFuture} which resolves to a Bundle with
9028778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     {@link #KEY_BOOLEAN_RESULT} if activity was specified and an account
9038778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     was removed or if active. If no activity was specified, the returned
9048778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     Bundle contains only {@link #KEY_INTENT} with the {@link Intent}
9058778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     needed to launch the actual account removal process, if authenticator
9068778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     needs the activity launch. If an error occurred,
9078778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     {@link AccountManagerFuture#getResult()} throws:
9088778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * <ul>
9098778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * <li> {@link AuthenticatorException} if no authenticator was registered for
9108778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *      this account type or the authenticator failed to respond
9118778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * <li> {@link OperationCanceledException} if the operation was canceled for
9128778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *      any reason, including the user canceling the creation process or
9138778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *      adding accounts (of this type) has been disabled by policy
9148778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * </ul>
9158778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     */
9168778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    public AccountManagerFuture<Bundle> removeAccount(final Account account,
9178778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
9188778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        if (account == null) throw new IllegalArgumentException("account is null");
9198778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        return new AmsTask(activity, handler, callback) {
9206eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia            @Override
9218778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            public void doWork() throws RemoteException {
9228778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli                mService.removeAccount(mResponse, account, activity != null);
9238778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            }
9248778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        }.start();
9258778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    }
9268778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli
9278778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    /**
928999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina     * @see #removeAccount(Account, AccountManagerCallback, Handler)
929999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina     * @hide
9308778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @deprecated use
9318778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     {@link #removeAccountAsUser(Account, Activity, AccountManagerCallback, Handler)}
9328778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *     instead
933999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina     */
9348778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    @Deprecated
935999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina    public AccountManagerFuture<Boolean> removeAccountAsUser(final Account account,
936999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            AccountManagerCallback<Boolean> callback, Handler handler,
937999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            final UserHandle userHandle) {
938999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        if (account == null) throw new IllegalArgumentException("account is null");
939999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        if (userHandle == null) throw new IllegalArgumentException("userHandle is null");
940999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        return new Future2Task<Boolean>(handler, callback) {
9416eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia            @Override
942999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            public void doWork() throws RemoteException {
9438778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli                mService.removeAccountAsUser(mResponse, account, false, userHandle.getIdentifier());
944999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            }
9456eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia            @Override
946999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
947999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
948999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                    throw new AuthenticatorException("no result in response");
949999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                }
950999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                return bundle.getBoolean(KEY_BOOLEAN_RESULT);
951999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            }
952999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        }.start();
953999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina    }
954999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina
955999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina    /**
9568778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @see #removeAccount(Account, Activity, AccountManagerCallback, Handler)
9578778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @hide
9588778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     */
9598778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    public AccountManagerFuture<Bundle> removeAccountAsUser(final Account account,
9608778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler,
9618778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            final UserHandle userHandle) {
9628778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        if (account == null)
9638778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            throw new IllegalArgumentException("account is null");
9648778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        if (userHandle == null)
9658778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            throw new IllegalArgumentException("userHandle is null");
9668778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        return new AmsTask(activity, handler, callback) {
9670b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
9688778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            public void doWork() throws RemoteException {
9698778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli                mService.removeAccountAsUser(mResponse, account, activity != null,
9708778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli                        userHandle.getIdentifier());
9718778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            }
9728778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        }.start();
9738778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    }
9748778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli
9758778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    /**
9768778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * Removes an account directly. Normally used by authenticators, not
9778778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * directly by applications. Does not delete the account from the server.
9788778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * The authenticator may have its own policies preventing account deletion,
9798778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * in which case the account will not be deleted.
9808778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * <p>
9818778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * It is safe to call this method from the main thread.
9826eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
9836eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that manages the specified account.
9848778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *
985210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
986210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
987210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * is needed for those platforms. See docs for this function in API level 22.
988210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
9898778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @param account The {@link Account} to delete.
9908778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     * @return True if the account was successfully deleted, false if the
9918778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *         account did not exist, the account is null, or another error
9928778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     *         occurs.
9938778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli     */
9948778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    public boolean removeAccountExplicitly(Account account) {
9958778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        if (account == null) throw new IllegalArgumentException("account is null");
9968778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        try {
9978778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli            return mService.removeAccountExplicitly(account);
9988778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        } catch (RemoteException e) {
999f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
10008778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli        }
10018778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    }
10028778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli
10038778f993aeb7ec3df88aa0b244381253257bafe2Simranjit Singh Kohli    /**
1004661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Removes an auth token from the AccountManager's cache.  Does nothing if
1005661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * the auth token is not currently in the cache.  Applications must call this
1006661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * method when the auth token is found to have expired or otherwise become
1007661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * invalid for authenticating requests.  The AccountManager does not validate
1008661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * or expire cached auth tokens otherwise.
1009661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1010661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
1011661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1012210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1013210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * MANAGE_ACCOUNTS or USE_CREDENTIALS permission is needed for those
1014210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * platforms. See docs for this function in API level 22.
1015210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
1016f35b68f2b926021bce407f092cfe3e8f52fa0794Fred Quintana     * @param accountType The account type of the auth token to invalidate, must not be null
1017f35b68f2b926021bce407f092cfe3e8f52fa0794Fred Quintana     * @param authToken The auth token to invalidate, may be null
1018756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1019ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public void invalidateAuthToken(final String accountType, final String authToken) {
1020382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (accountType == null) throw new IllegalArgumentException("accountType is null");
1021603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
1022f35b68f2b926021bce407f092cfe3e8f52fa0794Fred Quintana            if (authToken != null) {
1023f35b68f2b926021bce407f092cfe3e8f52fa0794Fred Quintana                mService.invalidateAuthToken(accountType, authToken);
1024f35b68f2b926021bce407f092cfe3e8f52fa0794Fred Quintana            }
1025603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
1026f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
1027603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
1028603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
1029603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
1030756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
1031661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Gets an auth token from the AccountManager's cache.  If no auth
1032661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * token is cached for this account, null will be returned -- a new
1033661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * auth token will not be generated, and the server will not be contacted.
1034661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Intended for use by the authenticator, not directly by applications.
1035661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1036661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
1037661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
10386eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
10396eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that manages the specified account.
1040661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1041210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1042210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
1043210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * is needed for those platforms. See docs for this function in API level 22.
1044210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
10456eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * @param account The account for which an auth token is to be fetched. Cannot be {@code null}.
10460b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan     * @param authTokenType The type of auth token to fetch. Cannot be {@code null}.
1047661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return The cached auth token for this account and type, or null if
1048661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     no auth token is cached or the account does not exist.
10496eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * @see #getAuthToken
1050756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1051ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public String peekAuthToken(final Account account, final String authTokenType) {
1052382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
1053382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
1054603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
1055603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana            return mService.peekAuthToken(account, authTokenType);
1056603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
1057f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
1058603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
1059603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
1060603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
1061756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
10620b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * Sets or forgets a saved password. This modifies the local copy of the
10630b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * password used to automatically authenticate the user; it does not change
10640b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * the user's account password on the server. Intended for use by the
10650b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * authenticator, not directly by applications.
10660b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * <p>Calling this method does not update the last authenticated timestamp,
10670b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * referred by {@link #KEY_LAST_AUTHENTICATED_TIME}. To update it, call
10680b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * {@link #notifyAccountAuthenticated(Account)} after getting success.
1069661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
10706eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
10716eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that manages the specified account.
1072661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1073210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1074210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
1075210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * is needed for those platforms. See docs for this function in API level 22.
1076210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
10770b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     * @param account The account whose password is to be set. Cannot be
10780b8a7c00bd9433862e7867f6780fe3cd5771ee7dSimranjit Singh Kohli     *            {@code null}.
1079661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param password The password to set, null to clear the password
1080756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1081ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public void setPassword(final Account account, final String password) {
1082382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
1083603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
1084603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana            mService.setPassword(account, password);
1085603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
1086f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
1087603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
1088603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
1089603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
1090756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
1091661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Forgets a saved password.  This erases the local copy of the password;
1092661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * it does not change the user's account password on the server.
1093661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Has the same effect as setPassword(account, null) but requires fewer
1094661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * permissions, and may be used by applications or management interfaces
1095661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * to "sign out" from an account.
1096661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
10976eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method only successfully clear the account's password when the
10986eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * caller has the same signature as the authenticator that owns the
10996eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * specified account. Otherwise, this method will silently fail.
1100661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
11016eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>It is safe to call this method from the main thread.
1102dcddc476651deb72a27798de56eef584e5be5d32Carlos Valdivia     *
1103210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1104210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
1105210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
1106210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
1107661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param account The account whose password to clear
1108756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1109ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public void clearPassword(final Account account) {
1110382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
1111603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
1112603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana            mService.clearPassword(account);
1113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
1114f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
1115603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
1116603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
1117603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
1118756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
1119661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Sets one userdata key for an account.  Intended by use for the
1120661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * authenticator to stash state for itself, not directly by applications.
1121661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * The meaning of the keys and values is up to the authenticator.
1122661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1123661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
1124661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
11256eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
11266eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that manages the specified account.
1127661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1128210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1129210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
1130210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * is needed for those platforms. See docs for this function in API level 22.
1131210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
11326eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * @param account Account whose user data is to be set. Must not be {@code null}.
11336eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * @param key String user data key to set.  Must not be null
11346eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * @param value String value to set, {@code null} to clear this user data key
1135756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1136ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public void setUserData(final Account account, final String key, final String value) {
1137382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
1138382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (key == null) throw new IllegalArgumentException("key is null");
1139603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
1140603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana            mService.setUserData(account, key, value);
1141603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
1142f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
1143603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
1144603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
1145603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
1146756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
1147661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Adds an auth token to the AccountManager cache for an account.
1148756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * If the account does not exist then this call has no effect.
1149661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Replaces any previous auth token for this account and auth token type.
1150661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Intended for use by the authenticator, not directly by applications.
1151661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1152661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
1153661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
11546eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have a signature match with the
11556eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator that manages the specified account.
1156661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1157210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1158210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
1159210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * is needed for those platforms. See docs for this function in API level 22.
1160210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
1161661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param account The account to set an auth token for
1162661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param authTokenType The type of the auth token, see {#getAuthToken}
1163661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param authToken The auth token to add to the cache
1164756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1165ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public void setAuthToken(Account account, final String authTokenType, final String authToken) {
1166382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
1167382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
1168603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        try {
1169603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana            mService.setAuthToken(account, authTokenType, authToken);
1170603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        } catch (RemoteException e) {
1171f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
1172603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
1173603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
1174603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
1175756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
1176661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * This convenience helper synchronously gets an auth token with
1177661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link #getAuthToken(Account, String, boolean, AccountManagerCallback, Handler)}.
1178661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1179661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may block while a network request completes, and must
1180661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * never be made from the main thread.
1181661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1182210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1183210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * USE_CREDENTIALS permission is needed for those platforms. See docs for
1184210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
1185210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
1186661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param account The account to fetch an auth token for
1187b6a35268ccb698cde6d2e1e2f475a7299112b034Joe Malin     * @param authTokenType The auth token type, see {@link #getAuthToken getAuthToken()}
1188661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param notifyAuthFailure If true, display a notification and return null
1189661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     if authentication fails; if false, prompt and wait for the user to
1190661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     re-enter correct credentials before returning
1191661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An auth token of the specified type for this account, or null
1192661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     if authentication fails or none can be fetched.
1193661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @throws AuthenticatorException if the authenticator failed to respond
1194661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @throws OperationCanceledException if the request was canceled for any
1195661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     reason, including the user canceling a credential request
1196661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @throws java.io.IOException if the authenticator experienced an I/O problem
1197661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     creating a new auth token, usually because of network trouble
1198756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1199a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    public String blockingGetAuthToken(Account account, String authTokenType,
1200a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            boolean notifyAuthFailure)
1201a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            throws OperationCanceledException, IOException, AuthenticatorException {
1202382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
1203382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
1204a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        Bundle bundle = getAuthToken(account, authTokenType, notifyAuthFailure, null /* callback */,
1205a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                null /* handler */).getResult();
120696580e00654a052a82120c374c6b5961ef349a92Fred Quintana        if (bundle == null) {
120796580e00654a052a82120c374c6b5961ef349a92Fred Quintana            // This should never happen, but it does, occasionally. If it does return null to
120896580e00654a052a82120c374c6b5961ef349a92Fred Quintana            // signify that we were not able to get the authtoken.
120996580e00654a052a82120c374c6b5961ef349a92Fred Quintana            // TODO: remove this when the bug is found that sometimes causes a null bundle to be
121096580e00654a052a82120c374c6b5961ef349a92Fred Quintana            // returned
121196580e00654a052a82120c374c6b5961ef349a92Fred Quintana            Log.e(TAG, "blockingGetAuthToken: null was returned from getResult() for "
121296580e00654a052a82120c374c6b5961ef349a92Fred Quintana                    + account + ", authTokenType " + authTokenType);
121396580e00654a052a82120c374c6b5961ef349a92Fred Quintana            return null;
121496580e00654a052a82120c374c6b5961ef349a92Fred Quintana        }
1215f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana        return bundle.getString(KEY_AUTHTOKEN);
1216a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
1217a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
1218a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    /**
1219661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Gets an auth token of the specified type for a particular account,
1220661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * prompting the user for credentials if necessary.  This method is
1221661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * intended for applications running in the foreground where it makes
1222661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * sense to ask the user directly for a password.
1223661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1224661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>If a previously generated auth token is cached for this account and
12258e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * type, then it is returned.  Otherwise, if a saved password is
12268e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * available, it is sent to the server to generate a new auth token.
12278e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * Otherwise, the user is prompted to enter a password.
1228661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
12298e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * <p>Some authenticators have auth token <em>types</em>, whose value
12308e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * is authenticator-dependent.  Some services use different token types to
12318e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * access different functionality -- for example, Google uses different auth
12328e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * tokens to access Gmail and Google Calendar for the same account.
1233661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1234210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
12350b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan     * USE_CREDENTIALS permission is needed for those platforms. See docs for
1236210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
1237210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
1238661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may be called from any thread, but the returned
1239661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManagerFuture} must not be used on the main thread.
1240661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1241661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param account The account to fetch an auth token for
1242661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param authTokenType The auth token type, an authenticator-dependent
1243661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     string token, must not be null
1244661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param options Authenticator-specific options for the request,
1245661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     may be null or empty
1246661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param activity The {@link Activity} context to use for launching a new
1247661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     authenticator-defined sub-Activity to prompt the user for a password
1248661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     if necessary; used only to call startActivity(); must not be null.
1249661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
1250661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
1251661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
1252661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
1253661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManagerFuture} which resolves to a Bundle with
1254661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     at least the following fields:
1255661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <ul>
1256661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account you supplied
1257661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
1258661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_AUTHTOKEN} - the auth token you wanted
1259661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * </ul>
1260661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1261661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * (Other authenticator-specific values may be returned.)  If an auth token
1262661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * could not be fetched, {@link AccountManagerFuture#getResult()} throws:
1263756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * <ul>
1264661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link AuthenticatorException} if the authenticator failed to respond
1265661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link OperationCanceledException} if the operation is canceled for
1266661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      any reason, incluidng the user canceling a credential request
1267661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link IOException} if the authenticator experienced an I/O problem
1268661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      creating a new auth token, usually because of network trouble
1269756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * </ul>
12708e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * If the account is no longer present on the device, the return value is
12718e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * authenticator-dependent.  The caller should verify the validity of the
12728e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * account before requesting an auth token.
1273a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana     */
1274ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public AccountManagerFuture<Bundle> getAuthToken(
127531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana            final Account account, final String authTokenType, final Bundle options,
1276ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
1277382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
1278a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
1279e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        final Bundle optionsIn = new Bundle();
1280e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        if (options != null) {
1281e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache            optionsIn.putAll(options);
1282e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        }
1283b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache        optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
1284a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        return new AmsTask(activity, handler, callback) {
12850b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
1286a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            public void doWork() throws RemoteException {
1287a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                mService.getAuthToken(mResponse, account, authTokenType,
1288a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                        false /* notifyOnAuthFailure */, true /* expectActivityLaunch */,
1289b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache                        optionsIn);
1290a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
12913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }.start();
1292a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
1293a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
1294756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
1295661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Gets an auth token of the specified type for a particular account,
1296661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * optionally raising a notification if the user must enter credentials.
1297661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * This method is intended for background tasks and services where the
1298661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * user should not be immediately interrupted with a password prompt.
1299661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1300661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>If a previously generated auth token is cached for this account and
13018e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * type, then it is returned.  Otherwise, if a saved password is
13028e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * available, it is sent to the server to generate a new auth token.
13038e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * Otherwise, an {@link Intent} is returned which, when started, will
13048e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * prompt the user for a password.  If the notifyAuthFailure parameter is
13058e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * set, a status bar notification is also created with the same Intent,
1306661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * alerting the user that they need to enter a password at some point.
1307661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
13088e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * <p>In that case, you may need to wait until the user responds, which
13098e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * could take hours or days or forever.  When the user does respond and
13108e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * supply a new password, the account manager will broadcast the
13118e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent, which applications can
13128e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * use to try again.
1313661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
13148e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * <p>If notifyAuthFailure is not set, it is the application's
13158e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * responsibility to launch the returned Intent at some point.
13168e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * Either way, the result from this call will not wait for user action.
1317661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
13188e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * <p>Some authenticators have auth token <em>types</em>, whose value
13198e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * is authenticator-dependent.  Some services use different token types to
13208e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * access different functionality -- for example, Google uses different auth
13218e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * tokens to access Gmail and Google Calendar for the same account.
1322661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1323661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may be called from any thread, but the returned
1324661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManagerFuture} must not be used on the main thread.
1325661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1326661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param account The account to fetch an auth token for
1327661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param authTokenType The auth token type, an authenticator-dependent
1328661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     string token, must not be null
1329661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param notifyAuthFailure True to add a notification to prompt the
1330661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     user for a password if necessary, false to leave that to the caller
1331661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
1332661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
1333661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
1334661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
1335661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManagerFuture} which resolves to a Bundle with
1336661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     at least the following fields on success:
1337756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * <ul>
1338661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account you supplied
1339661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
1340661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_AUTHTOKEN} - the auth token you wanted
1341661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * </ul>
1342661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1343661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * (Other authenticator-specific values may be returned.)  If the user
1344661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * must enter credentials, the returned Bundle contains only
1345661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link #KEY_INTENT} with the {@link Intent} needed to launch a prompt.
1346661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
13478e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * If an error occurred, {@link AccountManagerFuture#getResult()} throws:
1348661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <ul>
1349661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link AuthenticatorException} if the authenticator failed to respond
1350661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link OperationCanceledException} if the operation is canceled for
1351661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      any reason, incluidng the user canceling a credential request
1352661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link IOException} if the authenticator experienced an I/O problem
1353661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      creating a new auth token, usually because of network trouble
1354756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * </ul>
13558e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * If the account is no longer present on the device, the return value is
13568e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * authenticator-dependent.  The caller should verify the validity of the
13578e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * account before requesting an auth token.
1358ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * @deprecated use {@link #getAuthToken(Account, String, android.os.Bundle,
1359ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * boolean, AccountManagerCallback, android.os.Handler)} instead
1360756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1361ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana    @Deprecated
1362ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public AccountManagerFuture<Bundle> getAuthToken(
13633df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia            final Account account, final String authTokenType,
1364b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache            final boolean notifyAuthFailure,
1365ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            AccountManagerCallback<Bundle> callback, Handler handler) {
13663df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia        return getAuthToken(account, authTokenType, null, notifyAuthFailure, callback,
1367b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache                handler);
1368a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
1369a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
1370756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
1371ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * Gets an auth token of the specified type for a particular account,
1372ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * optionally raising a notification if the user must enter credentials.
1373ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * This method is intended for background tasks and services where the
1374ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * user should not be immediately interrupted with a password prompt.
1375ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *
1376ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <p>If a previously generated auth token is cached for this account and
1377ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * type, then it is returned.  Otherwise, if a saved password is
1378ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * available, it is sent to the server to generate a new auth token.
1379ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * Otherwise, an {@link Intent} is returned which, when started, will
1380ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * prompt the user for a password.  If the notifyAuthFailure parameter is
1381ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * set, a status bar notification is also created with the same Intent,
1382ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * alerting the user that they need to enter a password at some point.
1383ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *
1384ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <p>In that case, you may need to wait until the user responds, which
1385ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * could take hours or days or forever.  When the user does respond and
1386ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * supply a new password, the account manager will broadcast the
1387ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent, which applications can
1388ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * use to try again.
1389ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *
1390ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <p>If notifyAuthFailure is not set, it is the application's
1391ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * responsibility to launch the returned Intent at some point.
1392ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * Either way, the result from this call will not wait for user action.
1393ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *
1394ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <p>Some authenticators have auth token <em>types</em>, whose value
1395ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * is authenticator-dependent.  Some services use different token types to
1396ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * access different functionality -- for example, Google uses different auth
1397ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * tokens to access Gmail and Google Calendar for the same account.
1398ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *
1399ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <p>This method may be called from any thread, but the returned
1400ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * {@link AccountManagerFuture} must not be used on the main thread.
1401ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *
1402210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
14030b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan     * USE_CREDENTIALS permission is needed for those platforms. See docs for
1404210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
1405210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
1406ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * @param account The account to fetch an auth token for
1407ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * @param authTokenType The auth token type, an authenticator-dependent
1408ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *     string token, must not be null
1409ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * @param options Authenticator-specific options for the request,
1410ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *     may be null or empty
1411ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * @param notifyAuthFailure True to add a notification to prompt the
1412ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *     user for a password if necessary, false to leave that to the caller
1413ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * @param callback Callback to invoke when the request completes,
1414ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *     null for no callback
1415ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * @param handler {@link Handler} identifying the callback thread,
1416ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *     null for the main thread
1417ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * @return An {@link AccountManagerFuture} which resolves to a Bundle with
1418ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *     at least the following fields on success:
1419ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <ul>
1420ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account you supplied
1421ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
1422ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <li> {@link #KEY_AUTHTOKEN} - the auth token you wanted
1423ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * </ul>
1424ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *
1425ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * (Other authenticator-specific values may be returned.)  If the user
1426ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * must enter credentials, the returned Bundle contains only
1427ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * {@link #KEY_INTENT} with the {@link Intent} needed to launch a prompt.
1428ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *
1429ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * If an error occurred, {@link AccountManagerFuture#getResult()} throws:
1430ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <ul>
1431ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <li> {@link AuthenticatorException} if the authenticator failed to respond
1432ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <li> {@link OperationCanceledException} if the operation is canceled for
1433ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *      any reason, incluidng the user canceling a credential request
1434ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * <li> {@link IOException} if the authenticator experienced an I/O problem
1435ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     *      creating a new auth token, usually because of network trouble
1436ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * </ul>
1437ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * If the account is no longer present on the device, the return value is
1438ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * authenticator-dependent.  The caller should verify the validity of the
1439ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     * account before requesting an auth token.
1440ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana     */
1441ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana    public AccountManagerFuture<Bundle> getAuthToken(
1442b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache            final Account account, final String authTokenType, final Bundle options,
1443b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache            final boolean notifyAuthFailure,
1444ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana            AccountManagerCallback<Bundle> callback, Handler handler) {
1445b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache
1446ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
1447ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana        if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
1448e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        final Bundle optionsIn = new Bundle();
1449e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        if (options != null) {
1450e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache            optionsIn.putAll(options);
1451e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        }
1452b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache        optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
1453ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana        return new AmsTask(null, handler, callback) {
14540b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
1455ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana            public void doWork() throws RemoteException {
1456ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana                mService.getAuthToken(mResponse, account, authTokenType,
1457b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache                        notifyAuthFailure, false /* expectActivityLaunch */, optionsIn);
1458ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana            }
1459ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana        }.start();
1460ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana    }
1461ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana
1462ad93a323fef9761528512aff753c709b895c8ea0Fred Quintana    /**
1463661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Asks the user to add an account of a specified type.  The authenticator
1464661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * for this account type processes this request with the appropriate user
1465661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * interface.  If the user does elect to create a new account, the account
1466661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * name is returned.
1467661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1468661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may be called from any thread, but the returned
1469661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManagerFuture} must not be used on the main thread.
14700b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan     *
1471210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1472210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
1473210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
1474661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1475661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param accountType The type of account to add; must not be null
1476661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param authTokenType The type of auth token (see {@link #getAuthToken})
1477661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     this account will need to be able to generate, null for none
1478661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param requiredFeatures The features (see {@link #hasFeatures}) this
1479661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     account must have, null for none
1480661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param addAccountOptions Authenticator-specific options for the request,
1481661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     may be null or empty
1482661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param activity The {@link Activity} context to use for launching a new
1483661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     authenticator-defined sub-Activity to prompt the user to create an
1484661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     account; used only to call startActivity(); if null, the prompt
1485661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     will not be launched directly, but the necessary {@link Intent}
1486661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     will be returned to the caller instead
1487661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
1488661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
1489661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
1490661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
1491ff592dc2fa53d48e4121d9b8fd70efc19938c4a1Doug Zongker     * @return An {@link AccountManagerFuture} which resolves to a Bundle with
1492661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     these fields if activity was specified and an account was created:
1493756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * <ul>
1494661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account created
1495661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
1496661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * </ul>
1497661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1498661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * If no activity was specified, the returned Bundle contains only
1499661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link #KEY_INTENT} with the {@link Intent} needed to launch the
15008e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * actual account creation process.  If an error occurred,
15018e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * {@link AccountManagerFuture#getResult()} throws:
1502661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <ul>
1503661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link AuthenticatorException} if no authenticator was registered for
1504661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      this account type or the authenticator failed to respond
1505661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link OperationCanceledException} if the operation was canceled for
1506999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina     *      any reason, including the user canceling the creation process or adding accounts
1507999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina     *      (of this type) has been disabled by policy
1508661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link IOException} if the authenticator experienced an I/O problem
1509661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      creating a new account, usually because of network trouble
1510756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * </ul>
1511756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1512ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    public AccountManagerFuture<Bundle> addAccount(final String accountType,
15133326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            final String authTokenType, final String[] requiredFeatures,
15143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            final Bundle addAccountOptions,
1515ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
1516382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (accountType == null) throw new IllegalArgumentException("accountType is null");
1517e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        final Bundle optionsIn = new Bundle();
1518e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        if (addAccountOptions != null) {
1519e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache            optionsIn.putAll(addAccountOptions);
1520e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        }
1521e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache        optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
1522b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache
1523a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        return new AmsTask(activity, handler, callback) {
15240b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
1525a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            public void doWork() throws RemoteException {
152627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani                mService.addAccount(mResponse, accountType, authTokenType,
1527e5847ada7bdf99386dc13471a7d4f08bf779531bCostin Manolache                        requiredFeatures, activity != null, optionsIn);
1528a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
15293326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }.start();
1530a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
1531a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
15328570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana    /**
1533999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina     * @see #addAccount(String, String, String[], Bundle, Activity, AccountManagerCallback, Handler)
1534999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina     * @hide
1535999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina     */
1536999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina    public AccountManagerFuture<Bundle> addAccountAsUser(final String accountType,
1537999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            final String authTokenType, final String[] requiredFeatures,
1538999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            final Bundle addAccountOptions, final Activity activity,
1539999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            AccountManagerCallback<Bundle> callback, Handler handler, final UserHandle userHandle) {
1540999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        if (accountType == null) throw new IllegalArgumentException("accountType is null");
1541999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        if (userHandle == null) throw new IllegalArgumentException("userHandle is null");
1542999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        final Bundle optionsIn = new Bundle();
1543999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        if (addAccountOptions != null) {
1544999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            optionsIn.putAll(addAccountOptions);
1545999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        }
1546999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
1547999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina
1548999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        return new AmsTask(activity, handler, callback) {
15490b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
1550999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            public void doWork() throws RemoteException {
1551999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                mService.addAccountAsUser(mResponse, accountType, authTokenType,
1552999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                        requiredFeatures, activity != null, optionsIn, userHandle.getIdentifier());
1553999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina            }
1554999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina        }.start();
1555999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina    }
1556999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina
155702cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov
1558999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina    /**
155902cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov     * Adds shared accounts from a parent user to a secondary user. Adding the shared account
156067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * doesn't take effect immediately. When the target user starts up, any pending shared accounts
156167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * are attempted to be copied to the target user from the primary via calls to the
156267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * authenticator.
156302cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov     * @param parentUser parent user
156402cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov     * @param user target user
156567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * @hide
156667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     */
156702cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov    public void addSharedAccountsFromParentUser(UserHandle parentUser, UserHandle user) {
156867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani        try {
156902cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov            mService.addSharedAccountsFromParentUser(parentUser.getIdentifier(),
157002cb6e773b323a0d54b21f43460a23f668b7727cFyodor Kupolov                    user.getIdentifier());
157167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani        } catch (RemoteException re) {
1572f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw re.rethrowFromSystemServer();
157367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani        }
157467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani    }
157567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani
157667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani    /**
157775f68ce1bdb443984a9bd9652c3ad944cf782efbXiaohui Chen     * Copies an account from one user to another user.
157822dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera     * @param account the account to copy
157975f68ce1bdb443984a9bd9652c3ad944cf782efbXiaohui Chen     * @param fromUser the user to copy the account from
158075f68ce1bdb443984a9bd9652c3ad944cf782efbXiaohui Chen     * @param toUser the target user
158122dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera     * @param callback Callback to invoke when the request completes,
158222dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera     *     null for no callback
158322dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera     * @param handler {@link Handler} identifying the callback thread,
158422dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera     *     null for the main thread
158522dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera     * @return An {@link AccountManagerFuture} which resolves to a Boolean indicated wether it
158622dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera     * succeeded.
158722dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera     * @hide
158822dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera     */
158922dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera    public AccountManagerFuture<Boolean> copyAccountToUser(
159075f68ce1bdb443984a9bd9652c3ad944cf782efbXiaohui Chen            final Account account, final UserHandle fromUser, final UserHandle toUser,
159122dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera            AccountManagerCallback<Boolean> callback, Handler handler) {
159222dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera        if (account == null) throw new IllegalArgumentException("account is null");
159375f68ce1bdb443984a9bd9652c3ad944cf782efbXiaohui Chen        if (toUser == null || fromUser == null) {
159475f68ce1bdb443984a9bd9652c3ad944cf782efbXiaohui Chen            throw new IllegalArgumentException("fromUser and toUser cannot be null");
159575f68ce1bdb443984a9bd9652c3ad944cf782efbXiaohui Chen        }
159622dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera
159722dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera        return new Future2Task<Boolean>(handler, callback) {
159822dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera            @Override
159922dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera            public void doWork() throws RemoteException {
160022dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera                mService.copyAccountToUser(
160175f68ce1bdb443984a9bd9652c3ad944cf782efbXiaohui Chen                        mResponse, account, fromUser.getIdentifier(), toUser.getIdentifier());
160222dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera            }
160322dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera            @Override
160422dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
160522dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera                if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
160622dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera                    throw new AuthenticatorException("no result in response");
160722dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera                }
160822dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera                return bundle.getBoolean(KEY_BOOLEAN_RESULT);
160922dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera            }
161022dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera        }.start();
161122dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera    }
161222dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera
161322dc3b7ba111e27bce99a7cce966598e7873508cEsteban Talavera    /**
161467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * @hide
161567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * Removes the shared account.
161667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * @param account the account to remove
161767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * @param user the user to remove the account from
161867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * @return
161967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     */
162067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani    public boolean removeSharedAccount(final Account account, UserHandle user) {
162167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani        try {
162267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani            boolean val = mService.removeSharedAccountAsUser(account, user.getIdentifier());
162367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani            return val;
162467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani        } catch (RemoteException re) {
1625f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw re.rethrowFromSystemServer();
162667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani        }
162767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani    }
162867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani
162967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani    /**
163067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * @hide
163167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * @param user
163267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     * @return
163367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani     */
163467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani    public Account[] getSharedAccounts(UserHandle user) {
163567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani        try {
163667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani            return mService.getSharedAccountsAsUser(user.getIdentifier());
163767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani        } catch (RemoteException re) {
1638f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw re.rethrowFromSystemServer();
163967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani        }
164067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani    }
164167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani
164267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani    /**
1643661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Confirms that the user knows the password for an account to make extra
1644661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * sure they are the owner of the account.  The user-entered password can
1645661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * be supplied directly, otherwise the authenticator for this account type
1646661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * prompts the user with the appropriate interface.  This method is
1647661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * intended for applications which want extra assurance; for example, the
1648661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * phone lock screen uses this to let the user unlock the phone with an
1649661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * account password if they forget the lock pattern.
1650661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1651661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>If the user-entered password matches a saved password for this
1652661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * account, the request is considered valid; otherwise the authenticator
1653661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * verifies the password (usually by contacting the server).
1654661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1655661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may be called from any thread, but the returned
1656661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManagerFuture} must not be used on the main thread.
1657661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1658210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1659210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs
1660210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * for this function in API level 22.
1661210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
1662661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param account The account to confirm password knowledge for
1663661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param options Authenticator-specific options for the request;
1664661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     if the {@link #KEY_PASSWORD} string field is present, the
1665661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     authenticator may use it directly rather than prompting the user;
1666661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     may be null or empty
1667661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param activity The {@link Activity} context to use for launching a new
1668661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     authenticator-defined sub-Activity to prompt the user to enter a
1669661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     password; used only to call startActivity(); if null, the prompt
1670661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     will not be launched directly, but the necessary {@link Intent}
1671661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     will be returned to the caller instead
1672661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
1673661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
1674661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
1675661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
1676661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManagerFuture} which resolves to a Bundle
1677661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     with these fields if activity or password was supplied and
1678661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     the account was successfully verified:
1679661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <ul>
16806c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account verified
1681661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
1682661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_BOOLEAN_RESULT} - true to indicate success
1683661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * </ul>
1684661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1685661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * If no activity or password was specified, the returned Bundle contains
16866c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * {@link #KEY_INTENT} with the {@link Intent} needed to launch the
16876c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * password prompt.
16886eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     *
16896c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * <p>Also the returning Bundle may contain {@link
16901663b44cfd5fe589183dae5db769c843870cb5dbSimranjit Singh Kohli     * #KEY_LAST_AUTHENTICATED_TIME} indicating the last time the
16916c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * credential was validated/created.
16926eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     *
16936c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * If an error occurred,{@link AccountManagerFuture#getResult()} throws:
1694756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * <ul>
1695661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link AuthenticatorException} if the authenticator failed to respond
1696661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link OperationCanceledException} if the operation was canceled for
1697661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      any reason, including the user canceling the password prompt
1698661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link IOException} if the authenticator experienced an I/O problem
1699661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      verifying the password, usually because of network trouble
1700756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * </ul>
1701756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1702f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public AccountManagerFuture<Bundle> confirmCredentials(final Account account,
1703f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana            final Bundle options,
1704f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana            final Activity activity,
1705ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            final AccountManagerCallback<Bundle> callback,
1706a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            final Handler handler) {
17072c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani        return confirmCredentialsAsUser(account, options, activity, callback, handler,
17082c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani                Process.myUserHandle());
17092c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani    }
17102c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani
17112c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani    /**
17122c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani     * @hide
17132c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani     * Same as {@link #confirmCredentials(Account, Bundle, Activity, AccountManagerCallback, Handler)}
17142c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani     * but for the specified user.
17152c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani     */
17162c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani    public AccountManagerFuture<Bundle> confirmCredentialsAsUser(final Account account,
17172c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani            final Bundle options,
17182c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani            final Activity activity,
17192c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani            final AccountManagerCallback<Bundle> callback,
17202c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani            final Handler handler, UserHandle userHandle) {
1721382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
17222c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani        final int userId = userHandle.getIdentifier();
1723a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        return new AmsTask(activity, handler, callback) {
17240b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
1725a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            public void doWork() throws RemoteException {
17262c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani                mService.confirmCredentialsAsUser(mResponse, account, options, activity != null,
17272c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani                        userId);
1728a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
17293326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }.start();
1730a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
1731a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
1732756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
1733661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Asks the user to enter a new password for an account, updating the
1734661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * saved credentials for the account.  Normally this happens automatically
1735661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * when the server rejects credentials during an auth token fetch, but this
1736661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * can be invoked directly to ensure we have the correct credentials stored.
1737661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1738661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may be called from any thread, but the returned
1739661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManagerFuture} must not be used on the main thread.
1740661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1741210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1742210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
1743210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
1744210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
1745661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param account The account to update credentials for
1746661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param authTokenType The credentials entered must allow an auth token
1747661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     of this type to be created (but no actual auth token is returned);
1748661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     may be null
1749661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param options Authenticator-specific options for the request;
1750661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     may be null or empty
1751661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param activity The {@link Activity} context to use for launching a new
1752661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     authenticator-defined sub-Activity to prompt the user to enter a
1753661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     password; used only to call startActivity(); if null, the prompt
1754661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     will not be launched directly, but the necessary {@link Intent}
1755661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     will be returned to the caller instead
1756661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
1757661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
1758661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
1759661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
1760661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManagerFuture} which resolves to a Bundle
1761661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     with these fields if an activity was supplied and the account
1762661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     credentials were successfully updated:
1763756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * <ul>
17646cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account
1765661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
1766661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * </ul>
1767661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
17686c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * If no activity was specified, the returned Bundle contains
1769661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link #KEY_INTENT} with the {@link Intent} needed to launch the
17706c7c4ada8b0ce5f7027fd7b87dc8848b42fa5a0cSimranjit Singh Kohli     * password prompt. If an error occurred,
17718e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * {@link AccountManagerFuture#getResult()} throws:
1772661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <ul>
1773661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link AuthenticatorException} if the authenticator failed to respond
1774661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link OperationCanceledException} if the operation was canceled for
1775661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      any reason, including the user canceling the password prompt
1776661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link IOException} if the authenticator experienced an I/O problem
1777661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      verifying the password, usually because of network trouble
1778756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * </ul>
1779756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1780756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    public AccountManagerFuture<Bundle> updateCredentials(final Account account,
1781756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana            final String authTokenType,
178231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana            final Bundle options, final Activity activity,
1783ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            final AccountManagerCallback<Bundle> callback,
1784a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            final Handler handler) {
1785382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (account == null) throw new IllegalArgumentException("account is null");
1786a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        return new AmsTask(activity, handler, callback) {
17870b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
1788a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            public void doWork() throws RemoteException {
1789a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                mService.updateCredentials(mResponse, account, authTokenType, activity != null,
179031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana                        options);
1791a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
17923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }.start();
1793a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
1794a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
1795756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
1796661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Offers the user an opportunity to change an authenticator's settings.
1797661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * These properties are for the authenticator in general, not a particular
1798661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * account.  Not all authenticators support this method.
1799661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1800661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may be called from any thread, but the returned
1801661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManagerFuture} must not be used on the main thread.
1802661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
18036eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * <p>This method requires the caller to have the same signature as the
18046eb73a577850a4b6ddb06fd746f09a6c1d124f34Carlos Valdivia     * authenticator associated with the specified account type.
1805661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
1806210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
1807210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs
1808210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * for this function in API level 22.
1809210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
1810661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param accountType The account type associated with the authenticator
1811661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     to adjust
1812661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param activity The {@link Activity} context to use for launching a new
1813661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     authenticator-defined sub-Activity to adjust authenticator settings;
1814661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     used only to call startActivity(); if null, the settings dialog will
1815661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     not be launched directly, but the necessary {@link Intent} will be
1816661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     returned to the caller instead
1817661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
1818661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
1819661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
1820661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
1821661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManagerFuture} which resolves to a Bundle
1822661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     which is empty if properties were edited successfully, or
1823661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     if no activity was specified, contains only {@link #KEY_INTENT}
1824661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     needed to launch the authenticator's settings dialog.
18258e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     *     If an error occurred, {@link AccountManagerFuture#getResult()}
18268e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     *     throws:
1827756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * <ul>
1828661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link AuthenticatorException} if no authenticator was registered for
1829661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      this account type or the authenticator failed to respond
1830661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link OperationCanceledException} if the operation was canceled for
1831661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      any reason, including the user canceling the settings dialog
1832661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link IOException} if the authenticator experienced an I/O problem
1833661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      updating settings, usually because of network trouble
1834756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * </ul>
1835756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
1836756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    public AccountManagerFuture<Bundle> editProperties(final String accountType,
1837756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana            final Activity activity, final AccountManagerCallback<Bundle> callback,
1838a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            final Handler handler) {
1839382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (accountType == null) throw new IllegalArgumentException("accountType is null");
1840a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        return new AmsTask(activity, handler, callback) {
18410b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
1842a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            public void doWork() throws RemoteException {
1843a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                mService.editProperties(mResponse, accountType, activity != null);
1844a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
18453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }.start();
1846a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
1847a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
184812747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani    /**
184912747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani     * @hide
185012747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani     * Checks if the given account exists on any of the users on the device.
185112747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani     * Only the system process can call this method.
185212747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani     *
185312747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani     * @param account The account to check for existence.
185412747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani     * @return whether any user has this account
185512747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani     */
185612747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani    public boolean someUserHasAccount(@NonNull final Account account) {
185712747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani        try {
185812747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani            return mService.someUserHasAccount(account);
185912747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani        } catch (RemoteException re) {
1860f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw re.rethrowFromSystemServer();
186112747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani        }
186212747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani    }
186312747879b0204b9dfee997eddc981d09289e8b77Amith Yamasani
1864a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    private void ensureNotOnMainThread() {
1865a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        final Looper looper = Looper.myLooper();
1866a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        if (looper != null && looper == mContext.getMainLooper()) {
186753bd2522ca7767f46646606123b6e2689b811850Fred Quintana            final IllegalStateException exception = new IllegalStateException(
186853bd2522ca7767f46646606123b6e2689b811850Fred Quintana                    "calling this from your main thread can lead to deadlock");
186953bd2522ca7767f46646606123b6e2689b811850Fred Quintana            Log.e(TAG, "calling this from your main thread can lead to deadlock and/or ANRs",
187053bd2522ca7767f46646606123b6e2689b811850Fred Quintana                    exception);
1871751fdc09bb7ab0ce6feac7b7a823e38ed858feb0Fred Quintana            if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.FROYO) {
1872751fdc09bb7ab0ce6feac7b7a823e38ed858feb0Fred Quintana                throw exception;
1873751fdc09bb7ab0ce6feac7b7a823e38ed858feb0Fred Quintana            }
1874a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        }
1875a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
1876a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
1877ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    private void postToHandler(Handler handler, final AccountManagerCallback<Bundle> callback,
1878ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            final AccountManagerFuture<Bundle> future) {
1879d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        handler = handler == null ? mMainHandler : handler;
1880d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        handler.post(new Runnable() {
18810b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
1882a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            public void run() {
1883a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                callback.run(future);
1884a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
1885a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        });
1886603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
1887603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
1888f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    private void postToHandler(Handler handler, final OnAccountsUpdateListener listener,
1889d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            final Account[] accounts) {
1890ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        final Account[] accountsCopy = new Account[accounts.length];
1891ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        // send a copy to make sure that one doesn't
1892ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        // change what another sees
1893ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length);
1894ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        handler = (handler == null) ? mMainHandler : handler;
1895d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        handler.post(new Runnable() {
18960b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
1897a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            public void run() {
1898b6437245c280596d0a580b8d67189739cf793250Costin Manolache                try {
1899b6437245c280596d0a580b8d67189739cf793250Costin Manolache                    listener.onAccountsUpdated(accountsCopy);
1900b6437245c280596d0a580b8d67189739cf793250Costin Manolache                } catch (SQLException e) {
1901b6437245c280596d0a580b8d67189739cf793250Costin Manolache                    // Better luck next time.  If the problem was disk-full,
1902b6437245c280596d0a580b8d67189739cf793250Costin Manolache                    // the STORAGE_OK intent will re-trigger the update.
1903b6437245c280596d0a580b8d67189739cf793250Costin Manolache                    Log.e(TAG, "Can't update accounts", e);
1904b6437245c280596d0a580b8d67189739cf793250Costin Manolache                }
1905a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
1906a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        });
1907a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    }
1908a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
1909ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> {
1910a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        final IAccountManagerResponse mResponse;
1911a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        final Handler mHandler;
1912ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        final AccountManagerCallback<Bundle> mCallback;
1913a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        final Activity mActivity;
1914ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) {
1915a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            super(new Callable<Bundle>() {
19160b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                @Override
1917a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                public Bundle call() throws Exception {
1918a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw new IllegalStateException("this should never be called");
1919a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                }
1920a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            });
1921a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
1922a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            mHandler = handler;
1923a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            mCallback = callback;
1924a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            mActivity = activity;
1925a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            mResponse = new Response();
19263326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }
19273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana
1928ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public final AccountManagerFuture<Bundle> start() {
1929ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            try {
1930ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                doWork();
1931ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            } catch (RemoteException e) {
1932ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                setException(e);
1933ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            }
19343326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            return this;
1935a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        }
1936a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
19370b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
193896580e00654a052a82120c374c6b5961ef349a92Fred Quintana        protected void set(Bundle bundle) {
193996580e00654a052a82120c374c6b5961ef349a92Fred Quintana            // TODO: somehow a null is being set as the result of the Future. Log this
194096580e00654a052a82120c374c6b5961ef349a92Fred Quintana            // case to help debug where this is occurring. When this bug is fixed this
194196580e00654a052a82120c374c6b5961ef349a92Fred Quintana            // condition statement should be removed.
194296580e00654a052a82120c374c6b5961ef349a92Fred Quintana            if (bundle == null) {
194396580e00654a052a82120c374c6b5961ef349a92Fred Quintana                Log.e(TAG, "the bundle must not be null", new Exception());
194496580e00654a052a82120c374c6b5961ef349a92Fred Quintana            }
194596580e00654a052a82120c374c6b5961ef349a92Fred Quintana            super.set(bundle);
194696580e00654a052a82120c374c6b5961ef349a92Fred Quintana        }
194796580e00654a052a82120c374c6b5961ef349a92Fred Quintana
1948a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        public abstract void doWork() throws RemoteException;
1949603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
1950a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        private Bundle internalGetResult(Long timeout, TimeUnit unit)
1951a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                throws OperationCanceledException, IOException, AuthenticatorException {
195253bd2522ca7767f46646606123b6e2689b811850Fred Quintana            if (!isDone()) {
195353bd2522ca7767f46646606123b6e2689b811850Fred Quintana                ensureNotOnMainThread();
195453bd2522ca7767f46646606123b6e2689b811850Fred Quintana            }
1955a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            try {
1956a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                if (timeout == null) {
1957a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    return get();
1958a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else {
1959a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    return get(timeout, unit);
1960a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                }
1961a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } catch (CancellationException e) {
1962a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                throw new OperationCanceledException();
1963a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } catch (TimeoutException e) {
1964a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                // fall through and cancel
1965a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } catch (InterruptedException e) {
1966a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                // fall through and cancel
1967a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } catch (ExecutionException e) {
1968a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                final Throwable cause = e.getCause();
1969a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                if (cause instanceof IOException) {
1970a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw (IOException) cause;
1971a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else if (cause instanceof UnsupportedOperationException) {
1972a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw new AuthenticatorException(cause);
1973a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else if (cause instanceof AuthenticatorException) {
1974a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw (AuthenticatorException) cause;
1975a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else if (cause instanceof RuntimeException) {
1976a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw (RuntimeException) cause;
1977a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else if (cause instanceof Error) {
1978a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw (Error) cause;
1979a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else {
1980a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw new IllegalStateException(cause);
1981a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                }
1982a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } finally {
1983a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                cancel(true /* interrupt if running */);
1984603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana            }
1985a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            throw new OperationCanceledException();
1986603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
1987603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
19880b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
1989a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        public Bundle getResult()
1990a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                throws OperationCanceledException, IOException, AuthenticatorException {
1991a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            return internalGetResult(null, null);
1992603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
1993603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
19940b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
1995a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        public Bundle getResult(long timeout, TimeUnit unit)
1996a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                throws OperationCanceledException, IOException, AuthenticatorException {
1997a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            return internalGetResult(timeout, unit);
1998603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
1999603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
20000b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
2001a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        protected void done() {
2002a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            if (mCallback != null) {
2003a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                postToHandler(mHandler, mCallback, this);
2004a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
2005a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        }
2006a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
2007a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        /** Handles the responses from the AccountManager */
2008a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        private class Response extends IAccountManagerResponse.Stub {
20090b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
2010a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            public void onResult(Bundle bundle) {
201146703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom                Intent intent = bundle.getParcelable(KEY_INTENT);
2012a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                if (intent != null && mActivity != null) {
2013a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    // since the user provided an Activity we will silently start intents
2014a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    // that we see
2015a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    mActivity.startActivity(intent);
2016a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    // leave the Future running to wait for the real response to this request
2017d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana                } else if (bundle.getBoolean("retry")) {
2018d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana                    try {
2019d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana                        doWork();
2020d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana                    } catch (RemoteException e) {
2021f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                        throw e.rethrowFromSystemServer();
2022d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana                    }
2023a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else {
2024a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    set(bundle);
2025a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                }
2026a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
2027a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
20280b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
2029a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            public void onError(int code, String message) {
2030999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED
2031999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                        || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) {
2032999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                    // the authenticator indicated that this request was canceled or we were
2033999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                    // forbidden to fulfill; cancel now
2034a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    cancel(true /* mayInterruptIfRunning */);
2035a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    return;
2036a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                }
2037a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                setException(convertErrorToException(code, message));
2038a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
2039603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
2040a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
2041603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
2042603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
2043ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    private abstract class BaseFutureTask<T> extends FutureTask<T> {
2044ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        final public IAccountManagerResponse mResponse;
2045a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        final Handler mHandler;
2046ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana
2047ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public BaseFutureTask(Handler handler) {
2048ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            super(new Callable<T>() {
20490b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                @Override
2050ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                public T call() throws Exception {
2051a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw new IllegalStateException("this should never be called");
2052a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                }
2053a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            });
2054a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            mHandler = handler;
2055ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            mResponse = new Response();
2056ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        }
2057a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
2058ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public abstract void doWork() throws RemoteException;
2059ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana
2060ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public abstract T bundleToResult(Bundle bundle) throws AuthenticatorException;
2061ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana
2062ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        protected void postRunnableToHandler(Runnable runnable) {
2063ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            Handler handler = (mHandler == null) ? mMainHandler : mHandler;
2064ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            handler.post(runnable);
2065ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        }
2066ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana
2067ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        protected void startTask() {
2068ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            try {
2069ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                doWork();
2070ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            } catch (RemoteException e) {
2071ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                setException(e);
2072ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            }
2073ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        }
2074ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana
2075ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        protected class Response extends IAccountManagerResponse.Stub {
20760b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
2077ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            public void onResult(Bundle bundle) {
2078ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                try {
2079ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    T result = bundleToResult(bundle);
2080ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    if (result == null) {
2081ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                        return;
2082a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    }
2083ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    set(result);
2084ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    return;
2085ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                } catch (ClassCastException e) {
2086ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    // we will set the exception below
2087ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                } catch (AuthenticatorException e) {
2088ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    // we will set the exception below
2089a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                }
2090f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                onError(ERROR_CODE_INVALID_RESPONSE, "no result in response");
2091ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            }
2092a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
20930b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
2094ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            public void onError(int code, String message) {
2095999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED
2096999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                        || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) {
2097999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                    // the authenticator indicated that this request was canceled or we were
2098999d394adee533c55fce38bd632ffd4f1af91362Alexandra Gherghina                    // forbidden to fulfill; cancel now
2099ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    cancel(true /* mayInterruptIfRunning */);
2100ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    return;
2101ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                }
2102ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                setException(convertErrorToException(code, message));
2103ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            }
2104ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        }
2105ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    }
2106a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
2107ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    private abstract class Future2Task<T>
2108ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            extends BaseFutureTask<T> implements AccountManagerFuture<T> {
2109ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        final AccountManagerCallback<T> mCallback;
2110ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public Future2Task(Handler handler, AccountManagerCallback<T> callback) {
2111ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            super(handler);
2112ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            mCallback = callback;
2113ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        }
2114a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
21150b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
2116a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        protected void done() {
2117a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            if (mCallback != null) {
2118ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                postRunnableToHandler(new Runnable() {
21190b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                    @Override
2120ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    public void run() {
2121ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                        mCallback.run(Future2Task.this);
2122ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    }
2123ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                });
2124a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
2125a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        }
2126a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
2127ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public Future2Task<T> start() {
2128ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            startTask();
2129ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            return this;
2130ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        }
2131ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana
2132ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        private T internalGetResult(Long timeout, TimeUnit unit)
2133ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                throws OperationCanceledException, IOException, AuthenticatorException {
213453bd2522ca7767f46646606123b6e2689b811850Fred Quintana            if (!isDone()) {
213553bd2522ca7767f46646606123b6e2689b811850Fred Quintana                ensureNotOnMainThread();
213653bd2522ca7767f46646606123b6e2689b811850Fred Quintana            }
2137a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            try {
2138a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                if (timeout == null) {
2139a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    return get();
2140a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else {
2141a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    return get(timeout, unit);
2142a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                }
2143a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } catch (InterruptedException e) {
2144a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                // fall through and cancel
2145a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } catch (TimeoutException e) {
2146a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                // fall through and cancel
2147a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } catch (CancellationException e) {
2148ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                // fall through and cancel
2149a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } catch (ExecutionException e) {
2150a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                final Throwable cause = e.getCause();
2151a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                if (cause instanceof IOException) {
2152ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    throw (IOException) cause;
2153a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else if (cause instanceof UnsupportedOperationException) {
2154ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    throw new AuthenticatorException(cause);
2155a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else if (cause instanceof AuthenticatorException) {
2156ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    throw (AuthenticatorException) cause;
2157a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else if (cause instanceof RuntimeException) {
2158a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw (RuntimeException) cause;
2159a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else if (cause instanceof Error) {
2160a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw (Error) cause;
2161a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                } else {
2162a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                    throw new IllegalStateException(cause);
2163a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                }
2164a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            } finally {
2165a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana                cancel(true /* interrupt if running */);
2166a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            }
2167ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            throw new OperationCanceledException();
2168a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        }
2169a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
21700b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
2171ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public T getResult()
2172ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                throws OperationCanceledException, IOException, AuthenticatorException {
2173a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            return internalGetResult(null, null);
2174603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
2175a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
21760b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
2177ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public T getResult(long timeout, TimeUnit unit)
2178ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                throws OperationCanceledException, IOException, AuthenticatorException {
2179a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            return internalGetResult(timeout, unit);
2180a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        }
2181a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
2182603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
2183603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana
2184a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana    private Exception convertErrorToException(int code, String message) {
2185f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana        if (code == ERROR_CODE_NETWORK_ERROR) {
2186a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana            return new IOException(message);
2187603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana        }
2188a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
2189f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana        if (code == ERROR_CODE_UNSUPPORTED_OPERATION) {
21903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            return new UnsupportedOperationException(message);
2191a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        }
2192a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
2193f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana        if (code == ERROR_CODE_INVALID_RESPONSE) {
21943326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            return new AuthenticatorException(message);
21953326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }
21963326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana
2197f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana        if (code == ERROR_CODE_BAD_ARGUMENTS) {
21983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            return new IllegalArgumentException(message);
21993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }
22003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana
22013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        return new AuthenticatorException(message);
22023326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana    }
22033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana
2204ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana    private class GetAuthTokenByTypeAndFeaturesTask
2205ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            extends AmsTask implements AccountManagerCallback<Bundle> {
22063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        GetAuthTokenByTypeAndFeaturesTask(final String accountType, final String authTokenType,
22073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana                final String[] features, Activity activityForPrompting,
22083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana                final Bundle addAccountOptions, final Bundle loginOptions,
2209ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                AccountManagerCallback<Bundle> callback, Handler handler) {
22103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            super(activityForPrompting, handler, callback);
22113326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            if (accountType == null) throw new IllegalArgumentException("account type is null");
22123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            mAccountType = accountType;
22133326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            mAuthTokenType = authTokenType;
22143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            mFeatures = features;
22153326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            mAddAccountOptions = addAccountOptions;
22163326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            mLoginOptions = loginOptions;
22173326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            mMyCallback = this;
22183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }
2219ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        volatile AccountManagerFuture<Bundle> mFuture = null;
22203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        final String mAccountType;
22213326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        final String mAuthTokenType;
22223326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        final String[] mFeatures;
22233326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        final Bundle mAddAccountOptions;
22243326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        final Bundle mLoginOptions;
2225ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        final AccountManagerCallback<Bundle> mMyCallback;
2226f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana        private volatile int mNumAccounts = 0;
22273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana
22280b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
22293326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        public void doWork() throws RemoteException {
2230ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            getAccountsByTypeAndFeatures(mAccountType, mFeatures,
2231ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    new AccountManagerCallback<Account[]>() {
22320b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                        @Override
2233ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                        public void run(AccountManagerFuture<Account[]> future) {
2234ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                            Account[] accounts;
22353326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana                            try {
2236ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                accounts = future.getResult();
2237ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                            } catch (OperationCanceledException e) {
2238ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                setException(e);
2239ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                return;
2240ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                            } catch (IOException e) {
2241ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                setException(e);
2242ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                return;
2243ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                            } catch (AuthenticatorException e) {
2244ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                setException(e);
2245ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                return;
22463326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana                            }
2247ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana
2248f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                            mNumAccounts = accounts.length;
2249f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana
2250ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                            if (accounts.length == 0) {
2251ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                if (mActivity != null) {
2252ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    // no accounts, add one now. pretend that the user directly
2253ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    // made this request
2254ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    mFuture = addAccount(mAccountType, mAuthTokenType, mFeatures,
2255ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                            mAddAccountOptions, mActivity, mMyCallback, mHandler);
2256ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                } else {
2257ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    // send result since we can't prompt to add an account
2258ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    Bundle result = new Bundle();
2259f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                                    result.putString(KEY_ACCOUNT_NAME, null);
2260f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                                    result.putString(KEY_ACCOUNT_TYPE, null);
2261f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                                    result.putString(KEY_AUTHTOKEN, null);
2262ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    try {
2263ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                        mResponse.onResult(result);
2264ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    } catch (RemoteException e) {
2265ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                        // this will never happen
2266ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    }
2267ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    // we are done
2268ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                }
2269ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                            } else if (accounts.length == 1) {
2270ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                // have a single account, return an authtoken for it
2271ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                if (mActivity == null) {
2272ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    mFuture = getAuthToken(accounts[0], mAuthTokenType,
2273ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                            false /* notifyAuthFailure */, mMyCallback, mHandler);
2274ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                } else {
2275ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    mFuture = getAuthToken(accounts[0],
2276ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                            mAuthTokenType, mLoginOptions,
22773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana                                            mActivity, mMyCallback, mHandler);
22783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana                                }
2279ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                            } else {
2280ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                if (mActivity != null) {
2281ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    IAccountManagerResponse chooseResponse =
2282ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                            new IAccountManagerResponse.Stub() {
22830b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                                        @Override
2284ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                        public void onResult(Bundle value) throws RemoteException {
2285ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                            Account account = new Account(
2286f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                                                    value.getString(KEY_ACCOUNT_NAME),
2287f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                                                    value.getString(KEY_ACCOUNT_TYPE));
2288ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                            mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions,
2289ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                                    mActivity, mMyCallback, mHandler);
2290ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                        }
2291ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana
22920b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                                        @Override
2293ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                        public void onError(int errorCode, String errorMessage)
2294ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                                throws RemoteException {
2295ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                            mResponse.onError(errorCode, errorMessage);
2296ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                        }
2297ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    };
2298ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    // have many accounts, launch the chooser
2299ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    Intent intent = new Intent();
230012b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasani                                    ComponentName componentName = ComponentName.unflattenFromString(
230112b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasani                                            Resources.getSystem().getString(
230212b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasani                                                    R.string.config_chooseAccountActivity));
230312b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasani                                    intent.setClassName(componentName.getPackageName(),
230412b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasani                                            componentName.getClassName());
2305f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                                    intent.putExtra(KEY_ACCOUNTS, accounts);
2306f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                                    intent.putExtra(KEY_ACCOUNT_MANAGER_RESPONSE,
2307ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                            new AccountManagerResponse(chooseResponse));
2308ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    mActivity.startActivity(intent);
2309ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    // the result will arrive via the IAccountManagerResponse
2310ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                } else {
2311ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    // send result since we can't prompt to select an account
2312ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    Bundle result = new Bundle();
2313f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                                    result.putString(KEY_ACCOUNTS, null);
2314ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    try {
2315ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                        mResponse.onResult(result);
2316ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    } catch (RemoteException e) {
2317ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                        // this will never happen
2318ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    }
2319ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                                    // we are done
23203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana                                }
23213326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana                            }
2322ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                        }}, mHandler);
23233326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        }
23243326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana
23250b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
2326ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana        public void run(AccountManagerFuture<Bundle> future) {
23273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            try {
2328f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                final Bundle result = future.getResult();
2329f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                if (mNumAccounts == 0) {
2330f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                    final String accountName = result.getString(KEY_ACCOUNT_NAME);
2331f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                    final String accountType = result.getString(KEY_ACCOUNT_TYPE);
2332f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                    if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
2333f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                        setException(new AuthenticatorException("account not in result"));
2334f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                        return;
2335f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                    }
2336f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                    final Account account = new Account(accountName, accountType);
2337f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                    mNumAccounts = 1;
2338f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                    getAuthToken(account, mAuthTokenType, null /* options */, mActivity,
2339f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                            mMyCallback, mHandler);
2340f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                    return;
2341f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                }
2342f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana                set(result);
2343f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana            } catch (OperationCanceledException e) {
2344f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                cancel(true /* mayInterruptIfRUnning */);
2345f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana            } catch (IOException e) {
2346f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                setException(e);
2347f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana            } catch (AuthenticatorException e) {
2348f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                setException(e);
23493326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            }
2350a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana        }
23513326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana    }
2352a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana
2353756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana    /**
2354661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * This convenience helper combines the functionality of
2355661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link #getAccountsByTypeAndFeatures}, {@link #getAuthToken}, and
2356661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link #addAccount}.
2357661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
2358661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method gets a list of the accounts matching the
2359661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * specified type and feature set; if there is exactly one, it is
2360661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * used; if there are more than one, the user is prompted to pick one;
2361661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * if there are none, the user is prompted to add one.  Finally,
2362661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * an auth token is acquired for the chosen account.
2363661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
2364661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>This method may be called from any thread, but the returned
2365661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManagerFuture} must not be used on the main thread.
2366661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
2367210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
2368210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
2369210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     * this function in API level 22.
2370210baceaa1843f789dec4c60e3d78f7ac7b415afSimranjit Singh Kohli     *
2371661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param accountType The account type required
2372ff592dc2fa53d48e4121d9b8fd70efc19938c4a1Doug Zongker     *     (see {@link #getAccountsByType}), must not be null
2373661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param authTokenType The desired auth token type
2374661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     (see {@link #getAuthToken}), must not be null
2375661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param features Required features for the account
2376661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     (see {@link #getAccountsByTypeAndFeatures}), may be null or empty
2377661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param activity The {@link Activity} context to use for launching new
2378661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     sub-Activities to prompt to add an account, select an account,
2379661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     and/or enter a password, as necessary; used only to call
2380661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     startActivity(); should not be null
2381661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param addAccountOptions Authenticator-specific options to use for
2382661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     adding new accounts; may be null or empty
2383661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param getAuthTokenOptions Authenticator-specific options to use for
2384661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     getting auth tokens; may be null or empty
2385661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param callback Callback to invoke when the request completes,
2386661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for no callback
2387661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the callback thread,
2388661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     null for the main thread
2389661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @return An {@link AccountManagerFuture} which resolves to a Bundle with
2390661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     at least the following fields:
2391756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * <ul>
2392661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account
2393661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
2394661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link #KEY_AUTHTOKEN} - the auth token you wanted
2395661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * </ul>
2396661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
23978e4378b3ae7c3b343f92b8f7fb8e46bdfdb01649Dan Egnor     * If an error occurred, {@link AccountManagerFuture#getResult()} throws:
2398661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <ul>
2399661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link AuthenticatorException} if no authenticator was registered for
2400661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      this account type or the authenticator failed to respond
2401661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link OperationCanceledException} if the operation was canceled for
2402661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      any reason, including the user canceling any operation
2403661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <li> {@link IOException} if the authenticator experienced an I/O problem
2404661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *      updating settings, usually because of network trouble
2405756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     * </ul>
2406756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana     */
2407f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public AccountManagerFuture<Bundle> getAuthTokenByFeatures(
24083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana            final String accountType, final String authTokenType, final String[] features,
2409661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor            final Activity activity, final Bundle addAccountOptions,
241031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana            final Bundle getAuthTokenOptions,
2411ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            final AccountManagerCallback<Bundle> callback, final Handler handler) {
24123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        if (accountType == null) throw new IllegalArgumentException("account type is null");
24133326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana        if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
2414f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana        final GetAuthTokenByTypeAndFeaturesTask task =
2415f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                new GetAuthTokenByTypeAndFeaturesTask(accountType, authTokenType, features,
2416661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor                activity, addAccountOptions, getAuthTokenOptions, callback, handler);
2417f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana        task.start();
2418f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana        return task;
2419603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana    }
2420d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana
24211121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    /**
2422a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * Deprecated in favor of {@link #newChooseAccountIntent(Account, List, String[], String,
2423a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * String, String[], Bundle)}.
2424a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     *
24251121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * Returns an intent to an {@link Activity} that prompts the user to choose from a list of
24261121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * accounts.
24271121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * The caller will then typically start the activity by calling
2428ab249e08db1f7ce88e039fa4baad9424b42404c1Mark Fickett     * <code>startActivityForResult(intent, ...);</code>.
24291121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * <p>
24301121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * On success the activity returns a Bundle with the account name and type specified using
24311121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * keys {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE}.
24321121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * <p>
24331121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * The most common case is to call this with one account type, e.g.:
24341121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * <p>
2435f783ce5bcfa85a260196d27fb9feabfc4fbd4b46kmccormick     * <pre>  newChooseAccountIntent(null, null, new String[]{"com.google"}, false, null,
2436d88324d8ab8b98bbc2c21551be3a8981ee431181Fred Quintana     * null, null, null);</pre>
24371121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * @param selectedAccount if specified, indicates that the {@link Account} is the currently
24381121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * selected one, according to the caller's definition of selected.
2439a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @param allowableAccounts an optional {@link List} of accounts that are allowed to be
24401121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * shown. If not specified then this field will not limit the displayed accounts.
24411121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * @param allowableAccountTypes an optional string array of account types. These are used
24421121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     * both to filter the shown accounts and to filter the list of account types that are shown
2443734f8fb69d0c8af7b10bded718897a55ced49bf0Simranjit Singh Kohli     * when adding an account. If not specified then this field will not limit the displayed
2444734f8fb69d0c8af7b10bded718897a55ced49bf0Simranjit Singh Kohli     * account types when adding an account.
2445a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @param alwaysPromptForAccount boolean that is ignored.
2446d88324d8ab8b98bbc2c21551be3a8981ee431181Fred Quintana     * @param descriptionOverrideText if non-null this string is used as the description in the
2447b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana     * accounts chooser screen rather than the default
2448d88324d8ab8b98bbc2c21551be3a8981ee431181Fred Quintana     * @param addAccountAuthTokenType this string is passed as the {@link #addAccount}
2449d88324d8ab8b98bbc2c21551be3a8981ee431181Fred Quintana     * authTokenType parameter
2450d88324d8ab8b98bbc2c21551be3a8981ee431181Fred Quintana     * @param addAccountRequiredFeatures this string array is passed as the {@link #addAccount}
2451d88324d8ab8b98bbc2c21551be3a8981ee431181Fred Quintana     * requiredFeatures parameter
2452b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana     * @param addAccountOptions This {@link Bundle} is passed as the {@link #addAccount} options
2453d88324d8ab8b98bbc2c21551be3a8981ee431181Fred Quintana     * parameter
2454b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana     * @return an {@link Intent} that can be used to launch the ChooseAccount activity flow.
24551121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana     */
2456a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia    @Deprecated
2457a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia    static public Intent newChooseAccountIntent(
2458a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia            Account selectedAccount,
2459f2d248db8078e716b809e0a17cacdea5c5609bd5Baligh Uddin            ArrayList<Account> allowableAccounts,
24601121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            String[] allowableAccountTypes,
2461b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana            boolean alwaysPromptForAccount,
2462b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana            String descriptionOverrideText,
2463b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana            String addAccountAuthTokenType,
2464b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana            String[] addAccountRequiredFeatures,
24651121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            Bundle addAccountOptions) {
2466a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia        return newChooseAccountIntent(
2467a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia                selectedAccount,
2468a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia                allowableAccounts,
2469a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia                allowableAccountTypes,
2470a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia                descriptionOverrideText,
2471a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia                addAccountAuthTokenType,
2472a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia                addAccountRequiredFeatures,
2473a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia                addAccountOptions);
2474a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia    }
2475a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia
2476a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia    /**
2477a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * Returns an intent to an {@link Activity} that prompts the user to choose from a list of
2478a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * accounts.
2479a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * The caller will then typically start the activity by calling
2480a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * <code>startActivityForResult(intent, ...);</code>.
2481a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * <p>
2482a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * On success the activity returns a Bundle with the account name and type specified using
2483a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * keys {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE}.
2484a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * <p>
2485a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * The most common case is to call this with one account type, e.g.:
2486a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * <p>
2487a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * <pre>  newChooseAccountIntent(null, null, new String[]{"com.google"}, null, null, null,
2488a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * null);</pre>
2489a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @param selectedAccount if specified, indicates that the {@link Account} is the currently
2490a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * selected one, according to the caller's definition of selected.
2491a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @param allowableAccounts an optional {@link List} of accounts that are allowed to be
2492a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * shown. If not specified then this field will not limit the displayed accounts.
2493a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @param allowableAccountTypes an optional string array of account types. These are used
2494a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * both to filter the shown accounts and to filter the list of account types that are shown
2495a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * when adding an account. If not specified then this field will not limit the displayed
2496a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * account types when adding an account.
2497a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @param descriptionOverrideText if non-null this string is used as the description in the
2498a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * accounts chooser screen rather than the default
2499a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @param addAccountAuthTokenType this string is passed as the {@link #addAccount}
2500a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * authTokenType parameter
2501a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @param addAccountRequiredFeatures this string array is passed as the {@link #addAccount}
2502a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * requiredFeatures parameter
2503a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @param addAccountOptions This {@link Bundle} is passed as the {@link #addAccount} options
2504a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * parameter
2505a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     * @return an {@link Intent} that can be used to launch the ChooseAccount activity flow.
2506a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia     */
2507a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia    static public Intent newChooseAccountIntent(
2508a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia            Account selectedAccount,
2509a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia            List<Account> allowableAccounts,
2510a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia            String[] allowableAccountTypes,
2511a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia            String descriptionOverrideText,
2512a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia            String addAccountAuthTokenType,
2513a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia            String[] addAccountRequiredFeatures,
2514a3db8acf3d05d66162834cca3129792aa571bccaCarlos Valdivia            Bundle addAccountOptions) {
25151121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        Intent intent = new Intent();
251612b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasani        ComponentName componentName = ComponentName.unflattenFromString(
251712b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasani                Resources.getSystem().getString(R.string.config_chooseTypeAndAccountActivity));
251812b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasani        intent.setClassName(componentName.getPackageName(),
251912b8e134c1c98d7eb90510fb79cc25dcf56b2cb0Amith Yamasani                componentName.getClassName());
25201121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNTS_ARRAYLIST,
25213c9c71d36e9eb6c88065fe064a15881e62c29268Craig Lafayette                allowableAccounts == null ? null : new ArrayList<Account>(allowableAccounts));
2522b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana        intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY,
2523b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana                allowableAccountTypes);
25241121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE,
25251121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                addAccountOptions);
25261121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_SELECTED_ACCOUNT, selectedAccount);
2527b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana        intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_DESCRIPTION_TEXT_OVERRIDE,
2528b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana                descriptionOverrideText);
2529b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana        intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING,
2530b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana                addAccountAuthTokenType);
2531b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana        intent.putExtra(
2532b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana                ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY,
2533b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana                addAccountRequiredFeatures);
25341121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        return intent;
25351121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
25361121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
2537f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    private final HashMap<OnAccountsUpdateListener, Handler> mAccountsUpdatedListeners =
2538d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            Maps.newHashMap();
2539d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana
2540d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana    /**
2541d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     * BroadcastReceiver that listens for the LOGIN_ACCOUNTS_CHANGED_ACTION intent
2542d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     * so that it can read the updated list of accounts and send them to the listener
2543d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     * in mAccountsUpdatedListeners.
2544d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     */
2545d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana    private final BroadcastReceiver mAccountsChangedBroadcastReceiver = new BroadcastReceiver() {
25460b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        @Override
2547d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        public void onReceive(final Context context, final Intent intent) {
2548ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            final Account[] accounts = getAccounts();
2549ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            // send the result to the listeners
2550ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            synchronized (mAccountsUpdatedListeners) {
2551f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                for (Map.Entry<OnAccountsUpdateListener, Handler> entry :
2552ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                        mAccountsUpdatedListeners.entrySet()) {
2553ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    postToHandler(entry.getValue(), entry.getKey(), accounts);
2554d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana                }
2555ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            }
2556d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        }
2557d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana    };
2558d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana
2559d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana    /**
2560661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Adds an {@link OnAccountsUpdateListener} to this instance of the
2561661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link AccountManager}.  This listener will be notified whenever the
2562661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * list of accounts on the device changes.
2563661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
2564661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>As long as this listener is present, the AccountManager instance
2565661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * will not be garbage-collected, and neither will the {@link Context}
2566661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * used to retrieve it, which may be a large Activity instance.  To avoid
2567661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * memory leaks, you must remove this listener before then.  Normally
2568661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * listeners are added in an Activity or Service's {@link Activity#onCreate}
2569661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * and removed in {@link Activity#onDestroy}.
2570661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
25716cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz     * <p>The listener will only be informed of accounts that would be returned
25726cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz     * to the caller via {@link #getAccounts()}. Typically this means that to
25736cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz     * get any accounts, the caller will need to be grated the GET_ACCOUNTS
25746cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz     * permission.
2575661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
25766cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz     * <p>It is safe to call this method from the main thread.
2577845d14db9066c3262f270237b52e315aa71508b2Ian Pedowitz     *
2578661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param listener The listener to send notifications to
2579661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param handler {@link Handler} identifying the thread to use
2580661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     for notifications, null for the main thread
2581661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param updateImmediately If true, the listener will be invoked
2582661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *     (on the handler thread) right away with the current account list
2583d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     * @throws IllegalArgumentException if listener is null
2584d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     * @throws IllegalStateException if listener was already added
2585d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     */
258680b530afdb3c19bb664e0ff8c2b650de917305d2Tor Norbye    @RequiresPermission(GET_ACCOUNTS)
2587f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public void addOnAccountsUpdatedListener(final OnAccountsUpdateListener listener,
2588d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            Handler handler, boolean updateImmediately) {
2589d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        if (listener == null) {
2590d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            throw new IllegalArgumentException("the listener is null");
2591d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        }
2592d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        synchronized (mAccountsUpdatedListeners) {
2593d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            if (mAccountsUpdatedListeners.containsKey(listener)) {
2594d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana                throw new IllegalStateException("this listener is already added");
2595d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            }
2596d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            final boolean wasEmpty = mAccountsUpdatedListeners.isEmpty();
2597d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana
2598d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            mAccountsUpdatedListeners.put(listener, handler);
2599d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana
2600d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            if (wasEmpty) {
2601d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana                // Register a broadcast receiver to monitor account changes
2602d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana                IntentFilter intentFilter = new IntentFilter();
2603f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana                intentFilter.addAction(LOGIN_ACCOUNTS_CHANGED_ACTION);
2604b6437245c280596d0a580b8d67189739cf793250Costin Manolache                // To recover from disk-full.
2605c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana                intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
2606d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana                mContext.registerReceiver(mAccountsChangedBroadcastReceiver, intentFilter);
2607d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            }
2608d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        }
2609d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana
2610d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        if (updateImmediately) {
2611ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            postToHandler(handler, listener, getAccounts());
2612d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        }
2613d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana    }
2614d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana
2615d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana    /**
2616661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * Removes an {@link OnAccountsUpdateListener} previously registered with
2617661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * {@link #addOnAccountsUpdatedListener}.  The listener will no longer
2618661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * receive notifications of account changes.
2619661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
2620661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>It is safe to call this method from the main thread.
2621661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
2622661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * <p>No permission is required to call this method.
2623661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     *
2624661f0130de6a4e1592b679a212c8f758133d36eeDan Egnor     * @param listener The previously added listener to remove
2625d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     * @throws IllegalArgumentException if listener is null
2626d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     * @throws IllegalStateException if listener was not already added
2627d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana     */
2628f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana    public void removeOnAccountsUpdatedListener(OnAccountsUpdateListener listener) {
2629382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana        if (listener == null) throw new IllegalArgumentException("listener is null");
2630d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        synchronized (mAccountsUpdatedListeners) {
26315be61f5b3ad61706b72c1f6b00914ab042dc6bedBryan Mawhinney            if (!mAccountsUpdatedListeners.containsKey(listener)) {
263288a211b148dd94df1f178338c94fdd7d01f53863Costin Manolache                Log.e(TAG, "Listener was not previously added");
263388a211b148dd94df1f178338c94fdd7d01f53863Costin Manolache                return;
2634d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            }
26355be61f5b3ad61706b72c1f6b00914ab042dc6bedBryan Mawhinney            mAccountsUpdatedListeners.remove(listener);
2636d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            if (mAccountsUpdatedListeners.isEmpty()) {
2637d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana                mContext.unregisterReceiver(mAccountsChangedBroadcastReceiver);
2638d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana            }
2639d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        }
2640d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana    }
26417881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan
26427881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan    /**
26437881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * Asks the user to authenticate with an account of a specified type. The
26447881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * authenticator for this account type processes this request with the
26457881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * appropriate user interface. If the user does elect to authenticate with a
26467881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * new account, a bundle of session data for installing the account later is
26477881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * returned with optional account password and account status token.
26487881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * <p>
26497881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * This method may be called from any thread, but the returned
26507881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * {@link AccountManagerFuture} must not be used on the main thread.
26517881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * <p>
26527881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * <p>
26537881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * <b>NOTE:</b> The account will not be installed to the device by calling
2654920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * this api alone. #finishSession should be called after this to install the
2655920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * account on device.
26567881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *
26577881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * @param accountType The type of account to add; must not be null
26587881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * @param authTokenType The type of auth token (see {@link #getAuthToken})
26597881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *            this account will need to be able to generate, null for none
26607881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * @param requiredFeatures The features (see {@link #hasFeatures}) this
26617881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *            account must have, null for none
26627881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * @param options Authenticator-specific options for the request, may be
26637881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *            null or empty
26647881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * @param activity The {@link Activity} context to use for launching a new
26657881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *            authenticator-defined sub-Activity to prompt the user to
26667881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *            create an account; used only to call startActivity(); if null,
26677881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *            the prompt will not be launched directly, but the necessary
26687881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *            {@link Intent} will be returned to the caller instead
26697881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * @param callback Callback to invoke when the request completes, null for
26707881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *            no callback
26717881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * @param handler {@link Handler} identifying the callback thread, null for
26727881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *            the main thread
26737881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     * @return An {@link AccountManagerFuture} which resolves to a Bundle with
26747881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         these fields if activity was specified and user was authenticated
26757881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         with an account:
26767881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         <ul>
26777881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         <li>{@link #KEY_ACCOUNT_SESSION_BUNDLE} - encrypted Bundle for
26787881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         adding the the to the device later.
26797881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         <li>{@link #KEY_PASSWORD} - optional, the password or password
26807881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         hash of the account.
26817881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         <li>{@link #KEY_ACCOUNT_STATUS_TOKEN} - optional, token to check
26827881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         status of the account
26837881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         </ul>
26847881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         If no activity was specified, the returned Bundle contains only
26857881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         {@link #KEY_INTENT} with the {@link Intent} needed to launch the
26867881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         actual account creation process. If authenticator doesn't support
26877881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         this method, the returned Bundle contains only
26887881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         {@link #KEY_ACCOUNT_SESSION_BUNDLE} with encrypted
26897881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         {@code options} needed to add account later. If an error
26907881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         occurred, {@link AccountManagerFuture#getResult()} throws:
26917881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         <ul>
26927881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         <li>{@link AuthenticatorException} if no authenticator was
26937881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         registered for this account type or the authenticator failed to
26947881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         respond
26957881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         <li>{@link OperationCanceledException} if the operation was
26967881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         canceled for any reason, including the user canceling the
26977881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         creation process or adding accounts (of this type) has been
26987881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         disabled by policy
26997881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         <li>{@link IOException} if the authenticator experienced an I/O
27007881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         problem creating a new account, usually because of network
27017881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         trouble
27027881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     *         </ul>
2703920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * @see #finishSession
2704a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan     * @hide
27057881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan     */
2706a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan    @SystemApi
2707e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan    public AccountManagerFuture<Bundle> startAddAccountSession(
2708e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final String accountType,
2709e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final String authTokenType,
2710e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final String[] requiredFeatures,
2711e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final Bundle options,
2712e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final Activity activity,
2713e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            AccountManagerCallback<Bundle> callback,
2714e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            Handler handler) {
27157881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan        if (accountType == null) throw new IllegalArgumentException("accountType is null");
27167881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan        final Bundle optionsIn = new Bundle();
27177881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan        if (options != null) {
27187881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan            optionsIn.putAll(options);
27197881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan        }
27207881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan        optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
27217881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan
27227881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan        return new AmsTask(activity, handler, callback) {
27237881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan            @Override
27247881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan            public void doWork() throws RemoteException {
2725e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                mService.startAddAccountSession(
2726e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        mResponse,
2727e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        accountType,
2728e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        authTokenType,
2729e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        requiredFeatures,
2730e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        activity != null,
2731e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        optionsIn);
2732e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            }
2733e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan        }.start();
2734e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan    }
2735e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan
2736e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan    /**
2737e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * Asks the user to enter a new password for an account but not updating the
2738920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * saved credentials for the account until {@link #finishSession} is called.
2739e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * <p>
2740e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * This method may be called from any thread, but the returned
2741e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * {@link AccountManagerFuture} must not be used on the main thread.
2742e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * <p>
2743e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * <b>NOTE:</b> The saved credentials for the account alone will not be
2744920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * updated by calling this API alone. #finishSession should be called after
2745920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * this to update local credentials
2746e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *
2747e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * @param account The account to update credentials for
2748e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * @param authTokenType The credentials entered must allow an auth token of
2749e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *            this type to be created (but no actual auth token is
2750e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *            returned); may be null
2751e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * @param options Authenticator-specific options for the request; may be
2752e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *            null or empty
2753e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * @param activity The {@link Activity} context to use for launching a new
2754e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *            authenticator-defined sub-Activity to prompt the user to enter
2755e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *            a password; used only to call startActivity(); if null, the
2756e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *            prompt will not be launched directly, but the necessary
2757e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *            {@link Intent} will be returned to the caller instead
2758e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * @param callback Callback to invoke when the request completes, null for
2759e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *            no callback
2760e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * @param handler {@link Handler} identifying the callback thread, null for
2761e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *            the main thread
2762e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     * @return An {@link AccountManagerFuture} which resolves to a Bundle with
2763e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         these fields if an activity was supplied and user was
2764920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         successfully re-authenticated to the account:
2765e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         <ul>
2766e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         <li>{@link #KEY_ACCOUNT_SESSION_BUNDLE} - encrypted Bundle for
2767e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         updating the local credentials on device later.
2768920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         <li>{@link #KEY_PASSWORD} - optional, the password or password
2769920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         hash of the account
2770920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         <li>{@link #KEY_ACCOUNT_STATUS_TOKEN} - optional, token to check
2771920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         status of the account
2772e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         </ul>
2773e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         If no activity was specified, the returned Bundle contains
2774e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         {@link #KEY_INTENT} with the {@link Intent} needed to launch the
2775e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         password prompt. If an error occurred,
2776e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         {@link AccountManagerFuture#getResult()} throws:
2777e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         <ul>
2778e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         <li>{@link AuthenticatorException} if the authenticator failed to
2779e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         respond
2780e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         <li>{@link OperationCanceledException} if the operation was
2781e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         canceled for any reason, including the user canceling the
2782e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         password prompt
2783e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         <li>{@link IOException} if the authenticator experienced an I/O
2784e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         problem verifying the password, usually because of network
2785e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         trouble
2786e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     *         </ul>
2787920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * @see #finishSession
2788a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan     * @hide
2789e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan     */
2790a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan    @SystemApi
2791e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan    public AccountManagerFuture<Bundle> startUpdateCredentialsSession(
2792e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final Account account,
2793e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final String authTokenType,
2794e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final Bundle options,
2795e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final Activity activity,
2796e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final AccountManagerCallback<Bundle> callback,
2797e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            final Handler handler) {
2798e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan        if (account == null) {
2799e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            throw new IllegalArgumentException("account is null");
2800e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan        }
280151b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia
280251b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia        // Always include the calling package name. This just makes life easier
280351b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia        // down stream.
280451b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia        final Bundle optionsIn = new Bundle();
280551b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia        if (options != null) {
280651b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia            optionsIn.putAll(options);
280751b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia        }
280851b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia        optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
280951b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia
2810e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan        return new AmsTask(activity, handler, callback) {
2811e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            @Override
2812e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan            public void doWork() throws RemoteException {
2813e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                mService.startUpdateCredentialsSession(
2814e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        mResponse,
2815e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        account,
2816e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        authTokenType,
2817e68c37eead0b7255d307af91ca284eaee419c944Sandra Kwan                        activity != null,
281851b651aea178fcfca8a3219141f0ecfda1504887Carlos Valdivia                        optionsIn);
28197881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan            }
28207881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan        }.start();
28217881228736fd5f3f4ecf25d4808dc004c03b54d1Sandra Kwan    }
2822920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan
2823920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan    /**
2824920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * Finishes the session started by {@link #startAddAccountSession} or
2825920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * {@link #startUpdateCredentialsSession}. This will either add the account
2826920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * to AccountManager or update the local credentials stored.
2827920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * <p>
2828920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * This method may be called from any thread, but the returned
2829920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * {@link AccountManagerFuture} must not be used on the main thread.
2830920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *
2831920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * @param sessionBundle a {@link Bundle} created by {@link #startAddAccountSession} or
2832920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *            {@link #startUpdateCredentialsSession}
2833920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * @param activity The {@link Activity} context to use for launching a new
2834920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *            authenticator-defined sub-Activity to prompt the user to
2835920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *            create an account or reauthenticate existing account; used
2836920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *            only to call startActivity(); if null, the prompt will not
2837920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *            be launched directly, but the necessary {@link Intent} will
2838920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *            be returned to the caller instead
2839920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * @param callback Callback to invoke when the request completes, null for
2840920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *            no callback
2841920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * @param handler {@link Handler} identifying the callback thread, null for
2842920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *            the main thread
2843920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * @return An {@link AccountManagerFuture} which resolves to a Bundle with
2844920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         these fields if an activity was supplied and an account was added
2845920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         to device or local credentials were updated::
2846920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         <ul>
2847920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         <li>{@link #KEY_ACCOUNT_NAME} - the name of the account created
2848920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         <li>{@link #KEY_ACCOUNT_TYPE} - the type of the account
2849920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         </ul>
2850920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         If no activity was specified and additional information is needed
2851920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         from user, the returned Bundle may contains only
2852920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         {@link #KEY_INTENT} with the {@link Intent} needed to launch the
2853920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         actual account creation process. If an error occurred,
2854920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         {@link AccountManagerFuture#getResult()} throws:
2855920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         <ul>
2856920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         <li>{@link AuthenticatorException} if no authenticator was
2857920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         registered for this account type or the authenticator failed to
2858920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         respond
2859920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         <li>{@link OperationCanceledException} if the operation was
2860920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         canceled for any reason, including the user canceling the
2861920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         creation process or adding accounts (of this type) has been
2862920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         disabled by policy
2863920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         <li>{@link IOException} if the authenticator experienced an I/O
2864920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         problem creating a new account, usually because of network
2865920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         trouble
2866920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     *         </ul>
2867920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     * @see #startAddAccountSession and #startUpdateCredentialsSession
2868a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan     * @hide
2869920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan     */
2870a578d11470d2c782bc8b54bc2a9154e7f5b68354Sandra Kwan    @SystemApi
2871920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan    public AccountManagerFuture<Bundle> finishSession(
2872920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan            final Bundle sessionBundle,
2873920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan            final Activity activity,
2874920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan            AccountManagerCallback<Bundle> callback,
2875920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan            Handler handler) {
28760b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan        return finishSessionAsUser(
28770b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                sessionBundle,
28780b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                activity,
28790b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                Process.myUserHandle(),
28800b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                callback,
28810b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                handler);
28820b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan    }
28830b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan
28840b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan    /**
28850b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan     * @see #finishSession
28860b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan     * @hide
28870b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan     */
28880b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan    @SystemApi
28890b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan    public AccountManagerFuture<Bundle> finishSessionAsUser(
28900b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            final Bundle sessionBundle,
28910b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            final Activity activity,
28920b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            final UserHandle userHandle,
28930b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            AccountManagerCallback<Bundle> callback,
28940b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            Handler handler) {
2895920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan        if (sessionBundle == null) {
2896920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan            throw new IllegalArgumentException("sessionBundle is null");
2897920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan        }
2898920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan
2899920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan        /* Add information required by add account flow */
2900920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan        final Bundle appInfo = new Bundle();
2901920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan        appInfo.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
2902920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan
2903920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan        return new AmsTask(activity, handler, callback) {
2904920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan            @Override
2905920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan            public void doWork() throws RemoteException {
29060b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                mService.finishSessionAsUser(
29070b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                        mResponse,
29080b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                        sessionBundle,
29090b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                        activity != null,
29100b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                        appInfo,
29110b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan                        userHandle.getIdentifier());
2912920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan            }
2913920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan        }.start();
2914920f6ef983024c15fbd47f7be7fa9204559f2514Sandra Kwan    }
2915390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan
2916390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan    /**
2917390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * Checks whether {@link #updateCredentials} or {@link #startUpdateCredentialsSession} should be
2918390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * called with respect to the specified account.
2919390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * <p>
2920390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * This method may be called from any thread, but the returned {@link AccountManagerFuture} must
2921390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * not be used on the main thread.
2922390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     *
2923390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * @param account The {@link Account} to be checked whether {@link #updateCredentials} or
2924390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * {@link #startUpdateCredentialsSession} should be called
2925390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * @param statusToken a String of token to check account staus
2926390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * @param callback Callback to invoke when the request completes, null for no callback
2927390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * @param handler {@link Handler} identifying the callback thread, null for the main thread
2928390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * @return An {@link AccountManagerFuture} which resolves to a Boolean, true if the credentials
2929390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     *         of the account should be updated.
2930390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     * @hide
2931390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan     */
2932390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan    @SystemApi
2933390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan    public AccountManagerFuture<Boolean> isCredentialsUpdateSuggested(
2934390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            final Account account,
2935390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            final String statusToken,
2936390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            AccountManagerCallback<Boolean> callback,
2937390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            Handler handler) {
2938390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan        if (account == null) {
2939390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            throw new IllegalArgumentException("account is null");
2940390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan        }
2941390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan
2942390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan        if (TextUtils.isEmpty(statusToken)) {
2943390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            throw new IllegalArgumentException("status token is empty");
2944390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan        }
2945390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan
2946390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan        return new Future2Task<Boolean>(handler, callback) {
29470b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
2948390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            public void doWork() throws RemoteException {
2949390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan                mService.isCredentialsUpdateSuggested(
2950390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan                        mResponse,
2951390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan                        account,
2952390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan                        statusToken);
2953390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            }
29540b84b456a79d83527665a5ac399cba73f1a85821Sandra Kwan            @Override
2955390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
2956390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan                if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
2957390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan                    throw new AuthenticatorException("no result in response");
2958390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan                }
2959390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan                return bundle.getBoolean(KEY_BOOLEAN_RESULT);
2960390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan            }
2961390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan        }.start();
2962390c9d2d91117c767b27e33e906f7830b4c0a4dcSandra Kwan    }
2963603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana}
2964