Make the RegisteredSErvices Cache not allow the registered service for a
type to change without first uninstalling the previous service for that
type, unless the newly installed service is in the system image.

Notify the listener when a service is added or removed.

Make the AccountManagerService remove the accounts for an authenticator
when the registered authenticator changes from one uid to another.

Make the AbstractSyncableContentProvider force a sync when the database is first created.
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 4f59c4e..800ad749 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -72,7 +72,7 @@
  */
 public class AccountManagerService
         extends IAccountManager.Stub
-        implements RegisteredServicesCacheListener {
+        implements RegisteredServicesCacheListener<AuthenticatorDescription> {
     private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
 
     private static final String NO_BROADCAST_FLAG = "nobroadcast";
@@ -220,34 +220,29 @@
         mMessageHandler = new MessageHandler(mMessageThread.getLooper());
 
         mAuthenticatorCache = new AccountAuthenticatorCache(mContext);
-        mAuthenticatorCache.setListener(this);
+        mAuthenticatorCache.setListener(this, null /* Handler */);
         mBindHelper = new AuthenticatorBindHelper(mContext, mAuthenticatorCache, mMessageHandler,
                 MESSAGE_CONNECTED, MESSAGE_DISCONNECTED);
 
         mSimWatcher = new SimWatcher(mContext);
         sThis.set(this);
-
-        onRegisteredServicesCacheChanged();
     }
 
-    public void onRegisteredServicesCacheChanged() {
+    public void onServiceChanged(AuthenticatorDescription desc, boolean removed) {
         boolean accountDeleted = false;
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         Cursor cursor = db.query(TABLE_ACCOUNTS,
                 new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME},
-                null, null, null, null, null);
+                ACCOUNTS_TYPE + "=?", new String[]{desc.type}, null, null, null);
         try {
             while (cursor.moveToNext()) {
                 final long accountId = cursor.getLong(0);
                 final String accountType = cursor.getString(1);
                 final String accountName = cursor.getString(2);
-                if (mAuthenticatorCache.getServiceInfo(AuthenticatorDescription.newKey(accountType))
-                        == null) {
-                    Log.d(TAG, "deleting account " + accountName + " because type "
-                            + accountType + " no longer has a registered authenticator");
-                    db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null);
-                    accountDeleted= true;
-                }
+                Log.d(TAG, "deleting account " + accountName + " because type "
+                        + accountType + " no longer has a registered authenticator");
+                db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null);
+                accountDeleted = true;
             }
         } finally {
             cursor.close();