Merge "Seeding CTS tests for ContactsContract." into eclair
diff --git a/tests/tests/accounts/AndroidManifest.xml b/tests/tests/accounts/AndroidManifest.xml
index 623e1ad..a54d423 100644
--- a/tests/tests/accounts/AndroidManifest.xml
+++ b/tests/tests/accounts/AndroidManifest.xml
@@ -22,12 +22,13 @@
     <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
     <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
 
     <application>
         <uses-library android:name="android.test.runner" />
 
         <service android:name="MockAccountService" android:exported="true"
-                android:process="android.accounts.cts">
+                 android:process="android.accounts.cts">
             <intent-filter>
                 <action android:name="android.accounts.AccountAuthenticator" />
             </intent-filter>
diff --git a/tests/tests/accounts/res/drawable/ic_cts_minitab_selected.png b/tests/tests/accounts/res/drawable/ic_cts_minitab_selected.png
index 73b0b38..c730050 100644
--- a/tests/tests/accounts/res/drawable/ic_cts_minitab_selected.png
+++ b/tests/tests/accounts/res/drawable/ic_cts_minitab_selected.png
Binary files differ
diff --git a/tests/tests/accounts/res/drawable/ic_cts_selected.png b/tests/tests/accounts/res/drawable/ic_cts_selected.png
index 0af7914..72a065c 100644
--- a/tests/tests/accounts/res/drawable/ic_cts_selected.png
+++ b/tests/tests/accounts/res/drawable/ic_cts_selected.png
Binary files differ
diff --git a/tests/tests/accounts/res/values/strings.xml b/tests/tests/accounts/res/values/strings.xml
index 6f12b72..442669b 100644
--- a/tests/tests/accounts/res/values/strings.xml
+++ b/tests/tests/accounts/res/values/strings.xml
@@ -19,5 +19,5 @@
 
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Label for this package -->
-    <string name="label">Android CTS</string>
+    <string name="label">Android CTS - Account</string>
 </resources>
\ No newline at end of file
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
index 0a86a5e..d625b06 100644
--- a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
@@ -16,49 +16,1105 @@
 
 package android.accounts.cts;
 
-import dalvik.annotation.KnownFailure;
-
 import android.accounts.Account;
 import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
 import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorDescription;
+import android.accounts.AuthenticatorException;
+import android.accounts.OnAccountsUpdateListener;
+import android.accounts.OperationCanceledException;
+import android.app.Activity;
+import android.content.Context;
 import android.os.Bundle;
