am a8b23f2: Refactor expandInstanceRangeLocked

Merge commit 'a8b23f2b386e3e0be20ef06522292314de8cbc78'

* commit 'a8b23f2b386e3e0be20ef06522292314de8cbc78':
  Refactor expandInstanceRangeLocked
diff --git a/src/com/android/providers/calendar/CalendarProvider.java b/src/com/android/providers/calendar/CalendarProvider.java
index a3a4c23..d65b4fb 100644
--- a/src/com/android/providers/calendar/CalendarProvider.java
+++ b/src/com/android/providers/calendar/CalendarProvider.java
@@ -17,11 +17,11 @@
 
 package com.android.providers.calendar;
 
+import com.google.android.collect.Maps;
 import com.google.android.collect.Sets;
 import com.google.android.gdata.client.AndroidGDataClient;
 import com.google.android.gdata.client.AndroidXmlParserFactory;
-import com.google.android.googlelogin.GoogleLoginServiceBlockingHelper;
-import com.google.android.googlelogin.GoogleLoginServiceNotFoundException;
+import com.google.android.googlelogin.GoogleLoginServiceConstants;
 import com.google.android.providers.AbstractGDataSyncAdapter;
 import com.google.android.providers.AbstractGDataSyncAdapter.GDataSyncData;
 import com.google.wireless.gdata.calendar.client.CalendarClient;
@@ -69,12 +69,12 @@
 import android.provider.Calendar.ExtendedProperties;
 import android.provider.Calendar.Instances;
 import android.provider.Calendar.Reminders;
-import android.provider.SyncConstValue;
 import android.text.TextUtils;
 import android.text.format.Time;
 import android.util.Config;
 import android.util.Log;
 import android.util.TimeFormatException;
+import android.accounts.*;
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -91,12 +91,14 @@
 
     private static final boolean PROFILE = false;
     private static final boolean MULTIPLE_ATTENDEES_PER_EVENT = false;
-    private static final String[] ACCOUNTS_PROJECTION = new String[] { Calendars._SYNC_ACCOUNT};
+    private static final String[] ACCOUNTS_PROJECTION =
+            new String[] {Calendars._SYNC_ACCOUNT, Calendars._SYNC_ACCOUNT_TYPE};
 
     private static final String[] EVENTS_PROJECTION = new String[] {
         Events._SYNC_ID,
         Events._SYNC_VERSION,
         Events._SYNC_ACCOUNT,
+        Events._SYNC_ACCOUNT_TYPE,
         Events.CALENDAR_ID,
         Events.RRULE,
         Events.RDATE,
@@ -104,11 +106,12 @@
         };
     private static final int EVENTS_SYNC_ID_INDEX = 0;
     private static final int EVENTS_SYNC_VERSION_INDEX = 1;
-    private static final int EVENTS_SYNC_ACCOUNT_INDEX = 2;
-    private static final int EVENTS_CALENDAR_ID_INDEX = 3;
-    private static final int EVENTS_RRULE_INDEX = 4;
-    private static final int EVENTS_RDATE_INDEX = 5;
-    private static final int EVENTS_ORIGINAL_EVENT_INDEX = 6;
+    private static final int EVENTS_SYNC_ACCOUNT_NAME_INDEX = 2;
+    private static final int EVENTS_SYNC_ACCOUNT_TYPE_INDEX = 3;
+    private static final int EVENTS_CALENDAR_ID_INDEX = 4;
+    private static final int EVENTS_RRULE_INDEX = 5;
+    private static final int EVENTS_RDATE_INDEX = 6;
+    private static final int EVENTS_ORIGINAL_EVENT_INDEX = 7;
 
     private DatabaseUtils.InsertHelper mCalendarsInserter;
     private DatabaseUtils.InsertHelper mEventsInserter;
@@ -230,7 +233,7 @@
 
     // Note: if you update the version number, you must also update the code
     // in upgradeDatabase() to modify the database (gracefully, if possible).
-    private static final int DATABASE_VERSION = 54;
+    private static final int DATABASE_VERSION = 55;
 
     private static final String EXPECTED_PROJECTION = "/full";
 
@@ -561,6 +564,27 @@
             oldVersion += 1;
         }
 
