1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server.accounts; 17 18 import android.accounts.AbstractAccountAuthenticator; 19 import android.accounts.Account; 20 import android.accounts.AccountAuthenticatorResponse; 21 import android.accounts.AccountManager; 22 import android.accounts.NetworkErrorException; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.os.Bundle; 26 27 import com.android.frameworks.servicestests.R; 28 29 import java.util.concurrent.atomic.AtomicInteger; 30 31 /** 32 * This authenticator is to mock account authenticator to test AccountManagerService. 33 */ 34 public class TestAccountType1Authenticator extends AbstractAccountAuthenticator { 35 private final AtomicInteger mTokenCounter = new AtomicInteger(0); 36 37 private final String mAccountType; 38 private final Context mContext; 39 40 public TestAccountType1Authenticator(Context context, String accountType) { 41 super(context); 42 mAccountType = accountType; 43 mContext = context; 44 } 45 46 @Override 47 public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { 48 Bundle result = new Bundle(); 49 result.putString(AccountManager.KEY_ACCOUNT_NAME, 50 AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS); 51 result.putString(AccountManager.KEY_ACCOUNT_TYPE, 52 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1); 53 result.putString( 54 AccountManager.KEY_AUTHTOKEN, 55 Integer.toString(mTokenCounter.incrementAndGet())); 56 return result; 57 } 58 59 @Override 60 public Bundle addAccount( 61 AccountAuthenticatorResponse response, 62 String accountType, 63 String authTokenType, 64 String[] requiredFeatures, 65 Bundle options) throws NetworkErrorException { 66 if (!mAccountType.equals(accountType)) { 67 throw new IllegalArgumentException("Request to the wrong authenticator!"); 68 } 69 String accountName = null; 70 71 if (options != null) { 72 accountName = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME); 73 } 74 75 Bundle result = new Bundle(); 76 if (accountName.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 77 // fill bundle with a success result. 78 result.putString(AccountManager.KEY_ACCOUNT_NAME, accountName); 79 result.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccountType); 80 result.putString(AccountManager.KEY_AUTHTOKEN, 81 Integer.toString(mTokenCounter.incrementAndGet())); 82 result.putParcelable(AccountManagerServiceTestFixtures.KEY_OPTIONS_BUNDLE, options); 83 } else if (accountName.equals( 84 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE)) { 85 // Specify data to be returned by the eventual activity. 86 Intent eventualActivityResultData = new Intent(); 87 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_NAME, accountName); 88 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType); 89 // Fill result with Intent. 90 Intent intent = new Intent(mContext, AccountAuthenticatorDummyActivity.class); 91 intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT, eventualActivityResultData); 92 intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response); 93 94 result.putParcelable(AccountManager.KEY_INTENT, intent); 95 } else { 96 fillResultWithError( 97 result, 98 AccountManager.ERROR_CODE_INVALID_RESPONSE, 99 AccountManagerServiceTestFixtures.ERROR_MESSAGE); 100 } 101 return result; 102 } 103 104 @Override 105 public Bundle confirmCredentials( 106 AccountAuthenticatorResponse response, 107 Account account, 108 Bundle options) throws NetworkErrorException { 109 if (!mAccountType.equals(account.type)) { 110 throw new IllegalArgumentException("Request to the wrong authenticator!"); 111 } 112 Bundle result = new Bundle(); 113 114 if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 115 // fill bundle with a success result. 116 result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); 117 result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 118 result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 119 } else if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE)) { 120 // Specify data to be returned by the eventual activity. 121 Intent eventualActivityResultData = new Intent(); 122 eventualActivityResultData.putExtra(AccountManager.KEY_BOOLEAN_RESULT, true); 123 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name); 124 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type); 125 126 // Fill result with Intent. 127 Intent intent = new Intent(mContext, AccountAuthenticatorDummyActivity.class); 128 intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT, 129 eventualActivityResultData); 130 intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response); 131 132 result.putParcelable(AccountManager.KEY_INTENT, intent); 133 } else { 134 // fill with error 135 fillResultWithError( 136 result, 137 AccountManager.ERROR_CODE_INVALID_RESPONSE, 138 AccountManagerServiceTestFixtures.ERROR_MESSAGE); 139 } 140 return result; 141 } 142 143 @Override 144 public Bundle getAuthToken( 145 AccountAuthenticatorResponse response, 146 Account account, 147 String authTokenType, 148 Bundle options) throws NetworkErrorException { 149 if (!mAccountType.equals(account.type)) { 150 throw new IllegalArgumentException("Request to the wrong authenticator!"); 151 } 152 Bundle result = new Bundle(); 153 154 long expiryMillis = (options == null) 155 ? 0 : options.getLong(AccountManagerServiceTestFixtures.KEY_TOKEN_EXPIRY); 156 if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 157 // fill bundle with a success result. 158 result.putString( 159 AccountManager.KEY_AUTHTOKEN, AccountManagerServiceTestFixtures.AUTH_TOKEN); 160 result.putLong( 161 AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY, 162 expiryMillis); 163 result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 164 result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 165 } else if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE)) { 166 // Specify data to be returned by the eventual activity. 167 Intent eventualActivityResultData = new Intent(); 168 eventualActivityResultData.putExtra( 169 AccountManager.KEY_AUTHTOKEN, AccountManagerServiceTestFixtures.AUTH_TOKEN); 170 eventualActivityResultData.putExtra( 171 AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY, 172 expiryMillis); 173 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name); 174 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type); 175 176 // Fill result with Intent. 177 Intent intent = new Intent(mContext, AccountAuthenticatorDummyActivity.class); 178 intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT, 179 eventualActivityResultData); 180 intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response); 181 182 result.putParcelable(AccountManager.KEY_INTENT, intent); 183 184 } else { 185 fillResultWithError( 186 result, 187 AccountManager.ERROR_CODE_INVALID_RESPONSE, 188 AccountManagerServiceTestFixtures.ERROR_MESSAGE); 189 } 190 return result; 191 } 192 193 @Override 194 public String getAuthTokenLabel(String authTokenType) { 195 return AccountManagerServiceTestFixtures.AUTH_TOKEN_LABEL; 196 } 197 198 @Override 199 public Bundle updateCredentials( 200 AccountAuthenticatorResponse response, 201 Account account, 202 String authTokenType, 203 Bundle options) throws NetworkErrorException { 204 if (!mAccountType.equals(account.type)) { 205 throw new IllegalArgumentException("Request to the wrong authenticator!"); 206 } 207 Bundle result = new Bundle(); 208 209 if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 210 // fill bundle with a success result. 211 result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 212 result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 213 } else if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE)) { 214 // Specify data to be returned by the eventual activity. 215 Intent eventualActivityResultData = new Intent(); 216 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name); 217 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type); 218 219 // Fill result with Intent. 220 Intent intent = new Intent(mContext, AccountAuthenticatorDummyActivity.class); 221 intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT, 222 eventualActivityResultData); 223 intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response); 224 225 result.putParcelable(AccountManager.KEY_INTENT, intent); 226 } else { 227 // fill with error 228 fillResultWithError( 229 result, 230 AccountManager.ERROR_CODE_INVALID_RESPONSE, 231 AccountManagerServiceTestFixtures.ERROR_MESSAGE); 232 } 233 return result; 234 } 235 236 @Override 237 public Bundle hasFeatures( 238 AccountAuthenticatorResponse response, 239 Account account, 240 String[] features) throws NetworkErrorException { 241 Bundle result = new Bundle(); 242 if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 243 // fill bundle with true. 244 result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); 245 } else if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS_2)) { 246 result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); 247 } else if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE)) { 248 // fill bundle with false. 249 result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); 250 } else { 251 // return null for error 252 result = null; 253 } 254 255 response.onResult(result); 256 return null; 257 } 258 259 @Override 260 public Bundle startAddAccountSession( 261 AccountAuthenticatorResponse response, 262 String accountType, 263 String authTokenType, 264 String[] requiredFeatures, 265 Bundle options) throws NetworkErrorException { 266 if (!mAccountType.equals(accountType)) { 267 throw new IllegalArgumentException("Request to the wrong authenticator!"); 268 } 269 270 String accountName = null; 271 Bundle sessionBundle = null; 272 String password = null; 273 if (options != null) { 274 accountName = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME); 275 sessionBundle = options.getBundle( 276 AccountManagerServiceTestFixtures.KEY_ACCOUNT_SESSION_BUNDLE); 277 password = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_PASSWORD); 278 } 279 280 Bundle result = new Bundle(); 281 if (accountName.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 282 // fill bundle with a success result. 283 result.putBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE, sessionBundle); 284 result.putString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN, 285 AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN); 286 result.putString(AccountManager.KEY_PASSWORD, password); 287 result.putString(AccountManager.KEY_AUTHTOKEN, 288 Integer.toString(mTokenCounter.incrementAndGet())); 289 } else if (accountName.equals( 290 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE)) { 291 // Specify data to be returned by the eventual activity. 292 Intent eventualActivityResultData = new Intent(); 293 eventualActivityResultData.putExtra(AccountManager.KEY_AUTHTOKEN, 294 Integer.toString(mTokenCounter.incrementAndGet())); 295 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_STATUS_TOKEN, 296 AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN); 297 eventualActivityResultData.putExtra(AccountManager.KEY_PASSWORD, password); 298 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE, 299 sessionBundle); 300 // Fill result with Intent. 301 Intent intent = new Intent(mContext, AccountAuthenticatorDummyActivity.class); 302 intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT, 303 eventualActivityResultData); 304 intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response); 305 306 result.putParcelable(AccountManager.KEY_INTENT, intent); 307 } else { 308 // fill with error 309 fillResultWithError(result, options); 310 } 311 312 return result; 313 } 314 315 @Override 316 public Bundle startUpdateCredentialsSession( 317 AccountAuthenticatorResponse response, 318 Account account, 319 String authTokenType, 320 Bundle options) 321 throws NetworkErrorException { 322 323 if (!mAccountType.equals(account.type)) { 324 throw new IllegalArgumentException("Request to the wrong authenticator!"); 325 } 326 327 String accountName = null; 328 Bundle sessionBundle = null; 329 if (options != null) { 330 accountName = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME); 331 sessionBundle = options.getBundle( 332 AccountManagerServiceTestFixtures.KEY_ACCOUNT_SESSION_BUNDLE); 333 } 334 335 Bundle result = new Bundle(); 336 if (accountName.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 337 // fill bundle with a success result. 338 result.putBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE, sessionBundle); 339 result.putString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN, 340 AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN); 341 result.putString(AccountManager.KEY_PASSWORD, 342 AccountManagerServiceTestFixtures.ACCOUNT_PASSWORD); 343 result.putString(AccountManager.KEY_AUTHTOKEN, 344 Integer.toString(mTokenCounter.incrementAndGet())); 345 } else if (accountName.equals( 346 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE)) { 347 // Specify data to be returned by the eventual activity. 348 Intent eventualActivityResultData = new Intent(); 349 eventualActivityResultData.putExtra(AccountManager.KEY_AUTHTOKEN, 350 Integer.toString(mTokenCounter.incrementAndGet())); 351 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_STATUS_TOKEN, 352 AccountManagerServiceTestFixtures.ACCOUNT_STATUS_TOKEN); 353 eventualActivityResultData.putExtra(AccountManager.KEY_PASSWORD, 354 AccountManagerServiceTestFixtures.ACCOUNT_PASSWORD); 355 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE, 356 sessionBundle); 357 // Fill result with Intent. 358 Intent intent = new Intent(mContext, AccountAuthenticatorDummyActivity.class); 359 intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT, 360 eventualActivityResultData); 361 intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response); 362 363 result.putParcelable(AccountManager.KEY_INTENT, intent); 364 } else { 365 // fill with error 366 fillResultWithError(result, options); 367 } 368 return result; 369 } 370 371 @Override 372 public Bundle finishSession(AccountAuthenticatorResponse response, 373 String accountType, 374 Bundle sessionBundle) throws NetworkErrorException { 375 376 if (!mAccountType.equals(accountType)) { 377 throw new IllegalArgumentException("Request to the wrong authenticator!"); 378 } 379 380 String accountName = null; 381 if (sessionBundle != null) { 382 accountName = sessionBundle.getString( 383 AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME); 384 } 385 386 Bundle result = new Bundle(); 387 if (accountName.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 388 // add sessionBundle into result for verification purpose 389 result.putBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE, sessionBundle); 390 // fill bundle with a success result. 391 result.putString(AccountManager.KEY_ACCOUNT_NAME, 392 AccountManagerServiceTestFixtures.ACCOUNT_NAME); 393 result.putString(AccountManager.KEY_ACCOUNT_TYPE, 394 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1); 395 result.putString(AccountManager.KEY_AUTHTOKEN, 396 Integer.toString(mTokenCounter.incrementAndGet())); 397 } else if (accountName.equals( 398 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE)) { 399 // Specify data to be returned by the eventual activity. 400 Intent eventualActivityResultData = new Intent(); 401 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_NAME, 402 AccountManagerServiceTestFixtures.ACCOUNT_NAME); 403 eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_TYPE, 404 AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1); 405 eventualActivityResultData.putExtra(AccountManager.KEY_AUTHTOKEN, 406 Integer.toString(mTokenCounter.incrementAndGet())); 407 408 // Fill result with Intent. 409 Intent intent = new Intent(mContext, AccountAuthenticatorDummyActivity.class); 410 intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT, 411 eventualActivityResultData); 412 intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response); 413 414 result.putParcelable(AccountManager.KEY_INTENT, intent); 415 } else { 416 // fill with error 417 fillResultWithError(result, sessionBundle); 418 } 419 return result; 420 } 421 422 @Override 423 public Bundle isCredentialsUpdateSuggested( 424 final AccountAuthenticatorResponse response, 425 Account account, 426 String statusToken) throws NetworkErrorException { 427 428 Bundle result = new Bundle(); 429 if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 430 // fill bundle with a success result. 431 result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); 432 } else { 433 // fill with error 434 fillResultWithError( 435 result, 436 AccountManager.ERROR_CODE_INVALID_RESPONSE, 437 AccountManagerServiceTestFixtures.ERROR_MESSAGE); 438 } 439 440 response.onResult(result); 441 return null; 442 } 443 444 @Override 445 public Bundle getAccountRemovalAllowed( 446 AccountAuthenticatorResponse response, Account account) throws NetworkErrorException { 447 Bundle result = new Bundle(); 448 if (account.name.equals(AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS)) { 449 result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); 450 } else if (account.name.equals( 451 AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE)) { 452 Intent intent = new Intent(mContext, AccountAuthenticatorDummyActivity.class); 453 result.putParcelable(AccountManager.KEY_INTENT, intent); 454 } else { 455 result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); 456 } 457 return result; 458 } 459 460 private void fillResultWithError(Bundle result, Bundle options) { 461 int errorCode = AccountManager.ERROR_CODE_INVALID_RESPONSE; 462 String errorMsg = "Default Error Message"; 463 if (options != null) { 464 errorCode = options.getInt(AccountManager.KEY_ERROR_CODE); 465 errorMsg = options.getString(AccountManager.KEY_ERROR_MESSAGE); 466 } 467 fillResultWithError(result, errorCode, errorMsg); 468 } 469 470 private void fillResultWithError(Bundle result, int errorCode, String errorMsg) { 471 result.putInt(AccountManager.KEY_ERROR_CODE, errorCode); 472 result.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg); 473 } 474 }