+import android.os.Handler;
 import android.test.AndroidTestCase;
 
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 public class AccountManagerTest extends AndroidTestCase {
 
-    @KnownFailure(value="failure removing account bug 2342468")
-    public void testAddAndRemoveAccount() throws Exception {
-        AccountManager am = AccountManager.get(getContext());
+    public static final String ACCOUNT_NAME = "android.accounts.cts.account.name";
+    public static final String ACCOUNT_NAME_OTHER = "android.accounts.cts.account.name.other";
 
+    public static final String ACCOUNT_TYPE = "android.accounts.cts.account.type";
+    public static final String ACCOUNT_TYPE_OTHER = "android.accounts.cts.account.type.other";
+
+    public static final String ACCOUNT_PASSWORD = "android.accounts.cts.account.password";
+
+    public static final String AUTH_TOKEN = "mockAuthToken";
+    public static final String AUTH_TOKEN_TYPE = "mockAuthTokenType";
+    public static final String AUTH_TOKEN_LABEL = "mockAuthTokenLabel";
+
+    public static final String FEATURE_1 = "feature.1";
+    public static final String FEATURE_2 = "feature.2";
+    public static final String NON_EXISTING_FEATURE = "feature.3";
+
+    public static final String OPTION_NAME_1 = "option.name.1";
+    public static final String OPTION_VALUE_1 = "option.value.1";
+
+    public static final String OPTION_NAME_2 = "option.name.2";
+    public static final String OPTION_VALUE_2 = "option.value.2";
+
+    public static final String[] REQUIRED_FEATURES = new String[] { FEATURE_1, FEATURE_2 };
+
+    public static final Activity ACTIVITY = new Activity();
+    public static final Bundle OPTIONS_BUNDLE = new Bundle();
+
+    public static final Bundle USERDATA_BUNDLE = new Bundle();
+
+    public static final String USERDATA_NAME_1 = "user.data.name.1";
+    public static final String USERDATA_NAME_2 = "user.data.name.2";
+    public static final String USERDATA_VALUE_1 = "user.data.value.1";
+    public static final String USERDATA_VALUE_2 = "user.data.value.2";
+
+    public static final Account ACCOUNT = new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
+    public static final Account ACCOUNT_SAME_TYPE = new Account(ACCOUNT_NAME_OTHER, ACCOUNT_TYPE);
+
+    private static MockAccountAuthenticator mockAuthenticator;
+    private static final int LATCH_TIMEOUT_MS = 500;
+    private static AccountManager am;
+
+    public synchronized static MockAccountAuthenticator getMockAuthenticator(Context context) {
+        if (null == mockAuthenticator) {
+            mockAuthenticator = new MockAccountAuthenticator(context);
+        }
+        return mockAuthenticator;
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        OPTIONS_BUNDLE.putString(OPTION_NAME_1, OPTION_VALUE_1);
+        OPTIONS_BUNDLE.putString(OPTION_NAME_2, OPTION_VALUE_2);
+
+        USERDATA_BUNDLE.putString(USERDATA_NAME_1, USERDATA_VALUE_1);
+
+        getMockAuthenticator(getContext());
+
+        am = AccountManager.get(getContext());
+    }
+
+    @Override
+    public void tearDown() throws Exception, AuthenticatorException, OperationCanceledException {
+        mockAuthenticator.clearData();
+
+        // Need to clean up created account
+        assertTrue(removeAccount(am, ACCOUNT, null /* callback */));
+        assertTrue(removeAccount(am, ACCOUNT_SAME_TYPE, null /* callback */));
+
+        // need to clean up the authenticator cached data
+        mockAuthenticator.clearData();
+
+        super.tearDown();
+    }
+
+    private void validateNonNullResult(Bundle result) {
+        assertEquals(ACCOUNT_NAME, result.get(AccountManager.KEY_ACCOUNT_NAME));
+        assertEquals(ACCOUNT_TYPE, result.get(AccountManager.KEY_ACCOUNT_TYPE));
+        assertEquals(AUTH_TOKEN, result.get(AccountManager.KEY_AUTHTOKEN));
+    }
+
+    private void validateNullResult(Bundle resultBundle) {
+        assertNull(resultBundle.get(AccountManager.KEY_ACCOUNT_NAME));
+        assertNull(resultBundle.get(AccountManager.KEY_ACCOUNT_TYPE));
+        assertNull(resultBundle.get(AccountManager.KEY_AUTHTOKEN));
+    }
+
+    private void validateAccountAndAuthTokenType() {
+        assertEquals(ACCOUNT_TYPE, mockAuthenticator.getAccountType());
+        assertEquals(AUTH_TOKEN_TYPE, mockAuthenticator.getAuthTokenType());
+    }
+
+    private void validateFeatures() {
+        assertEquals(REQUIRED_FEATURES[0], mockAuthenticator.getRequiredFeatures()[0]);
+        assertEquals(REQUIRED_FEATURES[1], mockAuthenticator.getRequiredFeatures()[1]);
+    }
+
+    private void validateOptions() {
+        assertNotNull(mockAuthenticator.getOptions());
+        assertEquals(OPTION_VALUE_1, mockAuthenticator.getOptions().get(OPTION_NAME_1));
+        assertEquals(OPTION_VALUE_2, mockAuthenticator.getOptions().get(OPTION_NAME_2));
+    }
+
+    private void validateCredentials() {
+        assertEquals(ACCOUNT, mockAuthenticator.getAccount());
+
+        assertEquals(OPTION_VALUE_1, mockAuthenticator.getOptions().get(OPTION_NAME_1));
+        assertEquals(OPTION_VALUE_2, mockAuthenticator.getOptions().get(OPTION_NAME_2));
+    }
+
+    private int getAccountsCount() {
         Account[] accounts = am.getAccounts();
         assertNotNull(accounts);
-        final int accountsCount = accounts.length;
+        return accounts.length;
+    }
+
+    private Bundle addAccount(AccountManager am, String accountType, String authTokenType,
+            String[] requiredFeatures, Bundle options, Activity activity,
+            AccountManagerCallback<Bundle> callback, Handler handler) throws
+                IOException, AuthenticatorException, OperationCanceledException {
 
         AccountManagerFuture<Bundle> futureBundle = am.addAccount(
-                MockAccountAuthenticator.MOCK_ACCOUNT_TYPE,
-                MockAccountAuthenticator.MOCK_AUTH_TOKEN_TYPE,
-                null, null, null, null, null);
+                accountType,
+                authTokenType,
+                requiredFeatures,
+                options,
+                activity,
+                callback,
+                handler);
 
         Bundle resultBundle = futureBundle.getResult();
         assertTrue(futureBundle.isDone());
         assertNotNull(resultBundle);
-        assertEquals(MockAccountAuthenticator.MOCK_ACCOUNT_NAME,
-                resultBundle.get(AccountManager.KEY_ACCOUNT_NAME));
-        assertEquals(MockAccountAuthenticator.MOCK_ACCOUNT_TYPE,
-                resultBundle.get(AccountManager.KEY_ACCOUNT_TYPE));
-        assertNotNull(resultBundle.get(AccountManager.KEY_AUTHTOKEN));
 
-        accounts = am.getAccounts();
-        assertNotNull(accounts);
-        assertEquals(1 + accountsCount, accounts.length);
+        return resultBundle;
+    }
 
-        AccountManagerFuture<Boolean> futureBoolean = am.removeAccount(accounts[0], null, null);
+    private boolean removeAccount(AccountManager am, Account account,
+            AccountManagerCallback<Boolean> callback) throws IOException, AuthenticatorException,
+                OperationCanceledException {
+
+        AccountManagerFuture<Boolean> futureBoolean = am.removeAccount(account,
+                callback,
+                null /* handler */);
         Boolean resultBoolean = futureBoolean.getResult();
         assertTrue(futureBoolean.isDone());
-        assertNotNull(resultBoolean);
 
+        return resultBoolean;
+    }
+
+    private void addAccountExplicitly(Account account, String password, Bundle userdata) {
+        assertTrue(am.addAccountExplicitly(account, password, userdata));
+    }
+
+    private Bundle getAuthTokenByFeature(String[] features, Activity activity)
+            throws IOException, AuthenticatorException, OperationCanceledException {
+
+        AccountManagerFuture<Bundle> futureBundle = am.getAuthTokenByFeatures(ACCOUNT_TYPE,
+                AUTH_TOKEN_TYPE,
+                features,
+                activity,
+                OPTIONS_BUNDLE,
+                OPTIONS_BUNDLE,
+                null /* no callback */,
+                null /* no handler */
+        );
+
+        Bundle resultBundle = futureBundle.getResult();
+
+        assertTrue(futureBundle.isDone());
+        assertNotNull(resultBundle);
+
+        return resultBundle;
+    }
+
+    private boolean isAccountPresent(Account[] accounts, Account accountToCheck) {
+        if (null == accounts || null == accountToCheck) {
+            return false;
+        }
+        boolean result = false;
+        int length = accounts.length;
+        for (int n=0; n<length; n++) {
+            if(accountToCheck.equals(accounts[n])) {
+                result = true;
+                break;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Test singleton
+     */
+    public void testGet() {
+        assertNotNull(AccountManager.get(getContext()));
+    }
+
+    /**
+     * Test a basic addAccount()
+     */
+    public void testAddAccount() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        Bundle resultBundle = addAccount(am,
+                ACCOUNT_TYPE,
+                AUTH_TOKEN_TYPE,
+                REQUIRED_FEATURES,
+                OPTIONS_BUNDLE,
+                ACTIVITY,
+                null /* callback */,
+                null /* handler */);
+
+        // Assert parameters has been passed correctly
+        validateAccountAndAuthTokenType();
+        validateFeatures();
+        validateOptions();
+
+        // Assert returned result
+        validateNonNullResult(resultBundle);
+    }
+
+    /**
+     * Test addAccount() with callback and handler
+     */
+    public void testAddAccountWithCallbackAndHandler() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        testAddAccountWithCallbackAndHandler(null /* handler */);
+        testAddAccountWithCallbackAndHandler(new Handler());
+    }
+
+    private void testAddAccountWithCallbackAndHandler(Handler handler) throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            public void run(AccountManagerFuture<Bundle> bundleFuture) {
+                Bundle resultBundle = null;
+                try {
+                    resultBundle = bundleFuture.getResult();
+                } catch (OperationCanceledException e) {
+                    fail("should not throw an OperationCanceledException");
+                } catch (IOException e) {
+                    fail("should not throw an IOException");
+                } catch (AuthenticatorException e) {
+                    fail("should not throw an AuthenticatorException");
+                }
+
+                // Assert parameters has been passed correctly
+                validateAccountAndAuthTokenType();
+                validateFeatures();
+                validateOptions();
+
+                // Assert return result
+                validateNonNullResult(resultBundle);
+
+                latch.countDown();
+            }
+        };
+
+        Bundle resultBundle = addAccount(am,
+                ACCOUNT_TYPE,
+                AUTH_TOKEN_TYPE,
+                REQUIRED_FEATURES,
+                OPTIONS_BUNDLE,
+                ACTIVITY,
+                callback,
+                handler);
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+    }
+
+    /**
+     * Test addAccountExplicitly() and removeAccount()
+     */
+    public void testAddAccountExplicitlyAndRemoveAccount() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        final int accountsCount = getAccountsCount();
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        // Assert that we have one more account
+        Account[] accounts = am.getAccounts();
+        assertNotNull(accounts);
+        assertEquals(1 + accountsCount, accounts.length);
+        assertTrue(isAccountPresent(am.getAccounts(), ACCOUNT));
+
+        // Need to clean up
+        assertTrue(removeAccount(am, ACCOUNT, null /* callback */));
+
+        // and verify that we go back to the initial state
         accounts = am.getAccounts();
         assertNotNull(accounts);
         assertEquals(accountsCount, accounts.length);
     }
