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 19a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Bundle; 20603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.os.RemoteException; 21d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.os.Binder; 22f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintanaimport android.os.IBinder; 23d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.PackageManager; 24d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.Context; 25f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintanaimport android.content.Intent; 26d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.Manifest; 27f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintanaimport android.util.Log; 28f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana 29f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintanaimport java.util.Arrays; 30603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 31603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/** 32756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Abstract base class for creating AccountAuthenticators. 33756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * In order to be an authenticator one must extend this class, provider implementations for the 34756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * abstract methods and write a service that returns the result of {@link #getIBinder()} 35756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * in the service's {@link android.app.Service#onBind(android.content.Intent)} when invoked 36756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * with an intent with action {@link AccountManager#ACTION_AUTHENTICATOR_INTENT}. This service 37756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * must specify the following intent filter and metadata tags in its AndroidManifest.xml file 38756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <pre> 39756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <intent-filter> 40756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <action android:name="android.accounts.AccountAuthenticator" /> 41756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </intent-filter> 42756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <meta-data android:name="android.accounts.AccountAuthenticator" 43756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:resource="@xml/authenticator" /> 44756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </pre> 45756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The <code>android:resource</code> attribute must point to a resource that looks like: 46756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <pre> 47756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" 48756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:accountType="typeOfAuthenticator" 49756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:icon="@drawable/icon" 50756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:smallIcon="@drawable/miniIcon" 51756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:label="@string/label" 52756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:accountPreferences="@xml/account_preferences" 53756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * /> 54756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </pre> 55756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Replace the icons and labels with your own resources. The <code>android:accountType</code> 56756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * attribute must be a string that uniquely identifies your authenticator and will be the same 57756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * string that user will use when making calls on the {@link AccountManager} and it also 58756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * corresponds to {@link Account#type} for your accounts. One user of the android:icon is the 59756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * "Account & Sync" settings page and one user of the android:smallIcon is the Contact Application's 60756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * tab panels. 61756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 62f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa * The preferences attribute points to a PreferenceScreen xml hierarchy that contains 63756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * a list of PreferenceScreens that can be invoked to manage the authenticator. An example is: 64756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <pre> 65756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 66756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <PreferenceCategory android:title="@string/title_fmt" /> 67756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <PreferenceScreen 68756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:key="key1" 69756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:title="@string/key1_action" 70756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:summary="@string/key1_summary"> 71756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <intent 72756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:action="key1.ACTION" 73756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:targetPackage="key1.package" 74756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:targetClass="key1.class" /> 75756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </PreferenceScreen> 76756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </PreferenceScreen> 77756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </pre> 78756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * 79756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 80756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The standard pattern for implementing any of the abstract methods is the following: 81756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 82756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> If the supplied arguments are enough for the authenticator to fully satisfy the request 83756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * then it will do so and return a {@link Bundle} that contains the results. 84756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> If the authenticator needs information from the user to satisfy the request then it 85756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will create an {@link Intent} to an activity that will prompt the user for the information 86756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * and then carry out the request. This intent must be returned in a Bundle as key 87756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * {@link AccountManager#KEY_INTENT}. 88756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 89756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The activity needs to return the final result when it is complete so the Intent should contain 90756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * the {@link AccountAuthenticatorResponse} as {@link AccountManager#KEY_ACCOUNT_MANAGER_RESPONSE}. 91756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The activity must then call {@link AccountAuthenticatorResponse#onResult} or 92756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * {@link AccountAuthenticatorResponse#onError} when it is complete. 9331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * <li> If the authenticator cannot synchronously process the request and return a result then it 94d6f158b3684acdf877ff6afb7208e1140afc4e12Ed Heyl * may choose to return null and then use the AccountManagerResponse to send the result 9531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * when it has completed the request. 96756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 97756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 98756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The following descriptions of each of the abstract authenticator methods will not describe the 99756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * possible asynchronous nature of the request handling and will instead just describe the input 100756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * parameters and the expected result. 101756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 102756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * When writing an activity to satisfy these requests one must pass in the AccountManagerResponse 103756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * and return the result via that response when the activity finishes (or whenever else the 104756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * activity author deems it is the correct time to respond). 105756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The {@link AccountAuthenticatorActivity} handles this, so one may wish to extend that when 106756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * writing activities to handle these requests. 107603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 108603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanapublic abstract class AbstractAccountAuthenticator { 109f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana private static final String TAG = "AccountAuthenticator"; 110f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana 11191979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia /** 11291979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * Bundle key used for the {@code long} expiration time (in millis from the unix epoch) of the 11391979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * associated auth token. 11491979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * 11591979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * @see #getAuthToken 11691979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia */ 11791979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia public static final String KEY_CUSTOM_TOKEN_EXPIRY = "android.accounts.expiry"; 11891979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia 119d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final Context mContext; 120d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 121d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public AbstractAccountAuthenticator(Context context) { 122d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mContext = context; 123d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 124d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 125f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana private class Transport extends IAccountAuthenticator.Stub { 12691979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 127a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void addAccount(IAccountAuthenticatorResponse response, String accountType, 128f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana String authTokenType, String[] features, Bundle options) 129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throws RemoteException { 130f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 131f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "addAccount: accountType " + accountType 132f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana + ", authTokenType " + authTokenType 133f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana + ", features " + (features == null ? "[]" : Arrays.toString(features))); 134f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 135d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 136a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 13731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.addAccount( 138a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana new AccountAuthenticatorResponse(response), 139f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana accountType, authTokenType, features, options); 140f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1416cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz if (result != null) { 1426cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz result.keySet(); // force it to be unparcelled 1436cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz } 144f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "addAccount: result " + AccountManager.sanitizeResult(result)); 145f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 14631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 14731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 14831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 1495d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } catch (Exception e) { 1505d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana handleException(response, "addAccount", accountType, e); 151a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 152603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 153603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 15491979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 155a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void confirmCredentials(IAccountAuthenticatorResponse response, 156f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana Account account, Bundle options) throws RemoteException { 157f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 158f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "confirmCredentials: " + account); 159f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 161a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 16231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.confirmCredentials( 163f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana new AccountAuthenticatorResponse(response), account, options); 164f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1656cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz if (result != null) { 1666cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz result.keySet(); // force it to be unparcelled 1676cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz } 168f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "confirmCredentials: result " 169f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana + AccountManager.sanitizeResult(result)); 170f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 17131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 17231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 17331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 1745d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } catch (Exception e) { 1755d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana handleException(response, "confirmCredentials", account.toString(), e); 176a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 177603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 178603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 17991979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 180d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public void getAuthTokenLabel(IAccountAuthenticatorResponse response, 181d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenType) 182d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throws RemoteException { 183f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 184f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "getAuthTokenLabel: authTokenType " + authTokenType); 185f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 186d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 187d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 188d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Bundle result = new Bundle(); 189f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, 190d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana AbstractAccountAuthenticator.this.getAuthTokenLabel(authTokenType)); 191f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1926cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz if (result != null) { 1936cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz result.keySet(); // force it to be unparcelled 1946cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz } 195f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "getAuthTokenLabel: result " 196f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana + AccountManager.sanitizeResult(result)); 197f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 1985d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana response.onResult(result); 1995d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } catch (Exception e) { 2005d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana handleException(response, "getAuthTokenLabel", authTokenType, e); 201d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 202d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 203d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 20491979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 205a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void getAuthToken(IAccountAuthenticatorResponse response, 206a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Account account, String authTokenType, Bundle loginOptions) 207603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throws RemoteException { 208f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 209f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "getAuthToken: " + account 210f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana + ", authTokenType " + authTokenType); 211f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 212d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 213a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 214a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final Bundle result = AbstractAccountAuthenticator.this.getAuthToken( 215a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana new AccountAuthenticatorResponse(response), account, 216a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana authTokenType, loginOptions); 217f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2186cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz if (result != null) { 2196cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz result.keySet(); // force it to be unparcelled 2206cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz } 221f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "getAuthToken: result " + AccountManager.sanitizeResult(result)); 222f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 223a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (result != null) { 224a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onResult(result); 225a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2265d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } catch (Exception e) { 2275d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana handleException(response, "getAuthToken", 2285d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana account.toString() + "," + authTokenType, e); 229a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 230603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 231603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 23291979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 233a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void updateCredentials(IAccountAuthenticatorResponse response, Account account, 234a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana String authTokenType, Bundle loginOptions) throws RemoteException { 235f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 236f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "updateCredentials: " + account 237f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana + ", authTokenType " + authTokenType); 238f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 239d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 240a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 24131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.updateCredentials( 242a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana new AccountAuthenticatorResponse(response), account, 243a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana authTokenType, loginOptions); 244f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2456cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz // Result may be null. 2466cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz if (result != null) { 2476cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz result.keySet(); // force it to be unparcelled 2486cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz } 249f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana Log.v(TAG, "updateCredentials: result " 250f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana + AccountManager.sanitizeResult(result)); 251f0fd8436b3ec2aa47cd5de61072b8395bbe46765Fred Quintana } 25231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 25331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 25431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2555d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } catch (Exception e) { 2565d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana handleException(response, "updateCredentials", 2575d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana account.toString() + "," + authTokenType, e); 258a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 259603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 260603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 26191979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 262a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void editProperties(IAccountAuthenticatorResponse response, 263a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana String accountType) throws RemoteException { 264d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 265a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 26631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.editProperties( 267603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new AccountAuthenticatorResponse(response), accountType); 26831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 26931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 27031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2715d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } catch (Exception e) { 2725d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana handleException(response, "editProperties", accountType, e); 273a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 274603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2753326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 27691979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 2773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void hasFeatures(IAccountAuthenticatorResponse response, 2783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account account, String[] features) throws RemoteException { 279d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 2803326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 28131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.hasFeatures( 2823326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new AccountAuthenticatorResponse(response), account, features); 28331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 28431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 28531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2865d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } catch (Exception e) { 2875d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana handleException(response, "hasFeatures", account.toString(), e); 2883326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 2893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 290ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 29191979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 292ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void getAccountRemovalAllowed(IAccountAuthenticatorResponse response, 293ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Account account) throws RemoteException { 294ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana checkBinderPermission(); 295ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 296ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Bundle result = AbstractAccountAuthenticator.this.getAccountRemovalAllowed( 297ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new AccountAuthenticatorResponse(response), account); 298ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (result != null) { 299ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana response.onResult(result); 300ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 3015d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } catch (Exception e) { 3025d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana handleException(response, "getAccountRemovalAllowed", account.toString(), e); 3035d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } 3045d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } 30567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 30691979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 30767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void getAccountCredentialsForCloning(IAccountAuthenticatorResponse response, 30867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account account) throws RemoteException { 30967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani checkBinderPermission(); 31067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 31167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final Bundle result = 31267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani AbstractAccountAuthenticator.this.getAccountCredentialsForCloning( 31367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new AccountAuthenticatorResponse(response), account); 31467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result != null) { 31567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani response.onResult(result); 31667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 31767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } catch (Exception e) { 31867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani handleException(response, "getAccountCredentialsForCloning", account.toString(), e); 31967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 32067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 32167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 32291979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 32367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void addAccountFromCredentials(IAccountAuthenticatorResponse response, 32467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account account, 32567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Bundle accountCredentials) throws RemoteException { 32667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani checkBinderPermission(); 32767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 32867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final Bundle result = 32967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani AbstractAccountAuthenticator.this.addAccountFromCredentials( 33067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new AccountAuthenticatorResponse(response), account, 33167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani accountCredentials); 33267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result != null) { 33367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani response.onResult(result); 33467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 33567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } catch (Exception e) { 33667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani handleException(response, "addAccountFromCredentials", account.toString(), e); 33767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 33867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 3395d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } 3405d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana 3415d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana private void handleException(IAccountAuthenticatorResponse response, String method, 3425d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana String data, Exception e) throws RemoteException { 3435d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana if (e instanceof NetworkErrorException) { 3445d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3455d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana Log.v(TAG, method + "(" + data + ")", e); 3465d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } 3475d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); 3485d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } else if (e instanceof UnsupportedOperationException) { 3495d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3505d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana Log.v(TAG, method + "(" + data + ")", e); 3515d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } 3525d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 3535d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana method + " not supported"); 3545d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } else if (e instanceof IllegalArgumentException) { 3555d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3565d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana Log.v(TAG, method + "(" + data + ")", e); 357ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 3585d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, 3595d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana method + " not supported"); 3605d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana } else { 3615d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana Log.w(TAG, method + "(" + data + ")", e); 3625d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 3635d1a0c3933253d66a9c230ea1da051a7626937d4Fred Quintana method + " failed"); 364ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 365603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 366603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 367d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkBinderPermission() { 368d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 369f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final String perm = Manifest.permission.ACCOUNT_MANAGER; 370d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (mContext.checkCallingOrSelfPermission(perm) != PackageManager.PERMISSION_GRANTED) { 371d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throw new SecurityException("caller uid " + uid + " lacks " + perm); 372d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 373d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 374d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 375f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana private Transport mTransport = new Transport(); 376603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 377603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana /** 378f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana * @return the IBinder for the AccountAuthenticator 379603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 380f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana public final IBinder getIBinder() { 381f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana return mTransport.asBinder(); 382603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 383603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 384603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana /** 385a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * Returns a Bundle that contains the Intent of the activity that can be used to edit the 386a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * properties. In order to indicate success the activity should call response.setResult() 387a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * with a non-null Bundle. 388a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * @param response used to set the result for the request. If the Constants.INTENT_KEY 389a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * is set in the bundle then this response field is to be used for sending future 390a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * results if and when the Intent is started. 391a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * @param accountType the AccountType whose properties are to be edited. 392a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * @return a Bundle containing the result or the Intent to start to continue the request. 393a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * If this is null then the request is considered to still be active and the result should 394a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * sent later using response. 395603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 396a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle editProperties(AccountAuthenticatorResponse response, 397a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana String accountType); 398756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 399756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 400756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Adds an account of the specified accountType. 401756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 402756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param accountType the type of account to add, will never be null 403756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param authTokenType the type of auth token to retrieve after adding the account, may be null 404756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param requiredFeatures a String array of authenticator-specific features that the added 405756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * account must support, may be null 406756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param options a Bundle of authenticator-specific options, may be null 407756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 408756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 409756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 410756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 411756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of 4128570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana * the account that was added, or 413756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 414756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 415756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 416756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 417756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * network error 418756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 419a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle addAccount(AccountAuthenticatorResponse response, String accountType, 4203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType, String[] requiredFeatures, Bundle options) 4213326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana throws NetworkErrorException; 422756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 423756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 424756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Checks that the user knows the credentials of an account. 425756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 426756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account whose credentials are to be checked, will never be null 427756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param options a Bundle of authenticator-specific options, may be null 428756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 429756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 430756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 431756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 432756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the check succeeded, false otherwise 433756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 434756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 435756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 43631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 43731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * network error 438756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 439a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle confirmCredentials(AccountAuthenticatorResponse response, 44031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana Account account, Bundle options) 44131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana throws NetworkErrorException; 44291979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia 443756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 44491979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * Gets an authtoken for an account. 44591979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * 44691979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * If not {@code null}, the resultant {@link Bundle} will contain different sets of keys 44791979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * depending on whether a token was successfully issued and, if not, whether one 44891979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * could be issued via some {@link android.app.Activity}. 44991979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * <p> 45091979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * If a token cannot be provided without some additional activity, the Bundle should contain 45191979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * {@link AccountManager#KEY_INTENT} with an associated {@link Intent}. On the other hand, if 45291979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * there is no such activity, then a Bundle containing 45391979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} should be 45491979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * returned. 45591979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * <p> 45691979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * If a token can be successfully issued, the implementation should return the 45791979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of the 45891979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * account associated with the token as well as the {@link AccountManager#KEY_AUTHTOKEN}. In 45991979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * addition {@link AbstractAccountAuthenticator} implementations that declare themselves 46091979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * {@code android:customTokens=true} may also provide a non-negative {@link 46191979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * #KEY_CUSTOM_TOKEN_EXPIRY} long value containing the expiration timestamp of the expiration 46291979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * time (in millis since the unix epoch). 46391979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * <p> 46491979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * Implementers should assume that tokens will be cached on the basis of account and 46591979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * authTokenType. The system may ignore the contents of the supplied options Bundle when 46691979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * determining to re-use a cached token. Furthermore, implementers should assume a supplied 46791979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * expiration time will be treated as non-binding advice. 46891979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * <p> 46991979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * Finally, note that for android:customTokens=false authenticators, tokens are cached 47091979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * indefinitely until some client calls {@link 47191979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * AccountManager#invalidateAuthToken(String,String)}. 47291979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * 473756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 474756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account whose credentials are to be retrieved, will never be null 475756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param authTokenType the type of auth token to retrieve, will never be null 47631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * @param options a Bundle of authenticator-specific options, may be null 47791979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia * @return a Bundle result or null if the result is to be returned via the response. 478756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 479756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * network error 480756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 481a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle getAuthToken(AccountAuthenticatorResponse response, 48231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana Account account, String authTokenType, Bundle options) 483a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana throws NetworkErrorException; 484756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 485756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 486756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Ask the authenticator for a localized label for the given authTokenType. 487756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param authTokenType the authTokenType whose label is to be returned, will never be null 488756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return the localized label of the auth token type, may be null if the type isn't known 489756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 490d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public abstract String getAuthTokenLabel(String authTokenType); 491756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 492756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 493756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Update the locally stored credentials for an account. 494756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 495756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account whose credentials are to be updated, will never be null 496756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param authTokenType the type of auth token to retrieve after updating the credentials, 497756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * may be null 49831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * @param options a Bundle of authenticator-specific options, may be null 499756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 500756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 501756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 502756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 503756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of 5046cc066df7a79eb9f3cdf7b41dc9307f75c413c09Ian Pedowitz * the account whose credentials were updated, or 505756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 506756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 507756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 50831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 50931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * network error 510756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 511a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle updateCredentials(AccountAuthenticatorResponse response, 51231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana Account account, String authTokenType, Bundle options) throws NetworkErrorException; 5138570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana 514756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 515756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Checks if the account supports all the specified authenticator specific features. 516756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 517756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account to check, will never be null 518756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param features an array of features to check, will never be null 519756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 520756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 521756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 522756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 523756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the account has all the features, 524756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * false otherwise 525756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 526756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 527756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 528756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 529756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * network error 530756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 5313326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public abstract Bundle hasFeatures(AccountAuthenticatorResponse response, 5323326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account account, String[] features) throws NetworkErrorException; 533756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 534756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 535756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Checks if the removal of this account is allowed. 536756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 537756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account to check, will never be null 538756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 539756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 540756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 541756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 542756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the removal of the account is 543756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * allowed, false otherwise 544756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 545756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 546756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 547756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 548756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * network error 549756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 550ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response, 551ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Account account) throws NetworkErrorException { 552ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Bundle result = new Bundle(); 553f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); 554ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return result; 555ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 55667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 55767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani /** 55867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * Returns a Bundle that contains whatever is required to clone the account on a different 55967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * user. The Bundle is passed to the authenticator instance in the target user via 56067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * {@link #addAccountFromCredentials(AccountAuthenticatorResponse, Account, Bundle)}. 56167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * The default implementation returns null, indicating that cloning is not supported. 56267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @param response to send the result back to the AccountManager, will never be null 56367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @param account the account to clone, will never be null 56467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @return a Bundle result or null if the result is to be returned via the response. 56567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @throws NetworkErrorException 56667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @see {@link #addAccountFromCredentials(AccountAuthenticatorResponse, Account, Bundle)} 56767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani */ 56867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public Bundle getAccountCredentialsForCloning(final AccountAuthenticatorResponse response, 56967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final Account account) throws NetworkErrorException { 57067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new Thread(new Runnable() { 57191979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 57267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void run() { 57367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Bundle result = new Bundle(); 57467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); 57567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani response.onResult(result); 57667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 57767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }).start(); 57867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return null; 57967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 58067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 58167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani /** 58267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * Creates an account based on credentials provided by the authenticator instance of another 58367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * user on the device, who has chosen to share the account with this user. 58467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @param response to send the result back to the AccountManager, will never be null 58567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @param account the account to clone, will never be null 58667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @param accountCredentials the Bundle containing the required credentials to create the 58767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * account. Contents of the Bundle are only meaningful to the authenticator. This Bundle is 58867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * provided by {@link #getAccountCredentialsForCloning(AccountAuthenticatorResponse, Account)}. 58967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @return a Bundle result or null if the result is to be returned via the response. 59067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @throws NetworkErrorException 59167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani * @see {@link #getAccountCredentialsForCloning(AccountAuthenticatorResponse, Account)} 59267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani */ 59367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public Bundle addAccountFromCredentials(final AccountAuthenticatorResponse response, 59467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account account, 59567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Bundle accountCredentials) throws NetworkErrorException { 59667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new Thread(new Runnable() { 59791979be8804232a04da2bf36cdd857ee7da04479Carlos Valdivia @Override 59867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void run() { 59967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Bundle result = new Bundle(); 60067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); 60167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani response.onResult(result); 60267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 60367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }).start(); 60467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return null; 60567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 606603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 607