am 090d33dc: Port SyncCalendar Tests from the 1.0 release tree to Donut Client.
Merge commit '090d33dc85fe791ff0a9876b19770428cd678e03'
* commit '090d33dc85fe791ff0a9876b19770428cd678e03':
Port SyncCalendar Tests from the 1.0 release tree to Donut Client.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7f53f11..6aabf45 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -42,6 +42,13 @@
android:syncable="true" android:multiprocess="false"
android:readPermission="android.permission.READ_CALENDAR"
android:writePermission="android.permission.WRITE_CALENDAR" />
+ <service android:name="CalendarSyncAdapterService" android:exported="true">
+ <intent-filter>
+ <action android:name="android.content.SyncAdapter" />
+ </intent-filter>
+ <meta-data android:name="android.content.SyncAdapter"
+ android:resource="@xml/syncadapter" />
+ </service>
<activity android:name="CalendarContentProviderTests" android:label="Calendar Content Provider">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/res/xml/syncadapter.xml b/res/xml/syncadapter.xml
new file mode 100644
index 0000000..b5f89cc
--- /dev/null
+++ b/res/xml/syncadapter.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the SyncAdapter. -->
+
+<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+ android:contentAuthority="calendar"
+ android:accountType="com.google.GAIA"
+/>
diff --git a/src/com/android/providers/calendar/CalendarProvider.java b/src/com/android/providers/calendar/CalendarProvider.java
index 59cc896..4079d9a 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;
@@ -45,7 +45,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SyncAdapter;
import android.content.SyncContext;
import android.content.UriMatcher;
import android.database.Cursor;
@@ -69,12 +68,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;
@@ -88,15 +87,16 @@
import java.util.TimeZone;
public class CalendarProvider extends AbstractSyncableContentProvider {
-
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 +104,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;
@@ -235,7 +236,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";
@@ -275,7 +276,6 @@
private AlarmManager mAlarmManager;
- private CalendarSyncAdapter mSyncAdapter;
private CalendarAppWidgetProvider mAppWidgetProvider = CalendarAppWidgetProvider.getInstance();
/**
@@ -309,6 +309,8 @@
public boolean onCreate() {
super.onCreate();
+ setTempProviderSyncAdapter(new CalendarSyncAdapter(getContext(), this));
+
// Register for Intent broadcasts
IntentFilter filter = new IntentFilter();
@@ -566,6 +568,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
}
@@ -589,6 +612,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
@@ -618,6 +642,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
@@ -652,7 +677,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 +
@@ -675,6 +701,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" +
@@ -831,18 +858,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();
@@ -856,28 +882,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 */);
}
@@ -890,8 +916,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) {
@@ -900,14 +926,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);
@@ -918,7 +945,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 */);
}
@@ -1081,36 +1108,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
@@ -1126,11 +1162,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);
@@ -1189,7 +1225,7 @@
}
}
- private void processCalendars(String username,
+ private void processCalendars(Account account,
GDataParser parser,
Set<Long> existingCalendarIds)
throws ParseException, IOException {
@@ -1201,7 +1237,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;
}
@@ -1242,7 +1278,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);
@@ -1272,7 +1309,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();
@@ -2472,7 +2509,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);
}
@@ -3083,13 +3123,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);
@@ -3332,12 +3376,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);
@@ -3350,28 +3394,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.");
@@ -3422,14 +3467,6 @@
}
@Override
- public synchronized SyncAdapter getSyncAdapter() {
- if (mSyncAdapter == null) {
- mSyncAdapter = new CalendarSyncAdapter(getContext(), this);
- }
- return mSyncAdapter;
- }
-
- @Override
public void onSyncStop(SyncContext context, boolean success) {
super.onSyncStop(context, success);
if (Log.isLoggable(TAG, Log.DEBUG)) {
@@ -4031,6 +4068,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);
@@ -4151,6 +4190,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 0c53c6a..100cded 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;
@@ -74,18 +75,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;
@@ -519,14 +523,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;
@@ -598,10 +605,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.
@@ -804,7 +812,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;
}
@@ -1038,9 +1047,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();
@@ -1064,7 +1075,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 */);
@@ -1091,9 +1101,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();
@@ -1154,10 +1165,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);
@@ -1171,7 +1184,7 @@
c.close();
}
- public void onAccountsChanged(String[] accountsArray) {
+ public void onAccountsChanged(Account[] accountsArray) {
if (!"yes".equals(SystemProperties.get("ro.config.sync"))) {
return;
}
@@ -1188,12 +1201,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) {
@@ -1201,7 +1219,8 @@
SubscribedFeeds.addFeed(
cr,
cursorA.getString(urlIndexA),
- cursorA.getString(accountIndexA),
+ new Account(cursorA.getString(accountNameIndexA),
+ cursorA.getString(accountTypeIndexA)),
Calendar.AUTHORITY,
CalendarClient.SERVICE);
break;
@@ -1209,7 +1228,8 @@
SubscribedFeeds.deleteFeed(
cr,
cursorB.getString(urlIndexB),
- cursorB.getString(accountIndexB),
+ new Account(cursorB.getString(accountNameIndexB),
+ cursorB.getString(accountTypeIndexB)),
Calendar.AUTHORITY);
break;
case BOTH:
@@ -1229,7 +1249,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/src/com/android/providers/calendar/CalendarSyncAdapterService.java b/src/com/android/providers/calendar/CalendarSyncAdapterService.java
new file mode 100644
index 0000000..7634f2c
--- /dev/null
+++ b/src/com/android/providers/calendar/CalendarSyncAdapterService.java
@@ -0,0 +1,29 @@
+package com.android.providers.calendar;
+
+import android.app.Service;
+import android.os.IBinder;
+import android.content.Intent;
+import android.content.ContentProviderClient;
+import android.content.ContentProvider;
+import android.content.SyncableContentProvider;
+import android.provider.Calendar;
+
+public class CalendarSyncAdapterService extends Service {
+ private ContentProviderClient mContentProviderClient = null;
+
+ public void onCreate() {
+ mContentProviderClient =
+ getContentResolver().acquireContentProviderClient(Calendar.CONTENT_URI);
+ }
+
+ public void onDestroy() {
+ mContentProviderClient.release();
+ }
+
+ public IBinder onBind(Intent intent) {
+ ContentProvider contentProvider = mContentProviderClient.getLocalContentProvider();
+ if (contentProvider == null) throw new IllegalStateException();
+ SyncableContentProvider syncableContentProvider = (SyncableContentProvider)contentProvider;
+ return syncableContentProvider.getTempProviderSyncAdapter().getISyncAdapter().asBinder();
+ }
+}
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) {
}
}