+
+    /**
+     * Test getAccounts() and getAccountsByType()
+     */
+    public void testGetAccountsAndGetAccountsByType() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        assertEquals(false, isAccountPresent(am.getAccounts(), ACCOUNT));
+        assertEquals(false, isAccountPresent(am.getAccounts(), ACCOUNT_SAME_TYPE));
+
+        final int accountsCount = getAccountsCount();
+
+        // Add a first account
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        // Check that we have the new account
+        Account[] accounts = am.getAccounts();
+        assertEquals(1 + accountsCount, accounts.length);
+        assertEquals(true, isAccountPresent(accounts, ACCOUNT));
+
+        // Add another account
+        addAccountExplicitly(ACCOUNT_SAME_TYPE, ACCOUNT_PASSWORD, null /* userData */);
+
+        // Check that we have one more account again
+        accounts = am.getAccounts();
+        assertEquals(2 + accountsCount, accounts.length);
+        assertEquals(true, isAccountPresent(accounts, ACCOUNT_SAME_TYPE));
+
+        // Check if we have one from first type
+        accounts = am.getAccountsByType(ACCOUNT_TYPE);
+        assertEquals(2, accounts.length);
+
+        // Check if we dont have any account from the other type
+        accounts = am.getAccountsByType(ACCOUNT_TYPE_OTHER);
+        assertEquals(0, accounts.length);
+    }
+
+    /**
+     * Test getAuthenticatorTypes()
+     */
+    public void testGetAuthenticatorTypes() {
+        AuthenticatorDescription[] types = am.getAuthenticatorTypes();
+        for(AuthenticatorDescription description: types) {
+            if (description.type.equals(ACCOUNT_TYPE)) {
+                return;
+            }
+        }
+        fail("should have found Authenticator type: " + ACCOUNT_TYPE);
+    }
+
+    /**
+     * Test setPassword() and getPassword()
+     */
+    public void testSetAndGetAndClearPassword() {
+        // Add a first account
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        // Check that the password is the one we defined
+        assertEquals(ACCOUNT_PASSWORD, am.getPassword(ACCOUNT));
+
+        // Clear the password and check that it is cleared
+        am.clearPassword(ACCOUNT);
+        assertNull(am.getPassword(ACCOUNT));
+
+        // Reset the password
+        am.setPassword(ACCOUNT, ACCOUNT_PASSWORD);
+
+        // Check that the password is the one we defined
+        assertEquals(ACCOUNT_PASSWORD, am.getPassword(ACCOUNT));
+    }
+
+    /**
+     * Test setUserData() and getUserData()
+     */
+    public void testSetAndGetUserData() {
+        // Add a first account
+        boolean result = am.addAccountExplicitly(ACCOUNT,
+                                ACCOUNT_PASSWORD,
+                                USERDATA_BUNDLE);
+
+        assertTrue(result);
+
+        // Check that the UserData is the one we defined
+        assertEquals(USERDATA_VALUE_1, am.getUserData(ACCOUNT, USERDATA_NAME_1));
+
+        am.setUserData(ACCOUNT, USERDATA_NAME_2, USERDATA_VALUE_2);
+
+        // Check that the UserData is the one we defined
+        assertEquals(USERDATA_VALUE_2, am.getUserData(ACCOUNT, USERDATA_NAME_2));
+    }
+
+    /**
+     * Test getAccountsByTypeAndFeatures()
+     */
+    public void testGetAccountsByTypeAndFeatures() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        AccountManagerFuture<Account[]> futureAccounts = am.getAccountsByTypeAndFeatures(
+                ACCOUNT_TYPE, REQUIRED_FEATURES, null, null);
+
+        Account[] accounts = futureAccounts.getResult();
+
+        assertNotNull(accounts);
+        assertEquals(1, accounts.length);
+        assertEquals(true, isAccountPresent(accounts, ACCOUNT));
+
+        futureAccounts = am.getAccountsByTypeAndFeatures(ACCOUNT_TYPE,
+                new String[] { NON_EXISTING_FEATURE },
+                null /* callback*/,
+                null /* handler */);
+        accounts = futureAccounts.getResult();
+
+        assertNotNull(accounts);
+        assertEquals(0, accounts.length);
+    }
+
+    /**
+     * Test getAccountsByTypeAndFeatures() with callback and handler
+     */
+    public void testGetAccountsByTypeAndFeaturesWithCallbackAndHandler() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        testGetAccountsByTypeAndFeaturesWithCallbackAndHandler(null /* handler */);
+        testGetAccountsByTypeAndFeaturesWithCallbackAndHandler(new Handler());
+    }
+
+    private void testGetAccountsByTypeAndFeaturesWithCallbackAndHandler(Handler handler) throws
+            IOException, AuthenticatorException, OperationCanceledException {
+
+        final CountDownLatch latch1 = new CountDownLatch(1);
+
+        AccountManagerCallback<Account[]> callback1 = new AccountManagerCallback<Account[]>() {
+            public void run(AccountManagerFuture<Account[]> accountsFuture) {
+                try {
+                    Account[] accounts = accountsFuture.getResult();
+                    assertNotNull(accounts);
+                    assertEquals(1, accounts.length);
+                    assertEquals(true, isAccountPresent(accounts, ACCOUNT));
+                } catch (OperationCanceledException e) {
+                    fail("should not throw an OperationCanceledException");
+                } catch (IOException e) {
+                    fail("should not throw an IOException");
+                } catch (AuthenticatorException e) {
+                    fail("should not throw an AuthenticatorException");
+                } finally {
+                  latch1.countDown();
+                }
+            }
+        };
+
+        AccountManagerFuture<Account[]> futureAccounts = am.getAccountsByTypeAndFeatures(
+                ACCOUNT_TYPE,
+                REQUIRED_FEATURES,
+                callback1,
+                handler);
+
+        Account[] accounts = futureAccounts.getResult();
+
+        assertNotNull(accounts);
+        assertEquals(1, accounts.length);
+        assertEquals(true, isAccountPresent(accounts, ACCOUNT));
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch1.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+
+        final CountDownLatch latch2 = new CountDownLatch(1);
+
+        AccountManagerCallback<Account[]> callback2 = new AccountManagerCallback<Account[]>() {
+            public void run(AccountManagerFuture<Account[]> accountsFuture) {
+                try {
+                    Account[] accounts = accountsFuture.getResult();
+                    assertNotNull(accounts);
+                    assertEquals(0, accounts.length);
+                } catch (OperationCanceledException e) {
+                    fail("should not throw an OperationCanceledException");
+                } catch (IOException e) {
+                    fail("should not throw an IOException");
+                } catch (AuthenticatorException e) {
+                    fail("should not throw an AuthenticatorException");
+                } finally {
+                  latch2.countDown();
+                }
+            }
+        };
+
+        accounts = null;
+
+        futureAccounts = am.getAccountsByTypeAndFeatures(ACCOUNT_TYPE,
+                new String[] { NON_EXISTING_FEATURE },
+                callback2,
+                handler);
+
+        accounts = futureAccounts.getResult();
+        assertNotNull(accounts);
+        assertEquals(0, accounts.length);
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch2.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+    }
+
+    /**
+     * Test setAuthToken() and peekAuthToken()
+     */
+    public void testSetAndPeekAndInvalidateAuthToken() {
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        am.setAuthToken(ACCOUNT, AUTH_TOKEN_TYPE, AUTH_TOKEN);
+
+        // Ask for the AuthToken
+        String token = am.peekAuthToken(ACCOUNT, AUTH_TOKEN_TYPE);
+        assertNotNull(token);
+        assertEquals(AUTH_TOKEN, token);
+
+        am.invalidateAuthToken(ACCOUNT_TYPE, AUTH_TOKEN);
+        token = am.peekAuthToken(ACCOUNT, AUTH_TOKEN_TYPE);
+        assertNull(token);
+    }
+
+    /**
+     * Test blockingGetAuthToken()
+     */
+    public void testBlockingGetAuthToken() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null);
+
+        String token = am.blockingGetAuthToken(ACCOUNT,
+                AUTH_TOKEN_TYPE,
+                false /* no failure notification */);
+
+        // Ask for the AuthToken
+        assertNotNull(token);
+        assertEquals(AUTH_TOKEN, token);
+    }
+
+    /**
+     * Test getAuthToken()
+     */
+    public void testGetAuthToken() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        AccountManagerFuture<Bundle> futureBundle = am.getAuthToken(ACCOUNT,
+                AUTH_TOKEN_TYPE,
+                false /* no failure notification */,
+                null /* no callback */,
+                null /* no handler */
+        );
+
+        Bundle resultBundle = futureBundle.getResult();
+
+        assertTrue(futureBundle.isDone());
+        assertNotNull(resultBundle);
+
+        // Assert returned result
+        validateNonNullResult(resultBundle);
+    }
+
+    /**
+     * Test getAuthToken() with callback and handler
+     */
+    public void testGetAuthTokenWithCallbackAndHandler() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        testGetAuthTokenWithCallbackAndHandler(null /* handler */);
+        testGetAuthTokenWithCallbackAndHandler(new Handler());
+    }
+
+    private void testGetAuthTokenWithCallbackAndHandler(Handler handler) throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            public void run(AccountManagerFuture<Bundle> bundleFuture) {
+
+                Bundle resultBundle = null;
+                try {
+                    resultBundle = bundleFuture.getResult();
+
+                    // Assert returned result
+                    validateNonNullResult(resultBundle);
+
+                } catch (OperationCanceledException e) {
+                    fail("should not throw an OperationCanceledException");
+                } catch (IOException e) {
+                    fail("should not throw an IOException");
+                } catch (AuthenticatorException e) {
+                    fail("should not throw an AuthenticatorException");
+                }
+                finally {
+                    latch.countDown();
+                }
+            }
+        };
+
+        AccountManagerFuture<Bundle> futureBundle = am.getAuthToken(ACCOUNT,
+                AUTH_TOKEN_TYPE,
+                false /* no failure notification */,
+                callback,
+                handler
+        );
+
+        Bundle resultBundle = futureBundle.getResult();
+
+        assertTrue(futureBundle.isDone());
+        assertNotNull(resultBundle);
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+    }
+
+    /**
+     * test getAuthToken() with options
+     */
+    public void testGetAuthTokenWithOptions() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        AccountManagerFuture<Bundle> futureBundle = am.getAuthToken(ACCOUNT,
+                AUTH_TOKEN_TYPE,
+                OPTIONS_BUNDLE,
+                ACTIVITY,
+                null /* no callback */,
+                null /* no handler */
+        );
+
+        Bundle resultBundle = futureBundle.getResult();
+
+        assertTrue(futureBundle.isDone());
+        assertNotNull(resultBundle);
+
+        // Assert returned result
+        validateNonNullResult(resultBundle);
+
+        validateOptions();
+    }
+
+    /**
+     * test getAuthToken() with options and callback and handler
+     */
+    public void testGetAuthTokenWithOptionsAndCallback() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        testGetAuthTokenWithOptionsAndCallbackAndHandler(null /* handler */);
+        testGetAuthTokenWithOptionsAndCallbackAndHandler(new Handler());
+    }
+
+    private void testGetAuthTokenWithOptionsAndCallbackAndHandler(Handler handler) throws
+            IOException, AuthenticatorException, OperationCanceledException {
+
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            public void run(AccountManagerFuture<Bundle> bundleFuture) {
+
+                Bundle resultBundle = null;
+                try {
+                    resultBundle = bundleFuture.getResult();
+
+                    // Assert returned result
+                    validateNonNullResult(resultBundle);
+
+                } catch (OperationCanceledException e) {
+                    fail("should not throw an OperationCanceledException");
+                } catch (IOException e) {
+                    fail("should not throw an IOException");
+                } catch (AuthenticatorException e) {
+                    fail("should not throw an AuthenticatorException");
+                }
+                finally {
+                    latch.countDown();
+                }
+            }
+        };
+
+        AccountManagerFuture<Bundle> futureBundle = am.getAuthToken(ACCOUNT,
+                AUTH_TOKEN_TYPE,
+                OPTIONS_BUNDLE,
+                ACTIVITY,
+                callback,
+                handler
+        );
+
+        Bundle resultBundle = futureBundle.getResult();
+
+        assertTrue(futureBundle.isDone());
+        assertNotNull(resultBundle);
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+    }
+
+    /**
+     * Test getAuthTokenByFeatures()
+     */
+    public void testGetAuthTokenByFeatures() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        Bundle resultBundle = getAuthTokenByFeature(
+                new String[] { NON_EXISTING_FEATURE },
+                null /* activity */
+        );
+
+        // Assert returned result
+        validateNullResult(resultBundle);
+
+        assertNull(mockAuthenticator.getOptions());
+        mockAuthenticator.clearData();
+
+        // Now test with existing features and an activity
+        resultBundle = getAuthTokenByFeature(
+                new String[] { NON_EXISTING_FEATURE },
+                ACTIVITY
+        );
+
+        // Assert returned result
+        validateNonNullResult(resultBundle);
+
+        validateOptions();
+        mockAuthenticator.clearData();
+
+        // Now test with existing features and no activity
+        resultBundle = getAuthTokenByFeature(
+                REQUIRED_FEATURES,
+                null /* activity */
+        );
+
+        // Assert returned result
+        validateNonNullResult(resultBundle);
+
+        assertNull(mockAuthenticator.getOptions());
+        mockAuthenticator.clearData();
+
+        // Now test with existing features and an activity
+        resultBundle = getAuthTokenByFeature(
+                REQUIRED_FEATURES,
+                ACTIVITY
+        );
+
+        // Assert returned result
+        validateNonNullResult(resultBundle);
+
+        assertNull(mockAuthenticator.getOptions());
+    }
+
+    /**
+     * Test confirmCredentials()
+     */
+    public void testConfirmCredentials() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        AccountManagerFuture<Bundle> futureBundle = am.confirmCredentials(ACCOUNT,
+                OPTIONS_BUNDLE,
+                ACTIVITY,
+                null /* callback*/,
+                null /* handler */);
+
+        futureBundle.getResult();
+
+        // Assert returned result
+        validateCredentials();
+    }
+
+    /**
+     * Test confirmCredentials() with callback
+     */
+    public void testConfirmCredentialsWithCallbackAndHandler() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        testConfirmCredentialsWithCallbackAndHandler(null /* handler */);
+        testConfirmCredentialsWithCallbackAndHandler(new Handler());
+    }
+
+    private void testConfirmCredentialsWithCallbackAndHandler(Handler handler) throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            public void run(AccountManagerFuture<Bundle> bundleFuture) {
+
+                Bundle resultBundle = null;
+                try {
+                    resultBundle = bundleFuture.getResult();
+
+                    // Assert returned result
+                    validateCredentials();
+
+                } catch (OperationCanceledException e) {
+                    fail("should not throw an OperationCanceledException");
+                } catch (IOException e) {
+                    fail("should not throw an IOException");
+                } catch (AuthenticatorException e) {
+                    fail("should not throw an AuthenticatorException");
+                }
+                finally {
+                    latch.countDown();
+                }
+            }
+        };
+
+        AccountManagerFuture<Bundle> futureBundle = am.confirmCredentials(ACCOUNT,
+                OPTIONS_BUNDLE,
+                ACTIVITY,
+                callback,
+                handler);
+
+        futureBundle.getResult();
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+    }
+
+    /**
+     * Test updateCredentials()
+     */
+    public void testUpdateCredentials() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        AccountManagerFuture<Bundle> futureBundle = am.updateCredentials(ACCOUNT,
+                AUTH_TOKEN_TYPE,
+                OPTIONS_BUNDLE,
+                ACTIVITY,
+                null /* callback*/,
+                null /* handler */);
+
+        futureBundle.getResult();
+
+        // Assert returned result
+        validateCredentials();
+    }
+
+    /**
+     * Test updateCredentials() with callback and handler
+     */
+    public void testUpdateCredentialsWithCallbackAndHandler() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        testUpdateCredentialsWithCallbackAndHandler(null /* handler */);
+        testUpdateCredentialsWithCallbackAndHandler(new Handler());
+    }
+
+    private void testUpdateCredentialsWithCallbackAndHandler(Handler handler) throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            public void run(AccountManagerFuture<Bundle> bundleFuture) {
+
+                Bundle resultBundle = null;
+                try {
+                    resultBundle = bundleFuture.getResult();
+
+                    // Assert returned result
+                    validateCredentials();
+
+                } catch (OperationCanceledException e) {
+                    fail("should not throw an OperationCanceledException");
+                } catch (IOException e) {
+                    fail("should not throw an IOException");
+                } catch (AuthenticatorException e) {
+                    fail("should not throw an AuthenticatorException");
+                }
+                finally {
+                    latch.countDown();
+                }
+            }
+        };
+
+        AccountManagerFuture<Bundle> futureBundle = am.updateCredentials(ACCOUNT,
+                AUTH_TOKEN_TYPE,
+                OPTIONS_BUNDLE,
+                ACTIVITY,
+                callback,
+                handler);
+
+        futureBundle.getResult();
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+    }
+
+    /**
+     * Test editProperties()
+     */
+    public void testEditProperties() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        AccountManagerFuture<Bundle> futureBundle = am.editProperties(ACCOUNT_TYPE,
+                ACTIVITY,
+                null /* callback */,
+                null /* handler*/);
+
+        futureBundle.getResult();
+
+        // Assert returned result
+        assertEquals(ACCOUNT_TYPE, mockAuthenticator.getAccountType());
+    }
+
+    /**
+     * Test editProperties() with callback and handler
+     */
+    public void testEditPropertiesWithCallbackAndHandler() {
+        testEditPropertiesWithCallbackAndHandler(null /* handler */);
+        testEditPropertiesWithCallbackAndHandler(new Handler());
+    }
+
+    private void testEditPropertiesWithCallbackAndHandler(Handler handler) {
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            public void run(AccountManagerFuture<Bundle> bundleFuture) {
+                try {
+                    // Assert returned result
+                    assertEquals(ACCOUNT_TYPE, mockAuthenticator.getAccountType());
+                }
+                finally {
+                    latch.countDown();
+                }
+            }
+        };
+
+        AccountManagerFuture<Bundle> futureBundle = am.editProperties(ACCOUNT_TYPE,
+                ACTIVITY,
+                callback,
+                handler);
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+    }
+
+    /**
+     * Test addOnAccountsUpdatedListener() with handler
+     */
+    public void testAddOnAccountsUpdatedListenerWithHandler() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        testAddOnAccountsUpdatedListenerWithHandler(null /* handler */,
+                false /* updateImmediately */);
+
+        // Need to cleanup intermediate state
+        assertTrue(removeAccount(am, ACCOUNT, null /* callback */));
+
+        testAddOnAccountsUpdatedListenerWithHandler(null /* handler */,
+                true /* updateImmediately */);
+
+        // Need to cleanup intermediate state
+        assertTrue(removeAccount(am, ACCOUNT, null /* callback */));
+
+        testAddOnAccountsUpdatedListenerWithHandler(new Handler(),
+                false /* updateImmediately */);
+
+        // Need to cleanup intermediate state
+        assertTrue(removeAccount(am, ACCOUNT, null /* callback */));
+
+        testAddOnAccountsUpdatedListenerWithHandler(new Handler(),
+                true /* updateImmediately */);
+    }
+
+    private void testAddOnAccountsUpdatedListenerWithHandler(Handler handler,
+            boolean updateImmediately) {
+
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        OnAccountsUpdateListener listener = new OnAccountsUpdateListener() {
+            public void onAccountsUpdated(Account[] accounts) {
+                latch.countDown();
+            }
+        };
+
+        // Add a listener
+        am.addOnAccountsUpdatedListener(listener,
+                handler,
+                updateImmediately);
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+
+        // Cleanup
+        am.removeOnAccountsUpdatedListener(listener);
+    }
+
+    /**
+     * Test removeOnAccountsUpdatedListener() with handler
+     */
+    public void testRemoveOnAccountsUpdatedListener() throws IOException, AuthenticatorException,
+            OperationCanceledException {
+
+        testRemoveOnAccountsUpdatedListenerWithHandler(null /* handler */);
+
+        // Need to cleanup intermediate state
+        assertTrue(removeAccount(am, ACCOUNT, null /* callback */));
+
+        testRemoveOnAccountsUpdatedListenerWithHandler(new Handler());
+    }
+
+    private void testRemoveOnAccountsUpdatedListenerWithHandler(Handler handler) {
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        OnAccountsUpdateListener listener = new OnAccountsUpdateListener() {
+            public void onAccountsUpdated(Account[] accounts) {
+                fail("should not be called");
+            }
+        };
+
+        // First add a listener
+        am.addOnAccountsUpdatedListener(listener,
+                handler,
+                false /* updateImmediately */);
+
+        // Then remove the listener
+        am.removeOnAccountsUpdatedListener(listener);
+
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        // Wait with timeout for the callback to do its work
+        try {
+            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("should not throw an InterruptedException");
+        }
+    }
 }
