AbstractAccountAuthenticator.java revision 31957f1badbb900bbfe211317e1ea992d650a72d
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; 27603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 28603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/** 29756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Abstract base class for creating AccountAuthenticators. 30756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * In order to be an authenticator one must extend this class, provider implementations for the 31756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * abstract methods and write a service that returns the result of {@link #getIBinder()} 32756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * in the service's {@link android.app.Service#onBind(android.content.Intent)} when invoked 33756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * with an intent with action {@link AccountManager#ACTION_AUTHENTICATOR_INTENT}. This service 34756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * must specify the following intent filter and metadata tags in its AndroidManifest.xml file 35756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <pre> 36756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <intent-filter> 37756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <action android:name="android.accounts.AccountAuthenticator" /> 38756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </intent-filter> 39756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <meta-data android:name="android.accounts.AccountAuthenticator" 40756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:resource="@xml/authenticator" /> 41756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </pre> 42756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The <code>android:resource</code> attribute must point to a resource that looks like: 43756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <pre> 44756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" 45756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:accountType="typeOfAuthenticator" 46756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:icon="@drawable/icon" 47756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:smallIcon="@drawable/miniIcon" 48756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:label="@string/label" 49756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:accountPreferences="@xml/account_preferences" 50756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * /> 51756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </pre> 52756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Replace the icons and labels with your own resources. The <code>android:accountType</code> 53756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * attribute must be a string that uniquely identifies your authenticator and will be the same 54756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * string that user will use when making calls on the {@link AccountManager} and it also 55756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * corresponds to {@link Account#type} for your accounts. One user of the android:icon is the 56756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * "Account & Sync" settings page and one user of the android:smallIcon is the Contact Application's 57756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * tab panels. 58756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 59756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The preferences attribute points to an PreferenceScreen xml hierarchy that contains 60756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * a list of PreferenceScreens that can be invoked to manage the authenticator. An example is: 61756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <pre> 62756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 63756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <PreferenceCategory android:title="@string/title_fmt" /> 64756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <PreferenceScreen 65756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:key="key1" 66756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:title="@string/key1_action" 67756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:summary="@string/key1_summary"> 68756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <intent 69756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:action="key1.ACTION" 70756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:targetPackage="key1.package" 71756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * android:targetClass="key1.class" /> 72756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </PreferenceScreen> 73756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </PreferenceScreen> 74756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </pre> 75756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * 76756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 77756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The standard pattern for implementing any of the abstract methods is the following: 78756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 79756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> If the supplied arguments are enough for the authenticator to fully satisfy the request 80756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * then it will do so and return a {@link Bundle} that contains the results. 81756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> If the authenticator needs information from the user to satisfy the request then it 82756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will create an {@link Intent} to an activity that will prompt the user for the information 83756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * and then carry out the request. This intent must be returned in a Bundle as key 84756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * {@link AccountManager#KEY_INTENT}. 85756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 86756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The activity needs to return the final result when it is complete so the Intent should contain 87756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * the {@link AccountAuthenticatorResponse} as {@link AccountManager#KEY_ACCOUNT_MANAGER_RESPONSE}. 88756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The activity must then call {@link AccountAuthenticatorResponse#onResult} or 89756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * {@link AccountAuthenticatorResponse#onError} when it is complete. 9031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * <li> If the authenticator cannot synchronously process the request and return a result then it 9131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * may choose to return null and then use the {@link AccountManagerResponse} to send the result 9231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * when it has completed the request. 93756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 94756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 95756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The following descriptions of each of the abstract authenticator methods will not describe the 96756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * possible asynchronous nature of the request handling and will instead just describe the input 97756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * parameters and the expected result. 98756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <p> 99756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * When writing an activity to satisfy these requests one must pass in the AccountManagerResponse 100756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * and return the result via that response when the activity finishes (or whenever else the 101756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * activity author deems it is the correct time to respond). 102756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * The {@link AccountAuthenticatorActivity} handles this, so one may wish to extend that when 103756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * writing activities to handle these requests. 104603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 105603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanapublic abstract class AbstractAccountAuthenticator { 106d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final Context mContext; 107d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 108d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public AbstractAccountAuthenticator(Context context) { 109d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mContext = context; 110d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 111d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 112f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana private class Transport extends IAccountAuthenticator.Stub { 113a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void addAccount(IAccountAuthenticatorResponse response, String accountType, 1143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType, String[] requiredFeatures, Bundle options) 115603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throws RemoteException { 116d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 117a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 11831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.addAccount( 119a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana new AccountAuthenticatorResponse(response), 1203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana accountType, authTokenType, requiredFeatures, options); 12131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 12231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 12331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 124a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (NetworkErrorException e) { 125f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); 126a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (UnsupportedOperationException e) { 127f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 128a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "addAccount not supported"); 129a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 132a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void confirmCredentials(IAccountAuthenticatorResponse response, 133f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana Account account, Bundle options) throws RemoteException { 134d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 135a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 13631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.confirmCredentials( 137f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana new AccountAuthenticatorResponse(response), account, options); 13831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 13931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 14031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 14131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } catch (NetworkErrorException e) { 14231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); 143a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (UnsupportedOperationException e) { 144f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 145a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "confirmCredentials not supported"); 146a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 147603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 148603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 149d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public void getAuthTokenLabel(IAccountAuthenticatorResponse response, 150d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenType) 151d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throws RemoteException { 152d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 153d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 154d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Bundle result = new Bundle(); 155f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, 156d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana AbstractAccountAuthenticator.this.getAuthTokenLabel(authTokenType)); 157d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana response.onResult(result); 158d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (IllegalArgumentException e) { 159f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, 160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana "unknown authTokenType"); 161d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (UnsupportedOperationException e) { 162f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 163d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana "getAuthTokenTypeLabel not supported"); 164d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 165d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 166d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 167a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void getAuthToken(IAccountAuthenticatorResponse response, 168a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Account account, String authTokenType, Bundle loginOptions) 169603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throws RemoteException { 170d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 171a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 172a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final Bundle result = AbstractAccountAuthenticator.this.getAuthToken( 173a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana new AccountAuthenticatorResponse(response), account, 174a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana authTokenType, loginOptions); 175a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (result != null) { 176a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onResult(result); 177a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 178a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (UnsupportedOperationException e) { 179f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 180a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "getAuthToken not supported"); 181a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (NetworkErrorException e) { 182f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); 183a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 184603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 185603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 186a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void updateCredentials(IAccountAuthenticatorResponse response, Account account, 187a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana String authTokenType, Bundle loginOptions) throws RemoteException { 188d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 189a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 19031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.updateCredentials( 191a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana new AccountAuthenticatorResponse(response), account, 192a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana authTokenType, loginOptions); 19331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 19431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 19531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 19631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } catch (NetworkErrorException e) { 19731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); 198a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (UnsupportedOperationException e) { 199f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 200a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "updateCredentials not supported"); 201a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 202603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 203603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 204a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void editProperties(IAccountAuthenticatorResponse response, 205a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana String accountType) throws RemoteException { 206d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 207a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 20831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.editProperties( 209603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new AccountAuthenticatorResponse(response), accountType); 21031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 21131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 21231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 213a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (UnsupportedOperationException e) { 214f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 215a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "editProperties not supported"); 216a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 217603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 2193326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void hasFeatures(IAccountAuthenticatorResponse response, 2203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account account, String[] features) throws RemoteException { 221d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(); 2223326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 22331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final Bundle result = AbstractAccountAuthenticator.this.hasFeatures( 2243326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new AccountAuthenticatorResponse(response), account, features); 22531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (result != null) { 22631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana response.onResult(result); 22731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2283326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (UnsupportedOperationException e) { 229f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 2303326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana "hasFeatures not supported"); 2313326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (NetworkErrorException e) { 232f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); 2333326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 2343326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 235ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 236ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void getAccountRemovalAllowed(IAccountAuthenticatorResponse response, 237ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Account account) throws RemoteException { 238ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana checkBinderPermission(); 239ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 240ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Bundle result = AbstractAccountAuthenticator.this.getAccountRemovalAllowed( 241ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new AccountAuthenticatorResponse(response), account); 242ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (result != null) { 243ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana response.onResult(result); 244ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 245ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } catch (UnsupportedOperationException e) { 246f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 247ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "getAccountRemovalAllowed not supported"); 248ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } catch (NetworkErrorException e) { 249f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); 250ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 251ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 252603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 253603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 254d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkBinderPermission() { 255d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 256f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final String perm = Manifest.permission.ACCOUNT_MANAGER; 257d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (mContext.checkCallingOrSelfPermission(perm) != PackageManager.PERMISSION_GRANTED) { 258d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throw new SecurityException("caller uid " + uid + " lacks " + perm); 259d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 260d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 261d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 262f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana private Transport mTransport = new Transport(); 263603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 264603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana /** 265f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana * @return the IBinder for the AccountAuthenticator 266603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 267f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana public final IBinder getIBinder() { 268f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana return mTransport.asBinder(); 269603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 270603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 271603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana /** 272a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * Returns a Bundle that contains the Intent of the activity that can be used to edit the 273a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * properties. In order to indicate success the activity should call response.setResult() 274a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * with a non-null Bundle. 275a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * @param response used to set the result for the request. If the Constants.INTENT_KEY 276a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * is set in the bundle then this response field is to be used for sending future 277a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * results if and when the Intent is started. 278a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * @param accountType the AccountType whose properties are to be edited. 279a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * @return a Bundle containing the result or the Intent to start to continue the request. 280a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * If this is null then the request is considered to still be active and the result should 281a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana * sent later using response. 282603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 283a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle editProperties(AccountAuthenticatorResponse response, 284a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana String accountType); 285756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 286756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 287756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Adds an account of the specified accountType. 288756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 289756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param accountType the type of account to add, will never be null 290756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param authTokenType the type of auth token to retrieve after adding the account, may be null 291756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param requiredFeatures a String array of authenticator-specific features that the added 292756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * account must support, may be null 293756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param options a Bundle of authenticator-specific options, may be null 294756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 295756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 296756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 297756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 298756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of 299756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * the account that was added, plus {@link AccountManager#KEY_AUTHTOKEN} if an authTokenType 300756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * was supplied, or 301756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 302756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 303756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 304756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 305756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * network error 306756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 307a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle addAccount(AccountAuthenticatorResponse response, String accountType, 3083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType, String[] requiredFeatures, Bundle options) 3093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana throws NetworkErrorException; 310756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 311756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 312756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Checks that the user knows the credentials of an account. 313756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 314756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account whose credentials are to be checked, will never be null 315756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param options a Bundle of authenticator-specific options, may be null 316756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 317756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 318756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 319756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 320756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the check succeeded, false otherwise 321756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 322756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 323756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 32431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 32531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * network error 326756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 327a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle confirmCredentials(AccountAuthenticatorResponse response, 32831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana Account account, Bundle options) 32931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana throws NetworkErrorException; 330756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 331756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Gets the authtoken for an account. 332756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 333756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account whose credentials are to be retrieved, will never be null 334756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param authTokenType the type of auth token to retrieve, will never be null 33531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * @param options a Bundle of authenticator-specific options, may be null 336756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 337756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 338756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 339756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 340756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ACCOUNT_NAME}, {@link AccountManager#KEY_ACCOUNT_TYPE}, 341756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * and {@link AccountManager#KEY_AUTHTOKEN}, or 342756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 343756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 344756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 345756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 346756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * network error 347756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 348a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle getAuthToken(AccountAuthenticatorResponse response, 34931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana Account account, String authTokenType, Bundle options) 350a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana throws NetworkErrorException; 351756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 352756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 353756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Ask the authenticator for a localized label for the given authTokenType. 354756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param authTokenType the authTokenType whose label is to be returned, will never be null 355756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return the localized label of the auth token type, may be null if the type isn't known 356756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 357d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public abstract String getAuthTokenLabel(String authTokenType); 358756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 359756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 360756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Update the locally stored credentials for an account. 361756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 362756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account whose credentials are to be updated, will never be null 363756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param authTokenType the type of auth token to retrieve after updating the credentials, 364756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * may be null 36531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * @param options a Bundle of authenticator-specific options, may be null 366756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 367756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 368756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 369756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 370756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of 371756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * the account that was added, plus {@link AccountManager#KEY_AUTHTOKEN} if an authTokenType 372756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * was supplied, or 373756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 374756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 375756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 37631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 37731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana * network error 378756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 379a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public abstract Bundle updateCredentials(AccountAuthenticatorResponse response, 38031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana Account account, String authTokenType, Bundle options) throws NetworkErrorException; 381756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 382756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 383756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Checks if the account supports all the specified authenticator specific features. 384756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 385756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account to check, will never be null 386756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param features an array of features to check, will never be null 387756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 388756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 389756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 390756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 391756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the account has all the features, 392756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * false otherwise 393756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 394756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 395756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 396756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 397756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * network error 398756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 3993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public abstract Bundle hasFeatures(AccountAuthenticatorResponse response, 4003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account account, String[] features) throws NetworkErrorException; 401756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana 402756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana /** 403756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * Checks if the removal of this account is allowed. 404756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param response to send the result back to the AccountManager, will never be null 405756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @param account the account to check, will never be null 406756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @return a Bundle result or null if the result is to be returned via the response. The result 407756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * will contain either: 408756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <ul> 409756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_INTENT}, or 410756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the removal of the account is 411756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * allowed, false otherwise 412756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to 413756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * indicate an error 414756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * </ul> 415756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * @throws NetworkErrorException if the authenticator could not honor the request due to a 416756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana * network error 417756b735e9312ee52618158270f0bdd0ec691a712Fred Quintana */ 418ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response, 419ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Account account) throws NetworkErrorException { 420ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Bundle result = new Bundle(); 421f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); 422ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return result; 423ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 424603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 425