Loading core/java/android/accounts/AccountManager.java +42 −12 Original line number Diff line number Diff line Loading @@ -343,6 +343,17 @@ public class AccountManager { public static final String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED"; /** * Action sent as a broadcast Intent to specific package by the AccountsService * when account visibility or account's credentials (saved password, etc) are changed. * * @see #addOnAccountsUpdatedListener * * @hide */ public static final String ACTION_VISIBLE_ACCOUNTS_CHANGED = "android.accounts.action.VISIBLE_ACCOUNTS_CHANGED"; /** * Key to set default visibility for applications targeting API level * {@link android.os.Build.VERSION_CODES#O} or above and don't have the same signature as Loading Loading @@ -1057,8 +1068,8 @@ public class AccountManager { /** * Gets the previous name associated with the account or {@code null}, if * none. This is intended so that clients of {@link * #LOGIN_ACCOUNTS_CHANGED_ACTION} broadcasts can determine if an * none. This is intended so that clients of * {@link OnAccountsUpdateListener} can determine if an * authenticator has renamed an account. * * <p>It is safe to call this method from the main thread. Loading Loading @@ -1555,7 +1566,8 @@ public class AccountManager { * <p>In that case, you may need to wait until the user responds, which * could take hours or days or forever. When the user does respond and * supply a new password, the account manager will broadcast the * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent, which applications can * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent and * notify {@link OnAccountsUpdateListener} which applications can * use to try again. * * <p>If notifyAuthFailure is not set, it is the application's Loading Loading @@ -1631,7 +1643,8 @@ public class AccountManager { * <p>In that case, you may need to wait until the user responds, which * could take hours or days or forever. When the user does respond and * supply a new password, the account manager will broadcast the * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent, which applications can * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent and * notify {@link OnAccountsUpdateListener} which applications can * use to try again. * * <p>If notifyAuthFailure is not set, it is the application's Loading Loading @@ -2811,7 +2824,7 @@ public class AccountManager { Maps.newHashMap(); /** * BroadcastReceiver that listens for the LOGIN_ACCOUNTS_CHANGED_ACTION intent * BroadcastReceiver that listens for the ACTION_VISIBLE_ACCOUNTS_CHANGED intent * so that it can read the updated list of accounts and send them to the listener * in mAccountsUpdatedListeners. */ Loading Loading @@ -2882,21 +2895,26 @@ public class AccountManager { if (accountTypes != null) { mAccountsUpdatedListenersTypes.put(listener, new HashSet<String>(Arrays.asList(accountTypes))); } else { mAccountsUpdatedListenersTypes.put(listener, null); } if (wasEmpty) { // Register a broadcast receiver to monitor account changes IntentFilter intentFilter = new IntentFilter(); // TODO get rid of the broadcast receiver // create android.os.ResultReceiver // send it to the service via aidl // handle onReceiveResult intentFilter.addAction(LOGIN_ACCOUNTS_CHANGED_ACTION); intentFilter.addAction(ACTION_VISIBLE_ACCOUNTS_CHANGED); // To recover from disk-full. intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); // Register a broadcast receiver to monitor account changes mContext.registerReceiver(mAccountsChangedBroadcastReceiver, intentFilter); } try { // Notify AccountManagedService about new receiver. // The receiver must be unregistered later exactly one time mService.registerAccountListener(accountTypes, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } if (updateImmediately) { postToHandler(handler, listener, getAccounts()); Loading @@ -2923,11 +2941,23 @@ public class AccountManager { Log.e(TAG, "Listener was not previously added"); return; } Set<String> accountTypes = mAccountsUpdatedListenersTypes.get(listener); String[] accountsArray; if (accountTypes != null) { accountsArray = accountTypes.toArray(new String[accountTypes.size()]); } else { accountsArray = null; } mAccountsUpdatedListeners.remove(listener); mAccountsUpdatedListenersTypes.remove(listener); if (mAccountsUpdatedListeners.isEmpty()) { mContext.unregisterReceiver(mAccountsChangedBroadcastReceiver); } try { mService.unregisterAccountListener(accountsArray, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } Loading core/java/android/accounts/IAccountManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,9 @@ interface IAccountManager { /* Type may be null returns Map <Account, Integer>*/ Map getAccountsAndVisibilityForPackage(in String packageName, in String accountType); void registerAccountListener(in String[] accountTypes, String opPackageName); void unregisterAccountListener(in String[] accountTypes, String opPackageName); /* Check if the package in a user can access an account */ boolean hasAccountAccess(in Account account, String packageName, in UserHandle userHandle); /* Crate an intent to request account access for package and a given user id */ Loading core/res/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,7 @@ <protected-broadcast android:name="android.intent.action.ACTION_RADIO_OFF" /> <protected-broadcast android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" /> <protected-broadcast android:name="android.accounts.action.VISIBLE_ACCOUNTS_CHANGED" /> <protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" /> <protected-broadcast android:name="com.android.phone.SIP_INCOMING_CALL" /> Loading services/core/java/com/android/server/accounts/AccountManagerService.java +169 −121 File changed.Preview size limit exceeded, changes collapsed. Show changes services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +172 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.nullable; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -87,6 +89,17 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * Tests for {@link AccountManagerService}. * <p>Run with:<pre> * mmma -j40 frameworks/base/services/tests/servicestests * adb install -r ${OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk * adb shell am instrument -w -e class package com.android.server.accounts \ * com.android.frameworks.servicestests\ * /android.support.test.runner.AndroidJUnitRunner * </pre> */ public class AccountManagerServiceTest extends AndroidTestCase { private static final String TAG = AccountManagerServiceTest.class.getSimpleName(); private static final long ONE_DAY_IN_MILLISECOND = 86400000; Loading @@ -103,6 +116,8 @@ public class AccountManagerServiceTest extends AndroidTestCase { @Captor private ArgumentCaptor<Intent> mIntentCaptor; @Captor private ArgumentCaptor<Bundle> mBundleCaptor; private int mVisibleAccountsChangedBroadcasts; private int mLoginAccountsChangedBroadcasts; private static final int LATCH_TIMEOUT_MS = 500; private static final String PREN_DB = "pren.db"; Loading Loading @@ -1042,7 +1057,7 @@ public class AccountManagerServiceTest extends AndroidTestCase { waitForLatch(latch); // Verify notification is cancelled verify(mMockNotificationManager).cancelNotificationWithTag( anyString(), anyString(), anyInt(), anyInt()); anyString(), nullable(String.class), anyInt(), anyInt()); verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture()); Bundle result = mBundleCaptor.getValue(); Loading Loading @@ -1889,7 +1904,7 @@ public class AccountManagerServiceTest extends AndroidTestCase { waitForLatch(latch); // Verify notification is cancelled verify(mMockNotificationManager).cancelNotificationWithTag( anyString(), anyString(), anyInt(), anyInt()); anyString(), nullable(String.class), anyInt(), anyInt()); verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture()); Bundle result = mBundleCaptor.getValue(); Loading Loading @@ -2446,6 +2461,161 @@ public class AccountManagerServiceTest extends AndroidTestCase { verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class)); } @SmallTest public void testRegisterAccountListener() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.registerAccountListener( null, //accountTypes "testpackage"); // opPackageName // Check that two previously registered receivers can be unregistered successfully. mAms.unregisterAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.unregisterAccountListener( null, //accountTypes "testpackage"); // opPackageName } @SmallTest public void testRegisterAccountListenerAndAddAccount() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); // Notification about new account updateBroadcastCounters(2); assertEquals(mVisibleAccountsChangedBroadcasts, 1); assertEquals(mLoginAccountsChangedBroadcasts, 1); } @SmallTest public void testRegisterAccountListenerAndAddAccountOfDifferentType() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2}, "testpackage"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); mAms.addAccountExplicitly( AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p11", null); // Notification about new account updateBroadcastCounters(2); assertEquals(mVisibleAccountsChangedBroadcasts, 0); // broadcast was not sent assertEquals(mLoginAccountsChangedBroadcasts, 2); } @SmallTest public void testRegisterAccountListenerWithAddingTwoAccounts() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); mAms.unregisterAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.addAccountExplicitly( AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p11", null); updateBroadcastCounters(3); assertEquals(mVisibleAccountsChangedBroadcasts, 1); assertEquals(mLoginAccountsChangedBroadcasts, 2); mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS); mAms.registerAccountListener( null /* accountTypes */, "testpackage"); mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE); updateBroadcastCounters(6); assertEquals(mVisibleAccountsChangedBroadcasts, 2); assertEquals(mLoginAccountsChangedBroadcasts, 4); } @SmallTest public void testRegisterAccountListenerForThreePackages() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage1"); // opPackageName mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage2"); // opPackageName mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage3"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); updateBroadcastCounters(4); assertEquals(mVisibleAccountsChangedBroadcasts, 3); assertEquals(mLoginAccountsChangedBroadcasts, 1); mAms.unregisterAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage3"); // opPackageName // Remove account with 2 active listeners. mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS); updateBroadcastCounters(7); assertEquals(mVisibleAccountsChangedBroadcasts, 5); assertEquals(mLoginAccountsChangedBroadcasts, 2); // 3 add, 2 remove // Add account of another type. mAms.addAccountExplicitly( AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_TYPE_2, "p11", null); updateBroadcastCounters(8); assertEquals(mVisibleAccountsChangedBroadcasts, 5); assertEquals(mLoginAccountsChangedBroadcasts, 3); } @SmallTest public void testRegisterAccountListenerCredentialsUpdate() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); mAms.setPassword(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "pwd"); updateBroadcastCounters(4); assertEquals(mVisibleAccountsChangedBroadcasts, 2); assertEquals(mLoginAccountsChangedBroadcasts, 2); } @SmallTest public void testUnregisterAccountListenerNotRegistered() throws Exception { unlockSystemUser(); try { mAms.unregisterAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName fail("IllegalArgumentException expected. But no exception was thrown."); } catch (IllegalArgumentException e) { // IllegalArgumentException is expected. } } private void updateBroadcastCounters (int expectedBroadcasts){ mVisibleAccountsChangedBroadcasts = 0; mLoginAccountsChangedBroadcasts = 0; ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mMockContext, times(expectedBroadcasts)).sendBroadcastAsUser(captor.capture(), any(UserHandle.class)); for (Intent intent : captor.getAllValues()) { if (AccountManager.ACTION_VISIBLE_ACCOUNTS_CHANGED. equals(intent.getAction())) { mVisibleAccountsChangedBroadcasts++; } if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION. equals(intent.getAction())) { mLoginAccountsChangedBroadcasts++; } } } private void waitForLatch(CountDownLatch latch) { try { latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS); Loading Loading
core/java/android/accounts/AccountManager.java +42 −12 Original line number Diff line number Diff line Loading @@ -343,6 +343,17 @@ public class AccountManager { public static final String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED"; /** * Action sent as a broadcast Intent to specific package by the AccountsService * when account visibility or account's credentials (saved password, etc) are changed. * * @see #addOnAccountsUpdatedListener * * @hide */ public static final String ACTION_VISIBLE_ACCOUNTS_CHANGED = "android.accounts.action.VISIBLE_ACCOUNTS_CHANGED"; /** * Key to set default visibility for applications targeting API level * {@link android.os.Build.VERSION_CODES#O} or above and don't have the same signature as Loading Loading @@ -1057,8 +1068,8 @@ public class AccountManager { /** * Gets the previous name associated with the account or {@code null}, if * none. This is intended so that clients of {@link * #LOGIN_ACCOUNTS_CHANGED_ACTION} broadcasts can determine if an * none. This is intended so that clients of * {@link OnAccountsUpdateListener} can determine if an * authenticator has renamed an account. * * <p>It is safe to call this method from the main thread. Loading Loading @@ -1555,7 +1566,8 @@ public class AccountManager { * <p>In that case, you may need to wait until the user responds, which * could take hours or days or forever. When the user does respond and * supply a new password, the account manager will broadcast the * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent, which applications can * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent and * notify {@link OnAccountsUpdateListener} which applications can * use to try again. * * <p>If notifyAuthFailure is not set, it is the application's Loading Loading @@ -1631,7 +1643,8 @@ public class AccountManager { * <p>In that case, you may need to wait until the user responds, which * could take hours or days or forever. When the user does respond and * supply a new password, the account manager will broadcast the * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent, which applications can * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent and * notify {@link OnAccountsUpdateListener} which applications can * use to try again. * * <p>If notifyAuthFailure is not set, it is the application's Loading Loading @@ -2811,7 +2824,7 @@ public class AccountManager { Maps.newHashMap(); /** * BroadcastReceiver that listens for the LOGIN_ACCOUNTS_CHANGED_ACTION intent * BroadcastReceiver that listens for the ACTION_VISIBLE_ACCOUNTS_CHANGED intent * so that it can read the updated list of accounts and send them to the listener * in mAccountsUpdatedListeners. */ Loading Loading @@ -2882,21 +2895,26 @@ public class AccountManager { if (accountTypes != null) { mAccountsUpdatedListenersTypes.put(listener, new HashSet<String>(Arrays.asList(accountTypes))); } else { mAccountsUpdatedListenersTypes.put(listener, null); } if (wasEmpty) { // Register a broadcast receiver to monitor account changes IntentFilter intentFilter = new IntentFilter(); // TODO get rid of the broadcast receiver // create android.os.ResultReceiver // send it to the service via aidl // handle onReceiveResult intentFilter.addAction(LOGIN_ACCOUNTS_CHANGED_ACTION); intentFilter.addAction(ACTION_VISIBLE_ACCOUNTS_CHANGED); // To recover from disk-full. intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); // Register a broadcast receiver to monitor account changes mContext.registerReceiver(mAccountsChangedBroadcastReceiver, intentFilter); } try { // Notify AccountManagedService about new receiver. // The receiver must be unregistered later exactly one time mService.registerAccountListener(accountTypes, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } if (updateImmediately) { postToHandler(handler, listener, getAccounts()); Loading @@ -2923,11 +2941,23 @@ public class AccountManager { Log.e(TAG, "Listener was not previously added"); return; } Set<String> accountTypes = mAccountsUpdatedListenersTypes.get(listener); String[] accountsArray; if (accountTypes != null) { accountsArray = accountTypes.toArray(new String[accountTypes.size()]); } else { accountsArray = null; } mAccountsUpdatedListeners.remove(listener); mAccountsUpdatedListenersTypes.remove(listener); if (mAccountsUpdatedListeners.isEmpty()) { mContext.unregisterReceiver(mAccountsChangedBroadcastReceiver); } try { mService.unregisterAccountListener(accountsArray, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } Loading
core/java/android/accounts/IAccountManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,9 @@ interface IAccountManager { /* Type may be null returns Map <Account, Integer>*/ Map getAccountsAndVisibilityForPackage(in String packageName, in String accountType); void registerAccountListener(in String[] accountTypes, String opPackageName); void unregisterAccountListener(in String[] accountTypes, String opPackageName); /* Check if the package in a user can access an account */ boolean hasAccountAccess(in Account account, String packageName, in UserHandle userHandle); /* Crate an intent to request account access for package and a given user id */ Loading
core/res/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,7 @@ <protected-broadcast android:name="android.intent.action.ACTION_RADIO_OFF" /> <protected-broadcast android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" /> <protected-broadcast android:name="android.accounts.action.VISIBLE_ACCOUNTS_CHANGED" /> <protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" /> <protected-broadcast android:name="com.android.phone.SIP_INCOMING_CALL" /> Loading
services/core/java/com/android/server/accounts/AccountManagerService.java +169 −121 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +172 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.nullable; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -87,6 +89,17 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * Tests for {@link AccountManagerService}. * <p>Run with:<pre> * mmma -j40 frameworks/base/services/tests/servicestests * adb install -r ${OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk * adb shell am instrument -w -e class package com.android.server.accounts \ * com.android.frameworks.servicestests\ * /android.support.test.runner.AndroidJUnitRunner * </pre> */ public class AccountManagerServiceTest extends AndroidTestCase { private static final String TAG = AccountManagerServiceTest.class.getSimpleName(); private static final long ONE_DAY_IN_MILLISECOND = 86400000; Loading @@ -103,6 +116,8 @@ public class AccountManagerServiceTest extends AndroidTestCase { @Captor private ArgumentCaptor<Intent> mIntentCaptor; @Captor private ArgumentCaptor<Bundle> mBundleCaptor; private int mVisibleAccountsChangedBroadcasts; private int mLoginAccountsChangedBroadcasts; private static final int LATCH_TIMEOUT_MS = 500; private static final String PREN_DB = "pren.db"; Loading Loading @@ -1042,7 +1057,7 @@ public class AccountManagerServiceTest extends AndroidTestCase { waitForLatch(latch); // Verify notification is cancelled verify(mMockNotificationManager).cancelNotificationWithTag( anyString(), anyString(), anyInt(), anyInt()); anyString(), nullable(String.class), anyInt(), anyInt()); verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture()); Bundle result = mBundleCaptor.getValue(); Loading Loading @@ -1889,7 +1904,7 @@ public class AccountManagerServiceTest extends AndroidTestCase { waitForLatch(latch); // Verify notification is cancelled verify(mMockNotificationManager).cancelNotificationWithTag( anyString(), anyString(), anyInt(), anyInt()); anyString(), nullable(String.class), anyInt(), anyInt()); verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture()); Bundle result = mBundleCaptor.getValue(); Loading Loading @@ -2446,6 +2461,161 @@ public class AccountManagerServiceTest extends AndroidTestCase { verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class)); } @SmallTest public void testRegisterAccountListener() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.registerAccountListener( null, //accountTypes "testpackage"); // opPackageName // Check that two previously registered receivers can be unregistered successfully. mAms.unregisterAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.unregisterAccountListener( null, //accountTypes "testpackage"); // opPackageName } @SmallTest public void testRegisterAccountListenerAndAddAccount() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); // Notification about new account updateBroadcastCounters(2); assertEquals(mVisibleAccountsChangedBroadcasts, 1); assertEquals(mLoginAccountsChangedBroadcasts, 1); } @SmallTest public void testRegisterAccountListenerAndAddAccountOfDifferentType() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2}, "testpackage"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); mAms.addAccountExplicitly( AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p11", null); // Notification about new account updateBroadcastCounters(2); assertEquals(mVisibleAccountsChangedBroadcasts, 0); // broadcast was not sent assertEquals(mLoginAccountsChangedBroadcasts, 2); } @SmallTest public void testRegisterAccountListenerWithAddingTwoAccounts() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); mAms.unregisterAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.addAccountExplicitly( AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p11", null); updateBroadcastCounters(3); assertEquals(mVisibleAccountsChangedBroadcasts, 1); assertEquals(mLoginAccountsChangedBroadcasts, 2); mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS); mAms.registerAccountListener( null /* accountTypes */, "testpackage"); mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE); updateBroadcastCounters(6); assertEquals(mVisibleAccountsChangedBroadcasts, 2); assertEquals(mLoginAccountsChangedBroadcasts, 4); } @SmallTest public void testRegisterAccountListenerForThreePackages() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage1"); // opPackageName mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage2"); // opPackageName mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage3"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); updateBroadcastCounters(4); assertEquals(mVisibleAccountsChangedBroadcasts, 3); assertEquals(mLoginAccountsChangedBroadcasts, 1); mAms.unregisterAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage3"); // opPackageName // Remove account with 2 active listeners. mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS); updateBroadcastCounters(7); assertEquals(mVisibleAccountsChangedBroadcasts, 5); assertEquals(mLoginAccountsChangedBroadcasts, 2); // 3 add, 2 remove // Add account of another type. mAms.addAccountExplicitly( AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_TYPE_2, "p11", null); updateBroadcastCounters(8); assertEquals(mVisibleAccountsChangedBroadcasts, 5); assertEquals(mLoginAccountsChangedBroadcasts, 3); } @SmallTest public void testRegisterAccountListenerCredentialsUpdate() throws Exception { unlockSystemUser(); mAms.registerAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null); mAms.setPassword(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "pwd"); updateBroadcastCounters(4); assertEquals(mVisibleAccountsChangedBroadcasts, 2); assertEquals(mLoginAccountsChangedBroadcasts, 2); } @SmallTest public void testUnregisterAccountListenerNotRegistered() throws Exception { unlockSystemUser(); try { mAms.unregisterAccountListener( new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, "testpackage"); // opPackageName fail("IllegalArgumentException expected. But no exception was thrown."); } catch (IllegalArgumentException e) { // IllegalArgumentException is expected. } } private void updateBroadcastCounters (int expectedBroadcasts){ mVisibleAccountsChangedBroadcasts = 0; mLoginAccountsChangedBroadcasts = 0; ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mMockContext, times(expectedBroadcasts)).sendBroadcastAsUser(captor.capture(), any(UserHandle.class)); for (Intent intent : captor.getAllValues()) { if (AccountManager.ACTION_VISIBLE_ACCOUNTS_CHANGED. equals(intent.getAction())) { mVisibleAccountsChangedBroadcasts++; } if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION. equals(intent.getAction())) { mLoginAccountsChangedBroadcasts++; } } } private void waitForLatch(CountDownLatch latch) { try { latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS); Loading