diff --git a/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java b/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
index 19d9f57..9843385 100644
--- a/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
+++ b/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
@@ -16,61 +16,84 @@
 
 package android.accounts.cts;
 
-import android.accounts.*;
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.NetworkErrorException;
 import android.content.Context;
 import android.os.Bundle;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * A simple Mock Account Authenticator
  */
 public class MockAccountAuthenticator extends AbstractAccountAuthenticator {
 
-    public static final String MOCK_ACCOUNT_NAME = "android.accounts.cts.account.name";
-    public static final String MOCK_ACCOUNT_TYPE = "android.accounts.cts.account.type";
-    public static final String MOCK_ACCOUNT_PASSWORD = "android.accounts.cts.account.password";
-    public static final String MOCK_AUTH_TOKEN = "mockAuthToken";
-    public static final String MOCK_AUTH_TOKEN_TYPE = "mockAuthTokenType";
-    public static final String MOCK_AUTH_TOKEN_LABEL = "mockAuthTokenLabel";
-
-    public static final int ERROR_CODE_ACCOUNT_TYPE = 11;
-    public static final String ERROR_MESSAGE_ACCOUNT_TYPE = "Account Type Unknown";
-
-    public static final int ERROR_CODE_ACCOUNT_CANNOT_ADD = 12;
-    public static final String ERROR_MESSAGE_ACCOUNT_CANNOT_ADD = "Cannot add account explicitely";
-
-    public static final int ERROR_CODE_ACCOUNT_UNKNOWN = 13;
-    public static final String ERROR_MESSAGE_ACCOUNT_UNKNOWN = "Account Unknown";
-
-    public static final int ERROR_CODE_AUTH_TOKEN_TYPE = 21;
-    public static final String ERROR_MESSAGE_AUTH_TOKEN_TYPE = "Auth Token Unknown";
-
-    public static final int ERROR_CODE_FEATURE_UNKNOWN = 31;
-    public static final String ERROR_MESSAGE_FEATURE_UNKNOWN = "Feature Unknown";
-
-    public static final String MOCK_FEATURE_1 = "feature1";
-    public static final String MOCK_FEATURE_2 = "feature2";
-
-    private final Map<String, Map<Integer, Account>> accountMapByType;
-    private final Context mContext;
+    private AccountAuthenticatorResponse mResponse;
+    private String mAccountType;
+    private String mAuthTokenType;
+    private String[] mRequiredFeatures;
+    private Bundle mOptions;
+    private Account mAccount;
+    private String[] mFeatures;
 
     private final ArrayList<String> mockFeatureList = new ArrayList<String>();
 
     public MockAccountAuthenticator(Context context) {
         super(context);
 
-        accountMapByType = new HashMap<String, Map<Integer, Account>>();
+        // Create some mock features
+        mockFeatureList.add(AccountManagerTest.FEATURE_1);
+        mockFeatureList.add(AccountManagerTest.FEATURE_2);
+    }
 
-        // we need the Context and AbstractAccountAuthenticator doe not provide
-        // access to it even if it stores it, so just duplicate it
-        mContext = context;
+    public AccountAuthenticatorResponse getResponse() {
+        return mResponse;
+    }
 
-        // create some mock features
-        mockFeatureList.add(MOCK_FEATURE_1);
-        mockFeatureList.add(MOCK_FEATURE_2);
+    public String getAccountType() {
+        return mAccountType;
+    }
+
+    public String getAuthTokenType() {
+        return mAuthTokenType;
+    }
+
+    public String[] getRequiredFeatures() {
+        return mRequiredFeatures;
+    }
+
+    public Bundle getOptions() {
+        return mOptions;
+    }
+
+    public Account getAccount() {
+        return mAccount;
+    }
+
+    public String[] getFeatures() {
+        return mFeatures;
+    }
+
+    public void clearData() {
+        mResponse = null;
+        mAccountType = null;
+        mAuthTokenType = null;
+        mRequiredFeatures = null;
+        mOptions = null;
+        mAccount = null;
+        mFeatures = null;
+    }
+
+    private Bundle createResultBundle() {
+        Bundle result = new Bundle();
+        result.putString(AccountManager.KEY_ACCOUNT_NAME, AccountManagerTest.ACCOUNT_NAME);
+        result.putString(AccountManager.KEY_ACCOUNT_TYPE, AccountManagerTest.ACCOUNT_TYPE);
+        result.putString(AccountManager.KEY_AUTHTOKEN, AccountManagerTest.AUTH_TOKEN);
+
+        return result;
     }
 
     /**
@@ -81,52 +104,13 @@
             String authTokenType, String[] requiredFeatures, Bundle options)
             throws NetworkErrorException {
 
-        if(null == response) {
-            throw new IllegalArgumentException("response cannot be null");
-        }
-        if(null == accountType) {
-            throw new IllegalArgumentException("accountType cannot be null");
-        }
-        if(null == authTokenType) {
-            throw new IllegalArgumentException("authTokenType cannot be null");
-        }
+        this.mResponse = response;
+        this.mAccountType = accountType;
+        this.mAuthTokenType = authTokenType;
+        this.mRequiredFeatures = requiredFeatures;
+        this.mOptions = options;
 
-        Bundle result = new Bundle();
-
-        if (accountType.equals(MOCK_ACCOUNT_TYPE)) {
-            Account account = new Account(MOCK_ACCOUNT_NAME, MOCK_ACCOUNT_TYPE);
-            // Add the account in the DB
-            if(AccountManager.get(mContext).addAccountExplicitly(account,
-                    MOCK_ACCOUNT_PASSWORD, 
-                    null)) {
-                getAccountMapByType(accountType).put(account.hashCode(), account);
-
-                result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
-                result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
-                result.putString(AccountManager.KEY_AUTHTOKEN, getAuthTokenForAccount(account));
-            }
-            else {
-                result.putInt(AccountManager.KEY_ERROR_CODE , ERROR_CODE_ACCOUNT_CANNOT_ADD);
-                result.putString(AccountManager.KEY_ERROR_MESSAGE , ERROR_MESSAGE_ACCOUNT_CANNOT_ADD);
-            }
-
-        } else {
-            result.putInt(AccountManager.KEY_ERROR_CODE , ERROR_CODE_ACCOUNT_TYPE);
-            result.putString(AccountManager.KEY_ERROR_MESSAGE , ERROR_MESSAGE_ACCOUNT_TYPE);
-        }
-
-        return result;
-    }
-
-    private Map<Integer, Account> getAccountMapByType(String accountType) {
-        String type = (null != accountType) ? accountType : "";
-
-        Map<Integer, Account> map = accountMapByType.get(type);
-        if(null == map) {
-            map = new HashMap<Integer, Account>();
-        }
-
-        return map;
+        return createResultBundle();
     }
 
     /**
@@ -136,45 +120,12 @@
     public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
             String authTokenType, Bundle options) throws NetworkErrorException {
 
-        if(null == response) {
-            throw new IllegalArgumentException("response cannot be null");
-        }
-        if(null == account) {
-            throw new IllegalArgumentException("account cannot be null");
-        }
+        this.mResponse = response;
+        this.mAccount = account;
+        this.mAuthTokenType = authTokenType;
+        this.mOptions = options;
 
-        Bundle result = new Bundle();
-
-        Account accountInMap = getAccountMapByType(account.type).get(account.hashCode());
-        if(null == accountInMap) {
-            result.putInt(AccountManager.KEY_ERROR_CODE , ERROR_CODE_ACCOUNT_UNKNOWN);
-            result.putString(AccountManager.KEY_ERROR_MESSAGE , ERROR_MESSAGE_ACCOUNT_UNKNOWN);
-        }
-
-        if(authTokenType.equals(MOCK_AUTH_TOKEN_TYPE)) {
-            result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
-            result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
-            result.putString(AccountManager.KEY_AUTHTOKEN, getAuthTokenForAccount(account));
-        } else {
-            result.putInt(AccountManager.KEY_ERROR_CODE , ERROR_CODE_AUTH_TOKEN_TYPE);
-            result.putString(AccountManager.KEY_ERROR_MESSAGE , ERROR_MESSAGE_AUTH_TOKEN_TYPE);
-        }
-
-        return result;
-    }
-
-    private String getAuthTokenForAccount(Account account) {
-        StringBuilder sb  = new StringBuilder(MOCK_AUTH_TOKEN);
-        sb.append(":");
-        if(null != account) {
-            sb.append(account.name);
-        }
-        sb.append(":");
-        if(null != account) {
-            sb.append(account.type);
-        }
-
-        return sb.toString();
+        return createResultBundle();
     }
 
     /**
@@ -184,7 +135,11 @@
      */
     @Override
     public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
-        throw new UnsupportedOperationException();
+
+        this.mResponse = response;
+        this.mAccountType = accountType;
+
+        return createResultBundle();
     }
 
     /**
@@ -194,24 +149,13 @@
     public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
             Bundle options) throws NetworkErrorException {
 
-        if(null == response) {
-            throw new IllegalArgumentException("response cannot be null");
-        }
-        if(null == account) {
-            throw new IllegalArgumentException("account cannot be null");
-        }
+        this.mResponse = response;
+        this.mAccount = account;
+        this.mOptions = options;
 
         Bundle result = new Bundle();
+        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
 
-        Account accountInMap = getAccountMapByType(account.type).get(account.hashCode());
-        if(null == accountInMap) {
-            result.putInt(AccountManager.KEY_ERROR_CODE , ERROR_CODE_ACCOUNT_UNKNOWN);
-            result.putString(AccountManager.KEY_ERROR_MESSAGE , ERROR_MESSAGE_ACCOUNT_UNKNOWN);
-        }
-        else {
-            result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
-        }
- 
         return result;
     }
 
@@ -222,36 +166,12 @@
     public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
             String authTokenType, Bundle options) throws NetworkErrorException {
 
-        if(null == response) {
-            throw new IllegalArgumentException("response cannot be null");
-        }
-        if(null == account) {
-            throw new IllegalArgumentException("account cannot be null");
-        }
-        if(null == authTokenType) {
-            throw new IllegalArgumentException("authTokenType cannot be null");
-        }
+        this.mResponse = response;
+        this.mAccount = account;
+        this.mAuthTokenType = authTokenType;
+        this.mOptions = options;
 
-        Bundle result = new Bundle();
-
-        Account accountInMap = getAccountMapByType(account.type).get(account.hashCode());
-        if(null == accountInMap) {
-            result.putInt(AccountManager.KEY_ERROR_CODE , ERROR_CODE_ACCOUNT_UNKNOWN);
-            result.putString(AccountManager.KEY_ERROR_MESSAGE , ERROR_MESSAGE_ACCOUNT_UNKNOWN);
-        }
-        else {
-            if(authTokenType.equals(MOCK_AUTH_TOKEN_TYPE)) {
-                result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
-                result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
-                result.putString(AccountManager.KEY_AUTHTOKEN, getAuthTokenForAccount(account));
-            }
-            else {
-                result.putInt(AccountManager.KEY_ERROR_CODE , ERROR_CODE_AUTH_TOKEN_TYPE);
-                result.putString(AccountManager.KEY_ERROR_MESSAGE , ERROR_MESSAGE_AUTH_TOKEN_TYPE);
-            }
-        }
-
-        return result;
+        return createResultBundle();
     }
 
     /**
@@ -259,14 +179,9 @@
      */
     @Override
     public String getAuthTokenLabel(String authTokenType) {
-        if(null == authTokenType) {
-            throw new IllegalArgumentException("authTokenType cannot be null");
-        }
-        if(! authTokenType.equals(MOCK_AUTH_TOKEN_TYPE)) {
-            throw new IllegalArgumentException("unknown authTokenType: " + authTokenType);
-        }
+        this.mAuthTokenType = authTokenType;
 
-        return MOCK_AUTH_TOKEN_LABEL;
+        return AccountManagerTest.AUTH_TOKEN_LABEL;
     }
 
     /**
@@ -276,33 +191,24 @@
     public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
             String[] features) throws NetworkErrorException {
 
-        if(null == response) {
-            throw new IllegalArgumentException("response cannot be null");
-        }
-        if(null == account) {
-            throw new IllegalArgumentException("account cannot be null");
-        }
-        if(null == features) {
-            throw new IllegalArgumentException("featues cannot be null");
-        }
+        this.mResponse = response;
+        this.mAccount = account;
+        this.mFeatures = features;
 
         Bundle result = new Bundle();
-
-        Account accountInMap = getAccountMapByType(account.type).get(account.hashCode());
-        if(null == accountInMap) {
-            result.putInt(AccountManager.KEY_ERROR_CODE , ERROR_CODE_ACCOUNT_UNKNOWN);
-            result.putString(AccountManager.KEY_ERROR_MESSAGE , ERROR_MESSAGE_ACCOUNT_UNKNOWN);
-        }
-        else {
-            for(String featureName: features) {
-                if(! mockFeatureList.contains(featureName)) {
-                    result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
-                    return result;
-                }
-            }
+        if (null == features) {
             result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
         }
-
+        else {
+            boolean booleanResult = true;
+            for (String feature: features) {
+                if (!mockFeatureList.contains(feature)) {
+                    booleanResult = false;
+                    break;
+                }
+            }
+            result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, booleanResult);
+        }
         return result;
     }
 }
\ No newline at end of file
diff --git a/tests/tests/accounts/src/android/accounts/cts/MockAccountService.java b/tests/tests/accounts/src/android/accounts/cts/MockAccountService.java
index bde2042..a52f580 100644
--- a/tests/tests/accounts/src/android/accounts/cts/MockAccountService.java
+++ b/tests/tests/accounts/src/android/accounts/cts/MockAccountService.java
@@ -25,15 +25,8 @@
  */
 public class MockAccountService extends Service {
 
-    private MockAccountAuthenticator mAuthenticator;
-
     @Override
     public IBinder onBind(Intent intent) {
-        return mAuthenticator.getIBinder();
-    }
-
-    @Override
-    public void onCreate() {
-        mAuthenticator = new MockAccountAuthenticator(this);
+        return AccountManagerTest.getMockAuthenticator(this).getIBinder();
     }
 }
