Merge "Format phone numbers in Recent card call logs" into ub-contactsdialer-g-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index becab16..0f9f16e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -300,19 +300,19 @@
<string name="contactUnlinkedToast">Contacts unlinked</string>
<!-- Toast displayed when saving a contact failed. [CHAR LIMIT=NONE] -->
- <string name="contactSavedErrorToast">Couldn\'t save contact changes.</string>
+ <string name="contactSavedErrorToast">Couldn\'t save contact changes</string>
<!-- Toast displayed when unlinking a contact failed. [CHAR LIMIT=NONE] -->
- <string name="contactUnlinkErrorToast">Couldn\'t unlink contact.</string>
+ <string name="contactUnlinkErrorToast">Couldn\'t unlink contact</string>
<!-- Toast displayed when linking a contact failed. [CHAR LIMIT=NONE] -->
- <string name="contactJoinErrorToast">Couldn\'t link contact.</string>
+ <string name="contactJoinErrorToast">Couldn\'t link contact</string>
<!-- Generic error default clause displayed when saving a contact failed. [CHAR LIMIT=NONE] -->
- <string name="contactGenericErrorToast">Error saving contact.</string>
+ <string name="contactGenericErrorToast">Error saving contact</string>
<!-- Toast displayed when saving a contact photo failed. [CHAR LIMIT=NONE] -->
- <string name="contactPhotoSavedErrorToast">Couldn\'t save contact photo changes.</string>
+ <string name="contactPhotoSavedErrorToast">Couldn\'t save contact photo changes</string>
<!-- Toast displayed when something goes wrong while loading a label. [CHAR LIMIT=70] -->
<string name="groupLoadErrorToast">Failed to load label</string>
@@ -339,7 +339,7 @@
<string name="groupMembersAddedToast">Added to label</string>
<!-- Toast displayed when saving a label failed [CHAR LIMIT=70] -->
- <string name="groupSavedErrorToast">Couldn\'t save label changes.</string>
+ <string name="groupSavedErrorToast">Couldn\'t save label changes</string>
<!-- Message displayed when creating a group with the same name as an existing group -->
<string name="groupExistsErrorMessage">That label already exists</string>
diff --git a/src-bind/com/android/contactsbind/FeatureHighlightHelper.java b/src-bind/com/android/contactsbind/FeatureHighlightHelper.java
index c246141..be1833d 100644
--- a/src-bind/com/android/contactsbind/FeatureHighlightHelper.java
+++ b/src-bind/com/android/contactsbind/FeatureHighlightHelper.java
@@ -26,4 +26,8 @@
public static boolean showHamburgerFeatureHighlight(final FragmentActivity activity) {
return false;
}
+
+ public static boolean tryRemoveHighlight(final FragmentActivity activity) {
+ return false;
+ }
}
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index b34f384..c514a45 100755
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -1359,17 +1359,26 @@
return;
}
- if (receiver != null) {
- final Bundle result = new Bundle();
- result.putSerializable(EXTRA_RAW_CONTACT_IDS, separatedRawContactIds);
- result.putString(EXTRA_DISPLAY_NAME, queryNameOfLinkedContacts(contactIds));
- receiver.send(CONTACTS_LINKED, result);
+
+ final String name = queryNameOfLinkedContacts(contactIds);
+ if (name != null) {
+ if (receiver != null) {
+ final Bundle result = new Bundle();
+ result.putSerializable(EXTRA_RAW_CONTACT_IDS, separatedRawContactIds);
+ result.putString(EXTRA_DISPLAY_NAME, name);
+ receiver.send(CONTACTS_LINKED, result);
+ } else {
+ showToast(R.string.contactsJoinedMessage);
+ }
} else {
- showToast(R.string.contactsJoinedMessage);
+ if (receiver != null) {
+ receiver.send(CP2_ERROR, new Bundle());
+ }
+ showToast(R.string.contactJoinErrorToast);
}
}
- // Get the display name of the top-level contact after the contacts have been linked.
+ /** Get the display name of the top-level contact after the contacts have been linked. */
private String queryNameOfLinkedContacts(long[] contactIds) {
final StringBuilder whereBuilder = new StringBuilder(Contacts._ID).append(" IN (");
final String[] whereArgs = new String[contactIds.length];
@@ -1379,23 +1388,41 @@
}
whereBuilder.deleteCharAt(whereBuilder.length() - 1).append(')');
final Cursor cursor = getContentResolver().query(Contacts.CONTENT_URI,
- new String[]{Contacts.DISPLAY_NAME}, whereBuilder.toString(), whereArgs, null);
+ new String[]{Contacts._ID, Contacts.DISPLAY_NAME},
+ whereBuilder.toString(), whereArgs, null);
+
+ String name = null;
+ long contactId = 0;
try {
if (cursor.moveToFirst()) {
- return cursor.getString(0);
+ contactId = cursor.getLong(0);
+ name = cursor.getString(1);
}
- return null;
+ while(cursor.moveToNext()) {
+ if (cursor.getLong(0) != contactId) {
+ return null;
+ }
+ }
+ return name == null ? "" : name;
} finally {
- cursor.close();
+ if (cursor != null) {
+ cursor.close();
+ }
}
}
-
/** Returns true if the batch was successfully applied and false otherwise. */
private boolean applyOperations(ContentResolver resolver,
ArrayList<ContentProviderOperation> operations) {
try {
- resolver.applyBatch(ContactsContract.AUTHORITY, operations);
+ final ContentProviderResult[] result =
+ resolver.applyBatch(ContactsContract.AUTHORITY, operations);
+ for (int i = 0; i < result.length; ++i) {
+ // if no rows were modified in the operation then we count it as fail.
+ if (result[i].count < 0) {
+ throw new OperationApplicationException();
+ }
+ }
return true;
} catch (RemoteException | OperationApplicationException e) {
Log.e(TAG, "Failed to apply aggregation exception batch", e);
@@ -1460,19 +1487,12 @@
operations.add(builder.build());
}
- boolean success = false;
// Apply all aggregation exceptions as one batch
- try {
- resolver.applyBatch(ContactsContract.AUTHORITY, operations);
- showToast(R.string.contactsJoinedMessage);
- success = true;
- } catch (RemoteException | OperationApplicationException e) {
- Log.e(TAG, "Failed to apply aggregation exception batch", e);
- showToast(R.string.contactSavedErrorToast);
- }
+ final boolean success = applyOperations(resolver, operations);
+ final String name = queryNameOfLinkedContacts(new long[] {contactId1, contactId2});
Intent callbackIntent = intent.getParcelableExtra(EXTRA_CALLBACK_INTENT);
- if (success) {
+ if (success && name != null) {
Uri uri = RawContacts.getContactLookupUri(resolver,
ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactIds[0]));
callbackIntent.setData(uri);
diff --git a/src/com/android/contacts/activities/GroupMembersActivity.java b/src/com/android/contacts/activities/GroupMembersActivity.java
index e887cb9..c32842a 100644
--- a/src/com/android/contacts/activities/GroupMembersActivity.java
+++ b/src/com/android/contacts/activities/GroupMembersActivity.java
@@ -88,15 +88,17 @@
private final long mGroupId;
private final String mAccountName;
private final String mAccountType;
+ private final String mDataSet;
private UpdateGroupMembersAsyncTask(int type, Context context, long[] contactIds,
- long groupId, String accountName, String accountType) {
+ long groupId, String accountName, String accountType, String dataSet) {
mContext = context;
mType = type;
mContactIds = contactIds;
mGroupId = groupId;
mAccountName = accountName;
mAccountType = accountType;
+ mDataSet = dataSet;
}
@Override
@@ -127,10 +129,16 @@
// ContactSaveService will log a warning if the raw contact is already a member and keep
// going but it is not ideal, we could also prune raw contacts that are already members.
private long[] getRawContactIds() {
- final Uri rawContactUri = RawContacts.CONTENT_URI.buildUpon()
- .appendQueryParameter(RawContacts.ACCOUNT_NAME, mAccountName)
- .appendQueryParameter(RawContacts.ACCOUNT_TYPE, mAccountType)
- .build();
+ final Uri.Builder builder = RawContacts.CONTENT_URI.buildUpon();
+ // null account names are not valid, see ContactsProvider2#appendAccountFromParameter
+ if (mAccountName != null) {
+ builder.appendQueryParameter(RawContacts.ACCOUNT_NAME, mAccountName);
+ builder.appendQueryParameter(RawContacts.ACCOUNT_TYPE, mAccountType);
+ }
+ if (mDataSet != null) {
+ builder.appendQueryParameter(RawContacts.DATA_SET, mDataSet);
+ }
+ final Uri rawContactUri = builder.build();
final String[] projection = new String[]{RawContacts._ID};
final StringBuilder selection = new StringBuilder();
final String[] selectionArgs = new String[mContactIds.length];
@@ -443,7 +451,7 @@
final long[] contactIds = mMembersFragment.getAdapter().getSelectedContactIdsArray();
new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE,
this, contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName,
- mGroupMetaData.accountType).execute();
+ mGroupMetaData.accountType, mGroupMetaData.dataSet).execute();
mActionBarAdapter.setSelectionMode(false);
}
@@ -489,7 +497,7 @@
}
new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_ADD,
this, contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName,
- mGroupMetaData.accountType).execute();
+ mGroupMetaData.accountType, mGroupMetaData.dataSet).execute();
}
}
@@ -610,6 +618,6 @@
contactIds[0] = contactId;
new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE,
this, contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName,
- mGroupMetaData.accountType).execute();
+ mGroupMetaData.accountType, mGroupMetaData.dataSet).execute();
}
}
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index d100d45..166222f 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -1378,6 +1378,8 @@
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
+ } else if (FeatureHighlightHelper.tryRemoveHighlight(this)) {
+ return;
} else if (mActionBarAdapter.isSelectionMode()) {
mActionBarAdapter.setSelectionMode(false);
mAllFragment.displayCheckBoxes(false);
diff --git a/src/com/android/contacts/common/list/ContactListFilter.java b/src/com/android/contacts/common/list/ContactListFilter.java
index 81ee5c9..8e29308 100644
--- a/src/com/android/contacts/common/list/ContactListFilter.java
+++ b/src/com/android/contacts/common/list/ContactListFilter.java
@@ -330,9 +330,12 @@
throw new IllegalStateException(
"filterType must be FILTER_TYPE_ACCOUNT or FILER_TYPE_GROUP_MEMBERS");
}
- uriBuilder.appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName);
- uriBuilder.appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType);
- if (!TextUtils.isEmpty(dataSet)) {
+ // null account names are not valid, see ContactsProvider2#appendAccountFromParameter
+ if (accountName != null) {
+ uriBuilder.appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName);
+ uriBuilder.appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType);
+ }
+ if (dataSet != null) {
uriBuilder.appendQueryParameter(RawContacts.DATA_SET, dataSet);
}
return uriBuilder;
diff --git a/src/com/android/contacts/common/model/DeviceLocalAccountLocator.java b/src/com/android/contacts/common/model/DeviceLocalAccountLocator.java
index 0efadc4..8c45c40 100644
--- a/src/com/android/contacts/common/model/DeviceLocalAccountLocator.java
+++ b/src/com/android/contacts/common/model/DeviceLocalAccountLocator.java
@@ -78,16 +78,8 @@
// Many device accounts have default groups associated with them.
addAccountsFromQuery(ContactsContract.Groups.CONTENT_URI, localAccounts);
-
addAccountsFromQuery(ContactsContract.Settings.CONTENT_URI, localAccounts);
-
- if (localAccounts.isEmpty()) {
- // It's probably safe to assume that if one of the earlier queries found a "device"
- // account then this query isn't going to find any different device accounts.
- // We skip this query because it probably is kind of expensive (relative to the other
- // queries).
- addAccountsFromQuery(ContactsContract.RawContacts.CONTENT_URI, localAccounts);
- }
+ addAccountsFromQuery(ContactsContract.RawContacts.CONTENT_URI, localAccounts);
return new ArrayList<>(localAccounts);
}
diff --git a/tests/src/com/android/contacts/common/model/DeviceLocalAccountLocatorTests.java b/tests/src/com/android/contacts/common/model/DeviceLocalAccountLocatorTests.java
index f1a2714..e8c4e2f 100644
--- a/tests/src/com/android/contacts/common/model/DeviceLocalAccountLocatorTests.java
+++ b/tests/src/com/android/contacts/common/model/DeviceLocalAccountLocatorTests.java
@@ -140,24 +140,6 @@
assertEquals(2, sut.getDeviceLocalAccounts().size());
}
- public void test_getDeviceLocalAccounts_onlyQueriesRawContactsIfNecessary() {
- final DeviceLocalAccountTypeFactory stubFactory = new FakeDeviceAccountTypeFactory()
- .withDeviceTypes(null, "vnd.sec.contact.phone")
- .withSimTypes("vnd.sec.contact.sim");
- final FakeContactsProvider contactsProvider = new FakeContactsProvider()
- .withQueryResult(ContactsContract.Groups.CONTENT_URI, queryResult(
- "phone_account", "vnd.sec.contact.phone",
- "sim_account", "vnd.sec.contact.sim"
- ));
- final DeviceLocalAccountLocator sut = new DeviceLocalAccountLocator(
- createContentResolverWithProvider(contactsProvider), stubFactory,
- Collections.<AccountWithDataSet>emptyList());
-
- sut.getDeviceLocalAccounts();
-
- assertEquals(0, contactsProvider.getQueryCountFor(RawContacts.CONTENT_URI));
- }
-
private DeviceLocalAccountLocator createWithQueryResult(
Cursor cursor) {
final DeviceLocalAccountLocator locator = new DeviceLocalAccountLocator(
@@ -194,7 +176,6 @@
private static class FakeContactsProvider extends MockContentProvider {
public Cursor mNextQueryResult;
public Map<Uri, Cursor> mNextResultMapping = new HashMap<>();
- public Map<Uri, Integer> mQueryCountMapping = new HashMap<>();
public FakeContactsProvider() {}
@@ -214,17 +195,10 @@
return query(uri, projection, selection, selectionArgs, sortOrder, null);
}
- public int getQueryCountFor(Uri uri) {
- ensureCountInitialized(uri);
- return mQueryCountMapping.get(uri);
- }
-
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder, CancellationSignal cancellationSignal) {
- incrementQueryCount(uri);
-
final Cursor result = mNextResultMapping.get(uri);
if (result == null) {
return mNextQueryResult;
@@ -232,17 +206,5 @@
return result;
}
}
-
- private void ensureCountInitialized(Uri uri) {
- if (!mQueryCountMapping.containsKey(uri)) {
- mQueryCountMapping.put(uri, 0);
- }
- }
-
- private void incrementQueryCount(Uri uri) {
- ensureCountInitialized(uri);
- final int count = mQueryCountMapping.get(uri);
- mQueryCountMapping.put(uri, count + 1);
- }
}
}