diff --git a/api/current.txt b/api/current.txt index 1ba5d41439192..fc0ae966bfbe3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2999,6 +2999,7 @@ package android.accounts { method public android.accounts.AccountManagerFuture startAddAccountSession(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture startUpdateCredentialsSession(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); + field public static final java.lang.String ACTION_ACCOUNT_REMOVED = "android.accounts.action.ACCOUNT_REMOVED"; field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator"; field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator"; field public static final java.lang.String AUTHENTICATOR_META_DATA_NAME = "android.accounts.AccountAuthenticator"; diff --git a/api/system-current.txt b/api/system-current.txt index a5da28e28431f..5e15a86828c5e 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3123,6 +3123,7 @@ package android.accounts { method public android.accounts.AccountManagerFuture startAddAccountSession(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture startUpdateCredentialsSession(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); + field public static final java.lang.String ACTION_ACCOUNT_REMOVED = "android.accounts.action.ACCOUNT_REMOVED"; field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator"; field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator"; field public static final java.lang.String AUTHENTICATOR_META_DATA_NAME = "android.accounts.AccountAuthenticator"; diff --git a/api/test-current.txt b/api/test-current.txt index 36698e85522d4..12950744526da 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -2999,6 +2999,7 @@ package android.accounts { method public android.accounts.AccountManagerFuture startAddAccountSession(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture startUpdateCredentialsSession(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); + field public static final java.lang.String ACTION_ACCOUNT_REMOVED = "android.accounts.action.ACCOUNT_REMOVED"; field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator"; field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator"; field public static final java.lang.String AUTHENTICATOR_META_DATA_NAME = "android.accounts.AccountAuthenticator"; diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 80522886c78f4..b320d5d83cc75 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -335,6 +335,7 @@ public class AccountManager { * are removed, or an account's credentials (saved password, etc) are changed. * * @see #addOnAccountsUpdatedListener + * @see #ACTION_ACCOUNT_REMOVED * * @deprecated use {@link #addOnAccountsUpdatedListener} to get account updates in runtime. */ @@ -343,6 +344,14 @@ public class AccountManager { public static final String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED"; + /** + * Action sent as a broadcast Intent by the AccountsService when any account is removed. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(includeBackground = true) + public static final String ACTION_ACCOUNT_REMOVED = + "android.accounts.action.ACCOUNT_REMOVED"; + /** * Action sent as a broadcast Intent to specific package by the AccountsService * when account visibility or account's credentials (saved password, etc) are changed. diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 4cf23f9e1a5f9..b2d98d613a92d 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -493,7 +493,9 @@ + + diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 5f585cc799c92..eb58e4c542461 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -959,6 +959,12 @@ public class AccountManagerService mContext.sendBroadcastAsUser(ACCOUNTS_CHANGED_INTENT, new UserHandle(userId)); } + private void sendAccountRemovedBroadcast(int userId) { + Intent intent = new Intent(AccountManager.ACTION_ACCOUNT_REMOVED); + intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + mContext.sendBroadcastAsUser(intent, new UserHandle(userId)); + } + @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { @@ -1111,6 +1117,7 @@ public class AccountManagerService notifyPackage(packageToVisibility.getKey(), accounts); } } + sendAccountRemovedBroadcast(accounts.userId); } else { ArrayList accountNames = accountNamesByType.get(account.type); if (accountNames == null) { @@ -1971,6 +1978,7 @@ public class AccountManagerService sendNotificationAccountUpdated(resultAccount, accounts); sendAccountsChangedBroadcast(accounts.userId); + sendAccountRemovedBroadcast(accounts.userId); } } return resultAccount; @@ -2206,6 +2214,7 @@ public class AccountManagerService // Only broadcast LOGIN_ACCOUNTS_CHANGED if a change occurred. sendAccountsChangedBroadcast(accounts.userId); + sendAccountRemovedBroadcast(accounts.userId); String action = userUnlocked ? AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE : AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE_DE; logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts); diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index 00f6273d14bf8..20839c5f7a182 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -117,6 +117,7 @@ public class AccountManagerServiceTest extends AndroidTestCase { @Captor private ArgumentCaptor mBundleCaptor; private int mVisibleAccountsChangedBroadcasts; private int mLoginAccountsChangedBroadcasts; + private int mAccountRemovedBroadcasts; private static final int LATCH_TIMEOUT_MS = 500; private static final String PREN_DB = "pren.db"; @@ -2510,6 +2511,7 @@ public class AccountManagerServiceTest extends AndroidTestCase { updateBroadcastCounters(2); assertEquals(mVisibleAccountsChangedBroadcasts, 0); // broadcast was not sent assertEquals(mLoginAccountsChangedBroadcasts, 2); + assertEquals(mAccountRemovedBroadcasts, 0); } @SmallTest @@ -2533,9 +2535,10 @@ public class AccountManagerServiceTest extends AndroidTestCase { mAms.registerAccountListener( null /* accountTypes */, "testpackage"); mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE); - updateBroadcastCounters(6); + updateBroadcastCounters(8); assertEquals(mVisibleAccountsChangedBroadcasts, 2); assertEquals(mLoginAccountsChangedBroadcasts, 4); + assertEquals(mAccountRemovedBroadcasts, 2); } @SmallTest @@ -2560,17 +2563,19 @@ public class AccountManagerServiceTest extends AndroidTestCase { "testpackage3"); // opPackageName // Remove account with 2 active listeners. mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS); - updateBroadcastCounters(7); + updateBroadcastCounters(8); assertEquals(mVisibleAccountsChangedBroadcasts, 5); assertEquals(mLoginAccountsChangedBroadcasts, 2); // 3 add, 2 remove + assertEquals(mAccountRemovedBroadcasts, 1); // Add account of another type. mAms.addAccountExplicitly( AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_TYPE_2, "p11", null); - updateBroadcastCounters(8); + updateBroadcastCounters(9); assertEquals(mVisibleAccountsChangedBroadcasts, 5); assertEquals(mLoginAccountsChangedBroadcasts, 3); + assertEquals(mAccountRemovedBroadcasts, 1); } @SmallTest @@ -2602,16 +2607,20 @@ public class AccountManagerServiceTest extends AndroidTestCase { private void updateBroadcastCounters (int expectedBroadcasts){ mVisibleAccountsChangedBroadcasts = 0; mLoginAccountsChangedBroadcasts = 0; + mAccountRemovedBroadcasts = 0; ArgumentCaptor 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())) { + if (AccountManager.ACTION_VISIBLE_ACCOUNTS_CHANGED.equals(intent.getAction())) { mVisibleAccountsChangedBroadcasts++; } - if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION. equals(intent.getAction())) { + if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) { mLoginAccountsChangedBroadcasts++; } + if (AccountManager.ACTION_ACCOUNT_REMOVED.equals(intent.getAction())) { + mAccountRemovedBroadcasts++; + } } }