diff --git a/tests/tests/text/src/android/text/format/cts/TimeTest.java b/tests/tests/text/src/android/text/format/cts/TimeTest.java
index 45dcfed..a8f2acd 100644
--- a/tests/tests/text/src/android/text/format/cts/TimeTest.java
+++ b/tests/tests/text/src/android/text/format/cts/TimeTest.java
@@ -17,6 +17,7 @@
 package android.text.format.cts;
 
 import java.util.Calendar;
+import java.util.TimeZone;
 
 import android.test.AndroidTestCase;
 import android.text.format.Time;
@@ -653,7 +654,7 @@
     public void testSet0() throws Exception {
         Time t = new Time(Time.TIMEZONE_UTC);
         long time = System.currentTimeMillis();
-        Calendar date = Calendar.getInstance();
+        Calendar date = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
         date.setTimeInMillis(time);
         t.set(time);
         assertEquals(date.get(Calendar.YEAR), t.year);
diff --git a/tests/tests/view/src/android/view/cts/KeyEventTest.java b/tests/tests/view/src/android/view/cts/KeyEventTest.java
index 6da754f..dc1696c6 100644
--- a/tests/tests/view/src/android/view/cts/KeyEventTest.java
+++ b/tests/tests/view/src/android/view/cts/KeyEventTest.java
@@ -532,35 +532,6 @@
 
     @TestTargetNew(
         level = TestLevel.COMPLETE,
-        notes = "Test {@link KeyEvent#getMatch(char[], int)}",
-        method = "getMatch",
-        args = {char[].class, int.class}
-    )
-    @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, " +
-            "should add NPE description in javadoc.")
-    public void testGetMatch2() {
-        char[] codes1 = { '0', '1', '2' };
-        assertEquals('\0', mKeyEvent.getMatch(codes1, KeyEvent.KEYCODE_SHIFT_LEFT));
-
-        char[] codes2 = { 'A', 'B', 'C' };
-        assertEquals('\0', mKeyEvent.getMatch(codes2, KeyEvent.KEYCODE_SHIFT_LEFT));
-        assertEquals('\0', mKeyEvent.getMatch(codes2, 0));
-
-        char[] codes3 = { '2', 's' };
-        mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_S);
-        assertEquals('\0', mKeyEvent.getMatch(codes3, KeyEvent.KEYCODE_ALT_LEFT));
-        assertEquals('s', mKeyEvent.getMatch(codes3, 0));
-
-        try {
-            mKeyEvent.getMatch(null, 0);
-            fail("Should throw NullPointerException ");
-        } catch (NullPointerException e) {
-            // empty
-        }
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
         notes = "Test {@link KeyEvent#getAction()}",
         method = "getAction",
         args = {}