+        if (oldVersion == 54) {
+            db.execSQL("ALTER TABLE Calendars ADD COLUMN _sync_account_type TEXT;");
+            db.execSQL("ALTER TABLE Events ADD COLUMN _sync_account_type TEXT;");
+            db.execSQL("ALTER TABLE DeletedEvents ADD COLUMN _sync_account_type TEXT;");
+            db.execSQL("UPDATE Calendars"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+            db.execSQL("UPDATE Events"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+            db.execSQL("UPDATE DeletedEvents"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+            Log.w(TAG, "re-creating eventSyncAccountAndIdIndex");
+            db.execSQL("DROP INDEX eventSyncAccountAndIdIndex");
+            db.execSQL("CREATE INDEX eventSyncAccountAndIdIndex ON Events ("
+                    + Events._SYNC_ACCOUNT_TYPE + ", " + Events._SYNC_ACCOUNT + ", "
+                    + Events._SYNC_ID + ");");
+            oldVersion += 1;
+        }
+
         return true; // this was lossless
     }
 
@@ -584,6 +608,7 @@
         db.execSQL("CREATE TABLE Calendars (" +
                         "_id INTEGER PRIMARY KEY," +
                         "_sync_account TEXT," +
+                        "_sync_account_type TEXT," +
                         "_sync_id TEXT," +
                         "_sync_version TEXT," +
                         "_sync_time TEXT," +            // UTC
@@ -613,6 +638,7 @@
         db.execSQL("CREATE TABLE Events (" +
                         "_id INTEGER PRIMARY KEY," +
                         "_sync_account TEXT," +
+                        "_sync_account_type TEXT," +
                         "_sync_id TEXT," +
                         "_sync_version TEXT," +
                         "_sync_time TEXT," +            // UTC
@@ -647,7 +673,8 @@
                     ");");
 
         db.execSQL("CREATE INDEX eventSyncAccountAndIdIndex ON Events ("
-                + Events._SYNC_ACCOUNT + ", " + Events._SYNC_ID + ");");
+                + Events._SYNC_ACCOUNT_TYPE + ", " + Events._SYNC_ACCOUNT + ", "
+                + Events._SYNC_ID + ");");
 
         db.execSQL("CREATE INDEX eventsCalendarIdIndex ON Events (" +
                    Events.CALENDAR_ID +
@@ -670,6 +697,7 @@
                         "_sync_id TEXT," +
                         "_sync_version TEXT," +
                         "_sync_account TEXT," +
+                        "_sync_account_type TEXT," +
                         (isTemporary() ? "_sync_local_id INTEGER," : "") + // Used while syncing,
                         "_sync_mark INTEGER," + // To filter out new rows
                         "calendar_id INTEGER" +
@@ -826,18 +854,17 @@
      * syncable.
      */
     @Override
-    protected void onAccountsChanged(String[] accountsArray) {
+    protected void onAccountsChanged(Account[] accountsArray) {
         super.onAccountsChanged(accountsArray);
 
-        Map<String, Boolean> accounts = new HashMap<String, Boolean>();
-        for (String account : accountsArray) {
+        Map<Account, Boolean> accounts = Maps.newHashMap();
+        for (Account account : accountsArray) {
             accounts.put(account, false);
         }
 
         mDb.beginTransaction();
         try {
-            deleteRowsForRemovedAccounts(accounts, "Calendars",
-                    SyncConstValue._SYNC_ACCOUNT);
+            deleteRowsForRemovedAccounts(accounts, "Calendars");
             mDb.setTransactionSuccessful();
         } finally {
             mDb.endTransaction();
@@ -851,28 +878,28 @@
         // If there are no calendars at all for a given account, add the
         // default calendar.
 
-        for (Map.Entry<String, Boolean> entry : accounts.entrySet()) {
+        for (Map.Entry<Account, Boolean> entry : accounts.entrySet()) {
             entry.setValue(false);
             // TODO: remove this break when Calendar supports multiple accounts. Until then
             // pretend that only the first account exists.
             break;
         }
 
-        Set<String> handledAccounts = Sets.newHashSet();
-        ContentResolver cr = getContext().getContentResolver();
+        Set<Account> handledAccounts = Sets.newHashSet();
         if (Config.LOGV) Log.v(TAG, "querying calendars");
-        Cursor c = cr.query(Calendars.CONTENT_URI, ACCOUNTS_PROJECTION, null, null, null);
+        Cursor c = queryInternal(Calendars.CONTENT_URI, ACCOUNTS_PROJECTION, null, null, null);
         try {
             while (c.moveToNext()) {
-                String account = c.getString(0);
+                final String accountName = c.getString(0);
+                final String accountType = c.getString(1);
+                final Account account = new Account(accountName, accountType);
                 if (handledAccounts.contains(account)) {
                     continue;
                 }
                 handledAccounts.add(account);
                 if (accounts.containsKey(account)) {
                     if (Config.LOGV) {
-                        Log.v(TAG, "calendars for account " + account
-                                + " exist");
+                        Log.v(TAG, "calendars for account " + account + " exist");
                     }
                     accounts.put(account, true /* hasCalendar */);
                 }
@@ -885,8 +912,8 @@
         if (Config.LOGV) {
             Log.v(TAG, "scanning over " + accounts.size() + " account(s)");
         }
-        for (Map.Entry<String, Boolean> entry : accounts.entrySet()) {
-            String account = entry.getKey();
+        for (Map.Entry<Account, Boolean> entry : accounts.entrySet()) {
+            final Account account = entry.getKey();
             boolean hasCalendar = entry.getValue();
             if (hasCalendar) {
                 if (Config.LOGV) {
@@ -895,14 +922,15 @@
                 }
                 continue;
             }
-            String feedUrl = mCalendarClient.getDefaultCalendarUrl(account,
+            String feedUrl = mCalendarClient.getDefaultCalendarUrl(account.mName,
                     CalendarClient.PROJECTION_PRIVATE_SELF_ATTENDANCE, null/* query params */);
             feedUrl = CalendarSyncAdapter.rewriteUrlforAccount(account, feedUrl);
             if (Config.LOGV) {
                 Log.v(TAG, "adding default calendar for account " + account);
             }
             ContentValues values = new ContentValues();
-            values.put(Calendars._SYNC_ACCOUNT, account);
+            values.put(Calendars._SYNC_ACCOUNT, account.mName);
+            values.put(Calendars._SYNC_ACCOUNT_TYPE, account.mType);
             values.put(Calendars.URL, feedUrl);
             values.put(Calendars.DISPLAY_NAME, "Default");
             values.put(Calendars.SYNC_EVENTS, 1);
@@ -913,7 +941,7 @@
             // when the user does a sync.
             values.put(Calendars.TIMEZONE, Time.getCurrentTimezone());
             values.put(Calendars.ACCESS_LEVEL, Calendars.OWNER_ACCESS);
-            cr.insert(Calendars.CONTENT_URI, values);
+            insertInternal(Calendars.CONTENT_URI, values);
 
             scheduleSync(account, false /* do a full sync */, null /* no url */);
         }
@@ -1076,36 +1104,45 @@
             return;
         }
 
-        GoogleLoginServiceBlockingHelper loginHelper = null;
-        String username = null;
+        Account account = null;
         String authToken = null;
 
+
         try {
-            loginHelper = new GoogleLoginServiceBlockingHelper(getContext());
-
             // TODO: allow caller to specify which account's feeds should be updated
-            username = loginHelper.getAccount(false);
-            if (TextUtils.isEmpty(username)) {
-                Log.w(TAG, "Unable to update calendars from server -- "
-                      + "no users configured.");
+            Account[] accounts = AccountManager.get(getContext())
+                    .blockingGetAccountsWithTypeAndFeatures(
+                            GoogleLoginServiceConstants.ACCOUNT_TYPE,
+                            new String[]{GoogleLoginServiceConstants.FEATURE_GOOGLE_OR_DASHER});
+            if (accounts.length == 0) {
+                Log.w(TAG, "Unable to update calendars from server -- no users configured.");
                 return;
             }
 
-            try {
-                authToken = loginHelper.getAuthToken(username,
-                                                     mCalendarClient.getServiceName());
-            } catch (GoogleLoginServiceBlockingHelper.AuthenticationException e) {
+            account = accounts[0];
+
+            Bundle bundle = AccountManager.get(getContext()).getAuthToken(
+                    account, mCalendarClient.getServiceName(),
+                    true /* notifyAuthFailure */, null /* callback */, null /* handler */)
+                    .getResult();
+            authToken = bundle.getString(Constants.AUTHTOKEN_KEY);
+            if (authToken == null) {
                 Log.w(TAG, "Unable to update calendars from server -- could not "
-                      + "authenticate user " + username, e);
+                      + "authenticate user " + account);
                 return;
             }
-        } catch (GoogleLoginServiceNotFoundException e) {
-            Log.e(TAG, "Could not find Google login service", e);
+        } catch (IOException e) {
+            Log.w(TAG, "Unable to update calendars from server -- could not "
+                  + "authenticate user " + account, e);
             return;
-        } finally {
-            if (loginHelper != null) {
-                loginHelper.close();
-            }
+        } catch (AuthenticatorException e) {
+            Log.w(TAG, "Unable to update calendars from server -- could not "
+                  + "authenticate user " + account, e);
+            return;
+        } catch (OperationCanceledException e) {
+            Log.w(TAG, "Unable to update calendars from server -- could not "
+                  + "authenticate user " + account, e);
+            return;
         }
 
         // get the current set of calendars.  we'll need to pay attention to
@@ -1121,11 +1158,11 @@
             // get and process the calendars meta feed
             GDataParser parser = null;
             try {
-                String feedUrl = mCalendarClient.getUserCalendarsUrl(username);
-                feedUrl = CalendarSyncAdapter.rewriteUrlforAccount(username, feedUrl);
+                String feedUrl = mCalendarClient.getUserCalendarsUrl(account.mName);
+                feedUrl = CalendarSyncAdapter.rewriteUrlforAccount(account, feedUrl);
                 parser = mCalendarClient.getParserForUserCalendars(feedUrl, authToken);
                 // process the calendars
-                processCalendars(username, parser, existingCalendarIds);
+                processCalendars(account, parser, existingCalendarIds);
             } catch (ParseException pe) {
                 Log.w(TAG, "Unable to process calendars from server -- could not "
                         + "parse calendar feed.", pe);
@@ -1184,7 +1221,7 @@
         }
     }
 
-    private void processCalendars(String username,
+    private void processCalendars(Account account,
                                   GDataParser parser,
                                   Set<Long> existingCalendarIds)
             throws ParseException, IOException {
@@ -1196,7 +1233,7 @@
             entry = parser.readNextEntry(entry);
             if (Config.LOGV) Log.v(TAG, "Read entry: " + entry.toString());
             CalendarEntry calendarEntry = (CalendarEntry) entry;
-            String feedUrl = calendarEntryToContentValues(username, feed, calendarEntry, map);
+            String feedUrl = calendarEntryToContentValues(account, feed, calendarEntry, map);
             if (TextUtils.isEmpty(feedUrl)) {
                 continue;
             }
@@ -1237,7 +1274,8 @@
                 map.put(Calendars.SYNC_EVENTS, syncAndDisplay);
                 map.put(Calendars.SELECTED, syncAndDisplay);
                 map.put(Calendars.HIDDEN, 0);
-                map.put(Calendars._SYNC_ACCOUNT, username);
+                map.put(Calendars._SYNC_ACCOUNT, account.mName);
+                map.put(Calendars._SYNC_ACCOUNT_TYPE, account.mType);
                 if (Config.LOGV) Log.v(TAG, "Adding calendar " + map);
                 // write to db directly, so we don't send a notification.
                 Uri row = insertInternal(calendarContentUri, map);
@@ -1267,7 +1305,7 @@
      * Convert the CalenderEntry to a Bundle that can be inserted/updated into the
      * Calendars table.
      */
-    private String calendarEntryToContentValues(String account, CalendarsFeed feed,
+    private String calendarEntryToContentValues(Account account, CalendarsFeed feed,
             CalendarEntry entry,
             ContentValues map) {
         map.clear();
@@ -2475,7 +2513,10 @@
                 if (!isTemporary()) {
                     Integer syncEvents = initialValues.getAsInteger(Calendars.SYNC_EVENTS);
                     if (syncEvents != null && syncEvents == 1) {
-                        String account = initialValues.getAsString(Calendars._SYNC_ACCOUNT);
+                        String accountName = initialValues.getAsString(Calendars._SYNC_ACCOUNT);
+                        String accountType = initialValues.getAsString(
+                                Calendars._SYNC_ACCOUNT_TYPE);
+                        final Account account = new Account(accountName, accountType);
                         String calendarUrl = initialValues.getAsString(Calendars.URL);
                         scheduleSync(account, false /* two-way sync */, calendarUrl);
                     }
@@ -2962,13 +3003,17 @@
                             String syncId = cursor.getString(EVENTS_SYNC_ID_INDEX);
                             if (!TextUtils.isEmpty(syncId)) {
                                 String syncVersion = cursor.getString(EVENTS_SYNC_VERSION_INDEX);
-                                String syncAccount = cursor.getString(EVENTS_SYNC_ACCOUNT_INDEX);
+                                String syncAccountName =
+                                        cursor.getString(EVENTS_SYNC_ACCOUNT_NAME_INDEX);
+                                String syncAccountType =
+                                        cursor.getString(EVENTS_SYNC_ACCOUNT_TYPE_INDEX);
                                 Long calId = cursor.getLong(EVENTS_CALENDAR_ID_INDEX);
 
                                 ContentValues values = new ContentValues();
                                 values.put(Events._SYNC_ID, syncId);
                                 values.put(Events._SYNC_VERSION, syncVersion);
-                                values.put(Events._SYNC_ACCOUNT, syncAccount);
+                                values.put(Events._SYNC_ACCOUNT, syncAccountName);
+                                values.put(Events._SYNC_ACCOUNT_TYPE, syncAccountType);
                                 values.put(Events.CALENDAR_ID, calId);
                                 mDeletedEventsInserter.insert(values);
 
@@ -3211,12 +3256,12 @@
      * Schedule a calendar sync for the account.
      * @param account the account for which to schedule a sync
      * @param uploadChangesOnly if set, specify that the sync should only send
-     *   up local changes
+ *   up local changes
      * @param url the url feed for the calendar to sync (may be null)
      */
-    private void scheduleSync(String account, boolean uploadChangesOnly, String url) {
+    private void scheduleSync(Account account, boolean uploadChangesOnly, String url) {
         Bundle extras = new Bundle();
-        extras.putString(ContentResolver.SYNC_EXTRAS_ACCOUNT, account);
+        extras.putParcelable(ContentResolver.SYNC_EXTRAS_ACCOUNT, account);
         extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, uploadChangesOnly);
         if (url != null) {
             extras.putString("feed", url);
@@ -3229,28 +3274,29 @@
         // get the account, url, and current selected state
         // for this calendar.
         Cursor cursor = query(ContentUris.withAppendedId(Calendars.CONTENT_URI, id),
-                new String[] { Calendars._SYNC_ACCOUNT,
-                               Calendars.URL,
-                               Calendars.SYNC_EVENTS},
+                new String[] {Calendars._SYNC_ACCOUNT, Calendars._SYNC_ACCOUNT_TYPE,
+                        Calendars.URL, Calendars.SYNC_EVENTS},
                 null /* selection */,
                 null /* selectionArgs */,
                 null /* sort */);
 
-        String account = null;
+        Account account = null;
         String calendarUrl = null;
         boolean oldSyncEvents = false;
         if (cursor != null) {
             try {
                 cursor.moveToFirst();
-                account = cursor.getString(0);
-                calendarUrl = cursor.getString(1);
-                oldSyncEvents = (cursor.getInt(2) != 0);
+                final String accountName = cursor.getString(0);
+                final String accountType = cursor.getString(1);
+                account = new Account(accountName, accountType);
+                calendarUrl = cursor.getString(2);
+                oldSyncEvents = (cursor.getInt(3) != 0);
             } finally {
                 cursor.close();
             }
         }
 
-        if (TextUtils.isEmpty(account) || TextUtils.isEmpty(calendarUrl)) {
+        if (account == null || TextUtils.isEmpty(calendarUrl)) {
             // should not happen?
             Log.w(TAG, "Cannot update subscription because account "
             + "or calendar url empty -- should not happen.");
@@ -3910,6 +3956,8 @@
             DatabaseUtils.cursorStringToContentValues(diffsCursor, Events._SYNC_VERSION, values);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, Events._SYNC_DIRTY, values);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, Events._SYNC_ACCOUNT, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor,
+                    Events._SYNC_ACCOUNT_TYPE, values);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.HTML_URI, values);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.TITLE, values);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.EVENT_LOCATION, values);
@@ -4030,6 +4078,8 @@
         sEventsProjectionMap.put(Events._SYNC_LOCAL_ID, "Events._sync_local_id AS _sync_local_id");
         sEventsProjectionMap.put(Events._SYNC_DIRTY, "Events._sync_dirty AS _sync_dirty");
         sEventsProjectionMap.put(Events._SYNC_ACCOUNT, "Events._sync_account AS _sync_account");
+        sEventsProjectionMap.put(Events._SYNC_ACCOUNT_TYPE,
+                "Events._sync_account_type AS _sync_account_type");
 
         // Instances columns
         sInstancesProjectionMap.put(Instances.BEGIN, "begin");
diff --git a/src/com/android/providers/calendar/CalendarSyncAdapter.java b/src/com/android/providers/calendar/CalendarSyncAdapter.java
index c84a4ff..08d92c7 100644
--- a/src/com/android/providers/calendar/CalendarSyncAdapter.java
+++ b/src/com/android/providers/calendar/CalendarSyncAdapter.java
@@ -58,6 +58,7 @@
 import android.text.format.Time;
 import android.util.Config;
 import android.util.Log;
+import android.accounts.Account;
 
 import java.util.Enumeration;
 import java.util.Hashtable;
@@ -73,18 +74,21 @@
 
     /* package */ static final String USER_AGENT_APP_VERSION = "Android-GData-Calendar/1.1";
 
-    private static final String SELECT_BY_ACCOUNT = Calendars._SYNC_ACCOUNT + "=?";
+    private static final String SELECT_BY_ACCOUNT =
+            Calendars._SYNC_ACCOUNT + "=? AND " + Calendars._SYNC_ACCOUNT_TYPE + "=?";
     private static final String SELECT_BY_ACCOUNT_AND_FEED =
             SELECT_BY_ACCOUNT + " AND " + Calendars.URL + "=?";
 
     private static final String[] CALENDAR_KEY_COLUMNS =
-            new String[]{Calendars._SYNC_ACCOUNT, Calendars.URL};
+            new String[]{Calendars._SYNC_ACCOUNT, Calendars._SYNC_ACCOUNT_TYPE, Calendars.URL};
     private static final String CALENDAR_KEY_SORT_ORDER =
-            Calendars._SYNC_ACCOUNT + "," + Calendars.URL;
+            Calendars._SYNC_ACCOUNT + "," + Calendars._SYNC_ACCOUNT_TYPE + "," + Calendars.URL;
     private static final String[] FEEDS_KEY_COLUMNS =
-            new String[]{SubscribedFeeds.Feeds._SYNC_ACCOUNT, SubscribedFeeds.Feeds.FEED};
+            new String[]{SubscribedFeeds.Feeds._SYNC_ACCOUNT,
+                    SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE, SubscribedFeeds.Feeds.FEED};
     private static final String FEEDS_KEY_SORT_ORDER =
-            SubscribedFeeds.Feeds._SYNC_ACCOUNT + ", " + SubscribedFeeds.Feeds.FEED;
+            SubscribedFeeds.Feeds._SYNC_ACCOUNT + ", " + SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE
+                    + ", " + SubscribedFeeds.Feeds.FEED;
 
     public static class SyncInfo {
         // public String feedUrl;
@@ -514,14 +518,17 @@
 
     protected boolean handleAllDeletedUnavailable(GDataSyncData syncData, String feed) {
         syncData.feedData.remove(feed);
+        final Account account = getAccount();
         getContext().getContentResolver().delete(Calendar.Calendars.CONTENT_URI,
-                Calendar.Calendars._SYNC_ACCOUNT + "=? AND " + Calendar.Calendars.URL + "=?",
-                new String[]{getAccount(), feed});
+                Calendar.Calendars._SYNC_ACCOUNT + "=? AND "
+                        + Calendar.Calendars._SYNC_ACCOUNT_TYPE + "=? AND "
+                        + Calendar.Calendars.URL + "=?",
+                new String[]{account.mName, account.mType, feed});
         return true;
     }
 
     @Override
-    public void onSyncStarting(SyncContext context, String account, boolean forced,
+    public void onSyncStarting(SyncContext context, Account account, boolean forced,
             SyncResult result) {
         mContentResolver = getContext().getContentResolver();
         mServerDiffs = 0;
@@ -593,10 +600,11 @@
         // Base sync info
         map.put(Events._SYNC_ID, event.getId());
         String version = event.getEditUri();
+        final Account account = getAccount();
         if (!StringUtils.isEmpty(version)) {
             // Always rewrite the edit URL to https for dasher account to avoid
             // redirection.
-            map.put(Events._SYNC_VERSION, rewriteUrlforAccount(getAccount(), version));
+            map.put(Events._SYNC_VERSION, rewriteUrlforAccount(account, version));
         }
 
         // see if this is an exception to an existing event/recurrence.
@@ -799,7 +807,8 @@
             return ENTRY_INVALID;
         }
 
-        map.put(SyncConstValue._SYNC_ACCOUNT, getAccount());
+        map.put(SyncConstValue._SYNC_ACCOUNT, account.mName);
+        map.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.mType);
         return ENTRY_OK;
     }
 
@@ -1033,9 +1042,11 @@
         }
 
         // select the set of calendars for this account.
+        final Account account = getAccount();
+        final String[] accountSelectionArgs = new String[]{account.mName, account.mType};
         Cursor cursor = cr.query(Calendar.Calendars.CONTENT_URI,
                 CALENDARS_PROJECTION, SELECT_BY_ACCOUNT,
-                new String[] { getAccount() }, null /* sort order */);
+                accountSelectionArgs, null /* sort order */);
 
         Bundle syncExtras = new Bundle();
 
@@ -1059,7 +1070,6 @@
                     context.setStatusText("Fetching list of calendars");
                     // get rid of the current cursor and fetch from the server.
                     cursor.close();
-                    final String[] accountSelectionArgs = new String[]{getAccount()};
                     cursor = cr.query(
                         Calendar.Calendars.LIVE_CONTENT_URI, CALENDARS_PROJECTION,
                         SELECT_BY_ACCOUNT, accountSelectionArgs, null /* sort order */);
@@ -1086,9 +1096,10 @@
         final SyncInfo syncInfo = (SyncInfo) baseSyncInfo;
         final GDataSyncData syncData = (GDataSyncData) baseSyncData;
 
+        final Account account = getAccount();
         Cursor cursor = getContext().getContentResolver().query(Calendar.Calendars.CONTENT_URI,
                 CALENDARS_PROJECTION, SELECT_BY_ACCOUNT_AND_FEED,
-                new String[] { getAccount(), feed }, null /* sort order */);
+                new String[] { account.mName, account.mType, feed }, null /* sort order */);
 
         ContentValues map = new ContentValues();
         int maxResults = getMaxEntriesPerSync();
@@ -1149,10 +1160,12 @@
         
         // populate temp provider with calendar ids, so joins work.
         ContentValues map = new ContentValues();
+        final Account account = getAccount();
         Cursor c = getContext().getContentResolver().query(
                 Calendar.Calendars.CONTENT_URI,
                 CALENDARS_PROJECTION,
-                SELECT_BY_ACCOUNT, new String[]{getAccount()}, null /* sort order */);
+                SELECT_BY_ACCOUNT, new String[]{account.mName, account.mType},
+                null /* sort order */);
         final int idIndex = c.getColumnIndexOrThrow(Calendars._ID);
         final int urlIndex = c.getColumnIndexOrThrow(Calendars.URL);
         final int timezoneIndex = c.getColumnIndexOrThrow(Calendars.TIMEZONE);
@@ -1166,7 +1179,7 @@
         c.close();
     }
 
-    public void onAccountsChanged(String[] accountsArray) {
+    public void onAccountsChanged(Account[] accountsArray) {
         if (!"yes".equals(SystemProperties.get("ro.config.sync"))) {
             return;
         }
@@ -1183,12 +1196,17 @@
             cursorA = Calendar.Calendars.query(cr, null /* projection */,
                     Calendar.Calendars.SELECTED + "=1", CALENDAR_KEY_SORT_ORDER);
             int urlIndexA = cursorA.getColumnIndexOrThrow(Calendar.Calendars.URL);
-            int accountIndexA = cursorA.getColumnIndexOrThrow(Calendar.Calendars._SYNC_ACCOUNT);
+            int accountNameIndexA = cursorA.getColumnIndexOrThrow(Calendar.Calendars._SYNC_ACCOUNT);
+            int accountTypeIndexA =
+                    cursorA.getColumnIndexOrThrow(Calendar.Calendars._SYNC_ACCOUNT_TYPE);
             cursorB = SubscribedFeeds.Feeds.query(cr, FEEDS_KEY_COLUMNS,
                     SubscribedFeeds.Feeds.AUTHORITY + "=?", new String[]{Calendar.AUTHORITY},
                     FEEDS_KEY_SORT_ORDER);
             int urlIndexB = cursorB.getColumnIndexOrThrow(SubscribedFeeds.Feeds.FEED);
-            int accountIndexB = cursorB.getColumnIndexOrThrow(SubscribedFeeds.Feeds._SYNC_ACCOUNT);
+            int accountNameIndexB =
+                    cursorB.getColumnIndexOrThrow(SubscribedFeeds.Feeds._SYNC_ACCOUNT);
+            int accountTypeIndexB =
+                    cursorB.getColumnIndexOrThrow(SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE);
             for (CursorJoiner.Result joinerResult :
                     new CursorJoiner(cursorA, CALENDAR_KEY_COLUMNS, cursorB, FEEDS_KEY_COLUMNS)) {
                 switch (joinerResult) {
@@ -1196,7 +1214,8 @@
                         SubscribedFeeds.addFeed(
                                 cr,
                                 cursorA.getString(urlIndexA),
-                                cursorA.getString(accountIndexA),
+                                new Account(cursorA.getString(accountNameIndexA),
+                                        cursorA.getString(accountTypeIndexA)),
                                 Calendar.AUTHORITY,
                                 CalendarClient.SERVICE);
                         break;
@@ -1204,7 +1223,8 @@
                         SubscribedFeeds.deleteFeed(
                                 cr,
                                 cursorB.getString(urlIndexB),
-                                cursorB.getString(accountIndexB),
+                                new Account(cursorB.getString(accountNameIndexB),
+                                        cursorB.getString(accountTypeIndexB)),
                                 Calendar.AUTHORITY);
                         break;
                     case BOTH:
@@ -1224,7 +1244,7 @@
      * to/from the device, and thus is determined and passed around as a local variable, where
      * appropriate.
      */
-    protected String getFeedUrl(String account) {
+    protected String getFeedUrl(Account account) {
         throw new UnsupportedOperationException("getFeedUrl() should not get called.");
     }
 
diff --git a/tests/src/com/android/providers/calendar/TestCalendarSyncAdapter.java b/tests/src/com/android/providers/calendar/TestCalendarSyncAdapter.java
index 136b382..1fc77e6 100644
--- a/tests/src/com/android/providers/calendar/TestCalendarSyncAdapter.java
+++ b/tests/src/com/android/providers/calendar/TestCalendarSyncAdapter.java
@@ -26,6 +26,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.text.format.DateUtils;
+import android.accounts.Account;
 
 import java.util.Calendar;
 import java.util.TimeZone;
@@ -40,7 +41,7 @@
     }
 
     @Override
-    public void onSyncStarting(SyncContext context, String account, boolean forced,
+    public void onSyncStarting(SyncContext context, Account account, boolean forced,
             SyncResult result)
     {
     }
@@ -162,7 +163,7 @@
         throw new UnsupportedOperationException("not implemented");
     }
 
-    public void onAccountsChanged(String[] accounts) {
+    public void onAccountsChanged(Account[] accounts) {
     }
 }