am 84f3e50c: (-s ours) Import revised translations. DO NOT MERGE
Merge commit '84f3e50c011372ba004ebc349def9558d6dda3c5' into eclair
* commit '84f3e50c011372ba004ebc349def9558d6dda3c5':
Import revised translations. DO NOT MERGE
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c485245..a66809f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -6,7 +6,10 @@
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
+ <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.cp" />
<uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ" />
@@ -19,5 +22,12 @@
android:syncable="true" android:multiprocess="false"
android:readPermission="android.permission.READ_CONTACTS"
android:writePermission="android.permission.WRITE_CONTACTS" />
+ <service android:name="ContactsSyncAdapterService" 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>
</application>
</manifest>
diff --git a/res/drawable-hdpi/app_icon.png b/res/drawable-hdpi/app_icon.png
new file mode 100755
index 0000000..0bcbca4
--- /dev/null
+++ b/res/drawable-hdpi/app_icon.png
Binary files differ
diff --git a/res/drawable/app_icon.png b/res/drawable-mdpi/app_icon.png
similarity index 100%
rename from res/drawable/app_icon.png
rename to res/drawable-mdpi/app_icon.png
Binary files differ
diff --git a/res/xml/syncadapter.xml b/res/xml/syncadapter.xml
new file mode 100644
index 0000000..d46be9a
--- /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="contacts"
+ android:accountType="com.google"
+/>
diff --git a/src/com/android/providers/contacts/ContactsSyncAdapter.java b/src/com/android/providers/contacts/ContactsSyncAdapter.java
index 0a5090b..c15f2da 100644
--- a/src/com/android/providers/contacts/ContactsSyncAdapter.java
+++ b/src/com/android/providers/contacts/ContactsSyncAdapter.java
@@ -19,8 +19,6 @@
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.providers.AbstractGDataSyncAdapter;
import com.google.wireless.gdata.client.GDataServiceClient;
import com.google.wireless.gdata.client.QueryParams;
@@ -72,6 +70,8 @@
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
+import android.accounts.AccountManager;
+import android.accounts.Account;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -126,7 +126,7 @@
private boolean mPerformedGetServerDiffs;
// Only valid during a sync. If set then this sync was a forced sync request
- private boolean mSyncForced;
+ private boolean mIsManualSync;
private int mPhotoDownloads;
private int mPhotoUploads;
@@ -221,7 +221,7 @@
throw new UnsupportedOperationException("this should never be used");
}
- protected String getFeedUrl(String account) {
+ protected String getFeedUrl(Account account) {
throw new UnsupportedOperationException("this should never be used");
}
@@ -281,7 +281,7 @@
* Look at the groups sync settings and the overall sync preference to determine which
* feeds to sync and add them to the feedsToSync list.
*/
- public static void addContactsFeedsToSync(ContentResolver cr, String account,
+ public static void addContactsFeedsToSync(ContentResolver cr, Account account,
Collection<String> feedsToSync) {
boolean shouldSyncEverything = getShouldSyncEverything(cr, account);
if (shouldSyncEverything) {
@@ -290,7 +290,8 @@
}
Cursor cursor = cr.query(Contacts.Groups.CONTENT_URI, new String[]{Groups._SYNC_ID},
- "_sync_account=? AND should_sync>0", new String[]{account}, null);
+ "_sync_account=? AND _sync_account_type=? AND should_sync>0",
+ new String[]{account.name, account.type}, null);
try {
while (cursor.moveToNext()) {
feedsToSync.add(getContactsFeedForGroup(account, cursor.getString(0)));
@@ -300,20 +301,22 @@
}
}
- private static boolean getShouldSyncEverything(ContentResolver cr, String account) {
- String value = Contacts.Settings.getSetting(cr, account, Contacts.Settings.SYNC_EVERYTHING);
+ private static boolean getShouldSyncEverything(ContentResolver cr, Account account) {
+ // TODO(fredq) should be using account instead of null
+ String value = Contacts.Settings.getSetting(cr, null, Contacts.Settings.SYNC_EVERYTHING);
return !TextUtils.isEmpty(value) && !"0".equals(value);
}
private void getServerPhotos(SyncContext context, String feedUrl, int maxDownloads,
GDataSyncData syncData, SyncResult syncResult) {
final ContentResolver cr = getContext().getContentResolver();
+ final Account account = getAccount();
Cursor cursor = cr.query(
Photos.CONTENT_URI,
new String[]{Photos._SYNC_ID, Photos._SYNC_VERSION, Photos.PERSON_ID,
Photos.DOWNLOAD_REQUIRED, Photos._ID}, ""
- + "_sync_account=? AND download_required != 0",
- new String[]{getAccount()}, null);
+ + "_sync_account=? AND _sync_account_type=? AND download_required != 0",
+ new String[]{account.name, account.type}, null);
try {
int numFetched = 0;
while (cursor.moveToNext()) {
@@ -425,7 +428,7 @@
GDataServiceClient client = getGDataServiceClient();
String authToken = getAuthToken();
ContentResolver cr = getContext().getContentResolver();
- final String account = getAccount();
+ final Account account = getAccount();
Cursor c = clientDiffs.query(Photos.CONTENT_URI, null /* all columns */,
null /* no where */, null /* no where args */, null /* default sort order */);
@@ -508,14 +511,8 @@
}
}
syncResult.stats.numAuthExceptions++;
- try {
- GoogleLoginServiceBlockingHelper.invalidateAuthToken(getContext(),
- authToken);
- } catch (GoogleLoginServiceNotFoundException e1) {
- if (Config.LOGD) {
- Log.d(TAG, "could not invalidate auth token", e1);
- }
- }
+ AccountManager.get(getContext()).invalidateAuthToken(
+ "com.google", authToken);
return;
case HttpException.SC_CONFLICT:
@@ -580,7 +577,7 @@
}
static protected String cursorToEntryImpl(ContentResolver cr, Cursor c, Entry entry,
- String account) throws ParseException {
+ Account account) throws ParseException {
cursorToBaseEntry(entry, account, c);
String createUrl = null;
if (entry instanceof ContactEntry) {
@@ -611,7 +608,7 @@
entry.setSystemGroup(null);
}
- private static void cursorToContactEntry(String account, ContentResolver cr, Cursor c,
+ private static void cursorToContactEntry(Account account, ContentResolver cr, Cursor c,
ContactEntry entry)
throws ParseException {
entry.setTitle(c.getString(c.getColumnIndexOrThrow(People.NAME)));
@@ -638,11 +635,11 @@
return false;
}
- protected static void deletedCursorToEntryImpl(Cursor c, Entry entry, String account) {
+ protected static void deletedCursorToEntryImpl(Cursor c, Entry entry, Account account) {
cursorToBaseEntry(entry, account, c);
}
- private static void cursorToBaseEntry(Entry entry, String account, Cursor c) {
+ private static void cursorToBaseEntry(Entry entry, Account account, Cursor c) {
String feedUrl;
if (entry instanceof ContactEntry) {
feedUrl = getContactsFeedForAccount(account);
@@ -662,7 +659,8 @@
}
}
- private static void addPhonesToContactEntry(ContentResolver cr, long personId, ContactEntry entry)
+ private static void addPhonesToContactEntry(ContentResolver cr, long personId,
+ ContactEntry entry)
throws ParseException {
Cursor c = cr.query(Phones.CONTENT_URI, null, "person=" + personId, null, null);
int numberIndex = c.getColumnIndexOrThrow(People.Phones.NUMBER);
@@ -750,7 +748,7 @@
}
}
- private static void addGroupMembershipToContactEntry(String account, ContentResolver cr,
+ private static void addGroupMembershipToContactEntry(Account account, ContentResolver cr,
long personId, ContactEntry entry) throws ParseException {
Cursor c = cr.query(GroupMembership.RAW_CONTENT_URI, null,
"person=" + personId, null, null);
@@ -841,7 +839,8 @@
* actions on the ContentProvider to represent the entry.
*/
protected void updateProvider(Feed feed, Long syncLocalId,
- Entry baseEntry, ContentProvider provider, Object syncInfo) throws ParseException {
+ Entry baseEntry, ContentProvider provider, Object syncInfo,
+ GDataSyncData.FeedData feedSyncData) throws ParseException {
// This is a hack to delete these incorrectly created contacts named "Starred in Android"
if (baseEntry instanceof ContactEntry
@@ -860,7 +859,7 @@
updateProviderImpl(getAccount(), syncLocalId, baseEntry, provider);
}
- protected static void updateProviderImpl(String account, Long syncLocalId,
+ protected static void updateProviderImpl(Account account, Long syncLocalId,
Entry entry, ContentProvider provider) throws ParseException {
// If this is a deleted entry then add it to the DELETED_CONTENT_URI
ContentValues deletedValues = null;
@@ -875,7 +874,8 @@
if (!TextUtils.isEmpty(editUri)) {
deletedValues.put(SyncConstValue._SYNC_VERSION, lastItemFromUri(editUri));
}
- deletedValues.put(SyncConstValue._SYNC_ACCOUNT, account);
+ deletedValues.put(SyncConstValue._SYNC_ACCOUNT, account.name);
+ deletedValues.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.type);
}
if (entry instanceof ContactEntry) {
@@ -897,7 +897,7 @@
throw new IllegalArgumentException("unknown entry type, " + entry.getClass().getName());
}
- protected static void updateProviderWithContactEntry(String account, Long syncLocalId,
+ protected static void updateProviderWithContactEntry(Account account, Long syncLocalId,
ContactEntry entry, ContentProvider provider) throws ParseException {
final String name = entry.getTitle();
final String notes = entry.getContent();
@@ -910,7 +910,8 @@
values.put(People.NAME, name);
values.put(People.NOTES, notes);
values.put(People.PHONETIC_NAME, yomiName);
- values.put(SyncConstValue._SYNC_ACCOUNT, account);
+ values.put(SyncConstValue._SYNC_ACCOUNT, account.name);
+ values.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.type);
values.put(SyncConstValue._SYNC_ID, personSyncId);
values.put(SyncConstValue._SYNC_DIRTY, "0");
values.put(SyncConstValue._SYNC_LOCAL_ID, syncLocalId);
@@ -924,7 +925,8 @@
values.clear();
values.put(Photos.PERSON_ID, ContentUris.parseId(personUri));
values.put(Photos.EXISTS_ON_SERVER, photoExistsOnServer ? 1 : 0);
- values.put(SyncConstValue._SYNC_ACCOUNT, account);
+ values.put(SyncConstValue._SYNC_ACCOUNT, account.name);
+ values.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.type);
values.put(SyncConstValue._SYNC_ID, personSyncId);
values.put(SyncConstValue._SYNC_DIRTY, 0);
values.put(SyncConstValue._SYNC_LOCAL_ID, syncLocalId);
@@ -1001,7 +1003,8 @@
continue;
}
values.clear();
- values.put(GroupMembership.GROUP_SYNC_ACCOUNT, account);
+ values.put(GroupMembership.GROUP_SYNC_ACCOUNT, account.name);
+ values.put(GroupMembership.GROUP_SYNC_ACCOUNT_TYPE, account.type);
values.put(GroupMembership.GROUP_SYNC_ID,
lastItemFromUri(groupMembershipInfo.getGroup()));
Uri uri = Uri.withAppendedPath(personUri, GroupMembership.CONTENT_DIRECTORY);
@@ -1053,13 +1056,14 @@
}
}
- protected static void updateProviderWithGroupEntry(String account, Long syncLocalId,
+ protected static void updateProviderWithGroupEntry(Account account, Long syncLocalId,
GroupEntry entry, ContentProvider provider) throws ParseException {
ContentValues values = new ContentValues();
values.put(Groups.NAME, entry.getTitle());
values.put(Groups.NOTES, entry.getContent());
values.put(Groups.SYSTEM_ID, entry.getSystemGroup());
- values.put(Groups._SYNC_ACCOUNT, account);
+ values.put(Groups._SYNC_ACCOUNT, account.name);
+ values.put(Groups._SYNC_ACCOUNT_TYPE, account.type);
values.put(Groups._SYNC_ID, lastItemFromUri(entry.getId()));
values.put(Groups._SYNC_DIRTY, 0);
values.put(Groups._SYNC_LOCAL_ID, syncLocalId);
@@ -1116,17 +1120,19 @@
* that we don't expect.
*/
@Override
- public void onAccountsChanged(String[] accountsArray) {
+ public void onAccountsChanged(Account[] accountsArray) {
if (!"yes".equals(SystemProperties.get("ro.config.sync"))) {
return;
}
ContentResolver cr = getContext().getContentResolver();
- for (String account : accountsArray) {
- String value = Contacts.Settings.getSetting(cr, account,
+ for (Account account : accountsArray) {
+ // TODO(fredq) should be using account instead of null
+ String value = Contacts.Settings.getSetting(cr, null,
Contacts.Settings.SYNC_EVERYTHING);
if (value == null) {
- Contacts.Settings.setSetting(cr, account, Contacts.Settings.SYNC_EVERYTHING, "1");
+ // TODO(fredq) should be using account instead of null
+ Contacts.Settings.setSetting(cr, null, Contacts.Settings.SYNC_EVERYTHING, "1");
}
updateSubscribedFeeds(cr, account);
}
@@ -1137,8 +1143,8 @@
* @param account The account
* @return The contacts feed url for a specific account.
*/
- public static String getContactsFeedForAccount(String account) {
- String url = CONTACTS_FEED_URL + account + "/base2_property-android";
+ public static String getContactsFeedForAccount(Account account) {
+ String url = CONTACTS_FEED_URL + account.name + "/base2_property-android";
return rewriteUrlforAccount(account, url);
}
@@ -1148,7 +1154,7 @@
* @param groupSyncId The group id
* @return The contacts feed url for a specific account and group.
*/
- public static String getContactsFeedForGroup(String account, String groupSyncId) {
+ public static String getContactsFeedForGroup(Account account, String groupSyncId) {
String groupId = getCanonicalGroupsFeedForAccount(account);
try {
groupId = URLEncoder.encode(groupId, "utf-8");
@@ -1163,8 +1169,8 @@
* @param account The account
* @return The groups feed url for a specific account.
*/
- public static String getGroupsFeedForAccount(String account) {
- String url = GROUPS_FEED_URL + account + "/base2_property-android";
+ public static String getGroupsFeedForAccount(Account account) {
+ String url = GROUPS_FEED_URL + account.name + "/base2_property-android";
return rewriteUrlforAccount(account, url);
}
@@ -1177,8 +1183,8 @@
* @param account The account
* @return The groups feed url for a specific account.
*/
- public static String getCanonicalGroupsFeedForAccount(String account) {
- return GROUPS_FEED_URL + account + "/base";
+ public static String getCanonicalGroupsFeedForAccount(Account account) {
+ return GROUPS_FEED_URL + account.name + "/base";
}
/**
@@ -1186,8 +1192,8 @@
* @param account The account
* @return The photo feed url for a specific account.
*/
- public static String getPhotosFeedForAccount(String account) {
- String url = PHOTO_FEED_URL + account;
+ public static String getPhotosFeedForAccount(Account account) {
+ String url = PHOTO_FEED_URL + account.name;
return rewriteUrlforAccount(account, url);
}
@@ -1196,7 +1202,7 @@
}
@Override
- protected void updateQueryParameters(QueryParams params) {
+ protected void updateQueryParameters(QueryParams params, GDataSyncData.FeedData feedSyncData) {
// we want to get the events ordered by last modified, so we can
// recover in case we cannot process the entire feed.
params.setParamValue("orderby", "lastmodified");
@@ -1210,13 +1216,13 @@
}
@Override
- public void onSyncStarting(SyncContext context, String account, boolean forced,
+ public void onSyncStarting(SyncContext context, Account account, boolean manualSync,
SyncResult result) {
mPerformedGetServerDiffs = false;
- mSyncForced = forced;
+ mIsManualSync = manualSync;
mPhotoDownloads = 0;
mPhotoUploads = 0;
- super.onSyncStarting(context, account, forced, result);
+ super.onSyncStarting(context, account, manualSync, result);
}
@Override
@@ -1224,20 +1230,19 @@
final ContentResolver cr = getContext().getContentResolver();
if (success && mPerformedGetServerDiffs && !mSyncCanceled) {
+ final Account account = getAccount();
Cursor cursor = cr.query(
Photos.CONTENT_URI,
new String[]{Photos._SYNC_ID, Photos._SYNC_VERSION, Photos.PERSON_ID,
Photos.DOWNLOAD_REQUIRED}, ""
- + "_sync_account=? AND download_required != 0",
- new String[]{getAccount()}, null);
+ + "_sync_account=? AND _sync_account_type=? AND download_required != 0",
+ new String[]{account.name, account.type}, null);
try {
if (cursor.getCount() != 0) {
Bundle extras = new Bundle();
- extras.putString(ContentResolver.SYNC_EXTRAS_ACCOUNT, getAccount());
- extras.putBoolean(ContentResolver.SYNC_EXTRAS_FORCE, mSyncForced);
- extras.putString("feed",
- ContactsSyncAdapter.getPhotosFeedForAccount(getAccount()));
- getContext().getContentResolver().startSync(Contacts.CONTENT_URI, extras);
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, mIsManualSync);
+ extras.putString("feed", ContactsSyncAdapter.getPhotosFeedForAccount(account));
+ ContentResolver.requestSync(account, Contacts.AUTHORITY, extras);
}
} finally {
cursor.close();
@@ -1247,15 +1252,16 @@
super.onSyncEnding(context, success);
}
- public static void updateSubscribedFeeds(ContentResolver cr, String account) {
+ public static void updateSubscribedFeeds(ContentResolver cr, Account account) {
Set<String> feedsToSync = Sets.newHashSet();
feedsToSync.add(getGroupsFeedForAccount(account));
addContactsFeedsToSync(cr, account, feedsToSync);
Cursor c = SubscribedFeeds.Feeds.query(cr, sSubscriptionProjection,
- SubscribedFeeds.Feeds.AUTHORITY + "=? AND "
- + SubscribedFeeds.Feeds._SYNC_ACCOUNT + "=?",
- new String[]{Contacts.AUTHORITY, account}, null);
+ SubscribedFeeds.Feeds.AUTHORITY + "=?"
+ + " AND " + SubscribedFeeds.Feeds._SYNC_ACCOUNT + "=?"
+ + " AND " + SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE + "=?",
+ new String[]{Contacts.AUTHORITY, account.name, account.type}, null);
try {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "scanning over subscriptions with authority "
@@ -1282,9 +1288,8 @@
// request a sync of this feed
Bundle extras = new Bundle();
- extras.putString(ContentResolver.SYNC_EXTRAS_ACCOUNT, account);
extras.putString("feed", feed);
- cr.startSync(Contacts.CONTENT_URI, extras);
+ ContentResolver.requestSync(account, Contacts.AUTHORITY, extras);
}
}
}
diff --git a/src/com/android/providers/contacts/ContactsSyncAdapterService.java b/src/com/android/providers/contacts/ContactsSyncAdapterService.java
new file mode 100644
index 0000000..ee95153
--- /dev/null
+++ b/src/com/android/providers/contacts/ContactsSyncAdapterService.java
@@ -0,0 +1,29 @@
+package com.android.providers.contacts;
+
+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.Contacts;
+
+public class ContactsSyncAdapterService extends Service {
+ private ContentProviderClient mContentProviderClient = null;
+
+ public void onCreate() {
+ mContentProviderClient =
+ getContentResolver().acquireContentProviderClient(Contacts.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/src/com/android/providers/contacts/GoogleContactsProvider.java b/src/com/android/providers/contacts/GoogleContactsProvider.java
index 3f7bef5..77bce2c 100644
--- a/src/com/android/providers/contacts/GoogleContactsProvider.java
+++ b/src/com/android/providers/contacts/GoogleContactsProvider.java
@@ -27,13 +27,13 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SyncAdapter;
import android.content.SyncContext;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.SystemClock;
import android.provider.Contacts;
import android.text.TextUtils;
+import android.accounts.Account;
import java.util.Iterator;
import java.util.Map;
@@ -64,23 +64,25 @@
+ " OUTER JOIN groups AS g "
+ " ON (gm.group_id=g._id "
+ " OR (gm.group_sync_id=g._sync_id "
- + " AND gm.group_sync_account=g._sync_account))) "
+ + " AND gm.group_sync_account=g._sync_account "
+ + " AND gm.group_sync_account_type=g._sync_account_type))) "
+ " GROUP BY person) "
+ " WHERE max_should_sync=0)"
+ " OR _id NOT IN (SELECT person FROM groupmembership))"
+ " AND _sync_dirty=0 "
- + " AND _sync_account=?";
+ + " AND _sync_account=? "
+ + " AND _sync_account_type=?";
- private SyncAdapter mSyncAdapter = null;
private AlarmManager mAlarmService = null;
@Override
public boolean onCreate() {
+ setTempProviderSyncAdapter(new ContactsSyncAdapter(getContext(), this));
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_PURGE_CONTACTS.equals(intent.getAction())) {
- purgeContacts(intent.getStringExtra("account"));
+ purgeContacts((Account) intent.getParcelableExtra("account"));
}
}
};
@@ -89,17 +91,7 @@
}
@Override
- public synchronized SyncAdapter getSyncAdapter() {
- if (mSyncAdapter != null) {
- return mSyncAdapter;
- }
-
- mSyncAdapter = new ContactsSyncAdapter(getContext(), this);
- return mSyncAdapter;
- }
-
- @Override
- protected void onLocalChangesForAccount(final ContentResolver resolver, String account,
+ protected void onLocalChangesForAccount(final ContentResolver resolver, Account account,
boolean groupsModified) {
ContactsSyncAdapter.updateSubscribedFeeds(resolver, account);
if (groupsModified) {
@@ -111,7 +103,7 @@
* Delete any non-sync_dirty contacts associated with the given account
* that are not in any of the synced groups.
*/
- private void schedulePurge(String account) {
+ private void schedulePurge(Account account) {
if (isTemporary()) {
throw new IllegalStateException("this must not be called on temp providers");
}
@@ -137,18 +129,19 @@
purgeContacts(getSyncingAccount());
}
- private void purgeContacts(String account) {
+ private void purgeContacts(Account account) {
if (isTemporary()) {
throw new IllegalStateException("this must not be called on temp providers");
}
SQLiteDatabase db = getDatabase();
db.beginTransaction();
try {
+ // TODO(fredq) should be using account instead of null
final String value = Contacts.Settings.getSetting(getContext().getContentResolver(),
- account, Contacts.Settings.SYNC_EVERYTHING);
+ null, Contacts.Settings.SYNC_EVERYTHING);
final boolean shouldSyncEverything = !TextUtils.isEmpty(value) && !"0".equals(value);
if (!shouldSyncEverything) {
- db.execSQL(PURGE_UNSYNCED_CONTACTS_SQL, new String[]{account});
+ db.execSQL(PURGE_UNSYNCED_CONTACTS_SQL, new String[]{account.name, account.type});
}
// remove any feeds in the SyncData that aren't in the current sync set.
@@ -179,12 +172,13 @@
}
}
- private AbstractGDataSyncAdapter.GDataSyncData readSyncData(String account) {
+ private AbstractGDataSyncAdapter.GDataSyncData readSyncData(Account account) {
if (!getDatabase().inTransaction()) {
throw new IllegalStateException("you can only call this from within a transaction");
}
- Cursor c = getDatabase().query("_sync_state", new String[]{"data"}, "_sync_account=?",
- new String[]{account}, null, null, null);
+ Cursor c = getDatabase().query("_sync_state", new String[]{"data"},
+ "_sync_account=? AND _sync_account_type=?",
+ new String[]{account.name, account.type}, null, null, null);
try {
byte[] data = null;
if (c.moveToNext()) data = c.getBlob(0);
@@ -194,15 +188,17 @@
}
}
- private void writeSyncData(String account, AbstractGDataSyncAdapter.GDataSyncData syncData) {
+ private void writeSyncData(Account account, AbstractGDataSyncAdapter.GDataSyncData syncData) {
final SQLiteDatabase db = getDatabase();
if (!db.inTransaction()) {
throw new IllegalStateException("you can only call this from within a transaction");
}
- db.delete("_sync_state", "_sync_account=?", new String[]{account});
+ db.delete("_sync_state", "_sync_account=? AND _sync_account_type=?",
+ new String[]{account.name, account.type});
ContentValues values = new ContentValues();
values.put("data", ContactsSyncAdapter.newBytesFromGDataSyncData(syncData));
- values.put("_sync_account", account);
+ values.put("_sync_account", account.name);
+ values.put("_sync_account_type", account.type);
db.insert("_sync_state", "_sync_account", values);
}
}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 8d207ad..c06a5e6 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
+ <uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
diff --git a/tests/src/com/android/providers/contacts/ContactsSyncAdapterTest.java b/tests/src/com/android/providers/contacts/ContactsSyncAdapterTest.java
index dc0204e..018907a 100644
--- a/tests/src/com/android/providers/contacts/ContactsSyncAdapterTest.java
+++ b/tests/src/com/android/providers/contacts/ContactsSyncAdapterTest.java
@@ -30,13 +30,14 @@
import android.provider.SyncConstValue;
import android.test.ProviderTestCase;
import android.util.Log;
+import android.accounts.Account;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ContactsSyncAdapterTest extends ProviderTestCase<ContactsProvider> {
- private static final String ACCOUNT = "testaccount@example.com";
+ private static final Account ACCOUNT = new Account("testaccount@example.com", "example.type");
private MockSyncContext mMockSyncContext = new MockSyncContext();
private ContactsSyncAdapter mSyncAdapter = null;
@@ -173,7 +174,7 @@
}
}
- private static void addGroupMembership(ContactEntry p, String account, String groupId) {
+ private static void addGroupMembership(ContactEntry p, Account account, String groupId) {
GroupMembershipInfo groupInfo = new GroupMembershipInfo();
final String serverId =
ContactsSyncAdapter.getCanonicalGroupsFeedForAccount(account) + "/" + groupId;
@@ -420,11 +421,12 @@
assertEquals(expectedServerVersion, getString(cursor, Photos._SYNC_VERSION));
}
- private Uri addPerson(ContactsProvider provider, String name,
- String account, String syncId) {
+ private Uri addPerson(ContactsProvider provider, Account account,
+ String name, String syncId) {
ContentValues values = new ContentValues();
values.put(People.NAME, name);
- values.put(People._SYNC_ACCOUNT, account);
+ values.put(People._SYNC_ACCOUNT, account.name);
+ values.put(People._SYNC_ACCOUNT_TYPE, account.type);
values.put(People._SYNC_ID, syncId);
return provider.insert(People.CONTENT_URI, values);
}
@@ -452,7 +454,10 @@
feedFromEntry(entry) + "/" + getString(cursor, SyncConstValue._SYNC_ID));
assertEquals(dumpRow(cursor), entry.getEditUri(),
entry.getId() + "/" + getString(cursor, SyncConstValue._SYNC_VERSION));
- assertEquals(dumpRow(cursor), ACCOUNT, getString(cursor, SyncConstValue._SYNC_ACCOUNT));
+ assertEquals(dumpRow(cursor), ACCOUNT.name,
+ getString(cursor, SyncConstValue._SYNC_ACCOUNT));
+ assertEquals(dumpRow(cursor), ACCOUNT.type,
+ getString(cursor, SyncConstValue._SYNC_ACCOUNT_TYPE));
assertEquals(dumpRow(cursor), entry.getTitle(), getString(cursor, Groups.NAME));
assertEquals(dumpRow(cursor), entry.getSystemGroup(), getString(cursor, Groups.SYSTEM_ID));
assertEquals(dumpRow(cursor), entry.getContent(), getString(cursor, Groups.NOTES));
@@ -531,7 +536,10 @@
feedFromEntry(entry) + "/" + getString(cursor, SyncConstValue._SYNC_ID));
assertEquals(dumpRow(cursor), entry.getEditUri(),
entry.getId() + "/" + getString(cursor, SyncConstValue._SYNC_VERSION));
- assertEquals(dumpRow(cursor), ACCOUNT, getString(cursor, SyncConstValue._SYNC_ACCOUNT));
+ assertEquals(dumpRow(cursor), ACCOUNT.name,
+ getString(cursor, SyncConstValue._SYNC_ACCOUNT));
+ assertEquals(dumpRow(cursor), ACCOUNT.type,
+ getString(cursor, SyncConstValue._SYNC_ACCOUNT_TYPE));
assertEquals(dumpRow(cursor), entry.getTitle(), getString(cursor, People.NAME));
assertEquals(dumpRow(cursor), entry.getContent(), getString(cursor, People.NOTES));
if (syncLocalId != null) {
@@ -562,7 +570,10 @@
feedFromEntry(entry) + "/" + getString(cursor, SyncConstValue._SYNC_ID));
assertEquals(dumpRow(cursor), entry.getEditUri(),
entry.getId() + "/" + getString(cursor, SyncConstValue._SYNC_VERSION));
- assertEquals(dumpRow(cursor), ACCOUNT, getString(cursor, SyncConstValue._SYNC_ACCOUNT));
+ assertEquals(dumpRow(cursor), ACCOUNT.name,
+ getString(cursor, SyncConstValue._SYNC_ACCOUNT));
+ assertEquals(dumpRow(cursor), ACCOUNT.type,
+ getString(cursor, SyncConstValue._SYNC_ACCOUNT_TYPE));
if (syncLocalId != null) {
assertEquals(dumpRow(cursor),
syncLocalId.toString(), getString(cursor, SyncConstValue._SYNC_LOCAL_ID));
@@ -801,7 +812,7 @@
protected void setUp() throws Exception {
super.setUp();
- mSyncAdapter = (ContactsSyncAdapter)getProvider().getSyncAdapter();
+ mSyncAdapter = (ContactsSyncAdapter)getProvider().getTempProviderSyncAdapter();
getProvider().onSyncStart(mMockSyncContext, ACCOUNT);
}
diff --git a/tests/src/com/android/providers/contacts/SyncContactsTest.java b/tests/src/com/android/providers/contacts/SyncContactsTest.java
index e4adf5b..7456bfa 100644
--- a/tests/src/com/android/providers/contacts/SyncContactsTest.java
+++ b/tests/src/com/android/providers/contacts/SyncContactsTest.java
@@ -1,20 +1,23 @@
package com.android.providers.contacts;
-import com.google.android.collect.Maps;
-import com.google.android.googlelogin.GoogleLoginServiceBlockingHelper;
-import com.google.android.googlelogin.GoogleLoginServiceNotFoundException;
-
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.Contacts;
import android.test.RenamingDelegatingContext;
import android.test.SyncBaseInstrumentation;
-import android.util.Log;
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.OperationCanceledException;
+import android.accounts.AuthenticatorException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.io.IOException;
+
+import com.google.android.collect.Maps;
+import com.google.android.googlelogin.GoogleLoginServiceConstants;
public class SyncContactsTest extends SyncBaseInstrumentation {
private Context mTargetContext;
@@ -64,11 +67,20 @@
private String getAccount() {
try {
- return GoogleLoginServiceBlockingHelper.getAccount(mTargetContext, false);
- } catch (GoogleLoginServiceNotFoundException e) {
- Log.e(this.getClass().getName(), "Could not find Google login service");
- return null;
+ String[] features = new String[]{GoogleLoginServiceConstants.FEATURE_HOSTED_OR_GOOGLE};
+ Account[] accounts = AccountManager.get(mTargetContext).getAccountsByTypeAndFeatures(
+ GoogleLoginServiceConstants.ACCOUNT_TYPE, features, null, null).getResult();
+ if (accounts.length > 0) {
+ return accounts[0].name;
+ }
+ } catch (OperationCanceledException e) {
+ // handle below
+ } catch (IOException e) {
+ // handle below
+ } catch (AuthenticatorException e) {
+ // handle below
}
+ return null;
}
/**