aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorke Lee <yorkelee@google.com>2013-08-05 15:28:21 -0700
committerYorke Lee <yorkelee@google.com>2013-08-05 17:07:00 -0700
commit45b023e89d87b66e44c1b79c6e1444ec9db70a82 (patch)
tree068a5215c6911e9133bbe7789b3a57799fd8729c
parenta89aa7533a14b143b55bf4a29d284152ab9278a5 (diff)
downloadContactsProvider-45b023e89d87b66e44c1b79c6e1444ec9db70a82.tar.gz
Handle DEMOTE and UNDEMOTE in CP2
* If a contact is UNDEMOTED, if it was previously DEMOTED, it will become UNPINNED. Otherwise, it will remain unchanged. * When two raw contacts are aggregated, the parent contact should inherit the lower pinned position of the two, not including negative integers. Change-Id: I74f41dfa327b8e5a79688b1e99eafbef7d9d58a0
-rw-r--r--src/com/android/providers/contacts/ContactsProvider2.java35
-rw-r--r--src/com/android/providers/contacts/aggregation/ContactAggregator.java10
-rw-r--r--tests/src/com/android/providers/contacts/ContactsProvider2Test.java120
3 files changed, 146 insertions, 19 deletions
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 68cb1835..5cdbb198 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -504,6 +504,20 @@ public class ContactsProvider2 extends AbstractContactsProvider
" SET " + RawContacts.VERSION + " = " + RawContacts.VERSION + " + 1" +
" WHERE " + RawContacts._ID + " IN (";
+ /** Sql for undemoting a demoted contact **/
+ private static final String UNDEMOTE_CONTACT =
+ "UPDATE " + Tables.CONTACTS +
+ " SET " + Contacts.PINNED + " = " + PinnedPositions.UNPINNED +
+ " WHERE " + Contacts._ID + " = ?1 AND " + Contacts.PINNED + " <= " +
+ PinnedPositions.DEMOTED;
+
+ /** Sql for undemoting a demoted raw contact **/
+ private static final String UNDEMOTE_RAW_CONTACT =
+ "UPDATE " + Tables.RAW_CONTACTS +
+ " SET " + RawContacts.PINNED + " = " + PinnedPositions.UNPINNED +
+ " WHERE " + RawContacts.CONTACT_ID + " = ?1 AND " + Contacts.PINNED + " <= " +
+ PinnedPositions.DEMOTED;
+
// Current contacts - those contacted within the last 3 days (in seconds)
private static final long LAST_TIME_USED_CURRENT_SEC = 3 * 24 * 60 * 60;
@@ -8551,14 +8565,22 @@ public class ContactsProvider2 extends AbstractContactsProvider
+ id);
}
+ // If contact is to be undemoted, go through a separate un-demotion process
+ final String undemote = values.getAsString(id);
+ if (PinnedPositions.UNDEMOTE.equals(undemote)) {
+ undemoteContact(db, contactId);
+ continue;
+ }
+
final Integer pinnedPosition = values.getAsInteger(id);
- if (pinnedPosition == null || pinnedPosition < 0) {
- throw new IllegalArgumentException("Pinned position must be a positive integer.");
+ if (pinnedPosition == null) {
+ throw new IllegalArgumentException("Pinned position must be an integer.");
}
args[0] = String.valueOf(contactId);
args[1] = String.valueOf(pinnedPosition);
if (forceStarWhenPinning) {
- args[2] = (pinnedPosition == PinnedPositions.UNPINNED ? "0" : "1");
+ args[2] = (pinnedPosition == PinnedPositions.UNPINNED ||
+ pinnedPosition == PinnedPositions.DEMOTED ? "0" : "1");
}
db.execSQL(contactSQL, args);
@@ -8567,6 +8589,13 @@ public class ContactsProvider2 extends AbstractContactsProvider
return count;
}
+ private void undemoteContact(SQLiteDatabase db, long id) {
+ final String[] arg = new String[1];
+ arg[0] = String.valueOf(id);
+ db.execSQL(UNDEMOTE_CONTACT, arg);
+ db.execSQL(UNDEMOTE_RAW_CONTACT, arg);
+ }
+
private boolean handleDataUsageFeedback(Uri uri) {
final long currentTimeMillis = Clock.getInstance().currentTimeMillis();
final String usageType = uri.getQueryParameter(DataUsageFeedback.USAGE_TYPE);
diff --git a/src/com/android/providers/contacts/aggregation/ContactAggregator.java b/src/com/android/providers/contacts/aggregation/ContactAggregator.java
index db88c10b..88369f9f 100644
--- a/src/com/android/providers/contacts/aggregation/ContactAggregator.java
+++ b/src/com/android/providers/contacts/aggregation/ContactAggregator.java
@@ -339,7 +339,8 @@ public class ContactAggregator {
mPinnedUpdate = db.compileStatement("UPDATE " + Tables.CONTACTS + " SET "
+ Contacts.PINNED + "=(SELECT MIN(" + RawContacts.PINNED + ") FROM "
+ Tables.RAW_CONTACTS + " WHERE " + RawContacts.CONTACT_ID + "="
- + ContactsColumns.CONCRETE_ID + ") WHERE " + Contacts._ID + "=?");
+ + ContactsColumns.CONCRETE_ID + " AND " + RawContacts.PINNED + ">"
+ + PinnedPositions.DEMOTED + ") WHERE " + Contacts._ID + "=?");
mContactIdAndMarkAggregatedUpdate = db.compileStatement(
"UPDATE " + Tables.RAW_CONTACTS +
@@ -1914,9 +1915,11 @@ public class ContactAggregator {
}
// contactPinned should be the lowest value of its constituent raw contacts,
- // excluding 0
+ // excluding negative integers
final int rawContactPinned = c.getInt(RawContactsQuery.PINNED);
- contactPinned = Math.min(contactPinned, rawContactPinned);
+ if (rawContactPinned >= 0) {
+ contactPinned = Math.min(contactPinned, rawContactPinned);
+ }
appendLookupKey(
lookupKey,
@@ -2366,7 +2369,6 @@ public class ContactAggregator {
if (contactId == 0) {
return;
}
-
mPinnedUpdate.bindLong(1, contactId);
mPinnedUpdate.execute();
}
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
index 3293a5b2..f9b13a58 100644
--- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -7885,19 +7885,20 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test {
cv(Contacts._ID, i4.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED)
);
- // negative number
- final ContentValues values = cv(i1.mContactId, 1, i3.mContactId, 3, i4.mContactId, -2);
+ // Unsupported string
+ final ContentValues values = cv(i1.mContactId, 1, i3.mContactId, 3, i4.mContactId,
+ "undemotemeplease!");
try {
mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values, null, null);
- fail("Pinned position must be a distinct(unrepeated) positive integer.");
+ fail("Pinned position must be an integer.");
} catch (IllegalArgumentException expected) {
}
- // non-integer
- final ContentValues values3 = cv(i1.mContactId, "1.1");
+ // Float
+ final ContentValues values2 = cv(i1.mContactId, "1.1");
try {
- mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values, null, null);
- fail("Pinned position must be a distinct(unrepeated) positive integer.");
+ mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values2, null, null);
+ fail("Pinned position must be an integer");
} catch (IllegalArgumentException expected) {
}
@@ -7923,8 +7924,11 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test {
final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
+ final DatabaseAsserts.ContactIdPair i5 = DatabaseAsserts.assertAndCreateContact(mResolver);
+ final DatabaseAsserts.ContactIdPair i6 = DatabaseAsserts.assertAndCreateContact(mResolver);
- final ContentValues values = cv(i1.mContactId, 1, i2.mContactId, 2, i3.mContactId, 3);
+ final ContentValues values = cv(i1.mContactId, 1, i2.mContactId, 2, i3.mContactId, 3,
+ i5.mContactId, 5, i6.mContactId, 6);
mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
.appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
values, null, null);
@@ -7937,7 +7941,9 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test {
assertStoredValuesWithProjection(Contacts.CONTENT_URI,
cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1),
cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
- cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3)
+ cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3),
+ cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 5),
+ cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
);
assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
@@ -7948,7 +7954,11 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test {
cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
RawContacts.STARRED, 1),
cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
- RawContacts.STARRED, 0)
+ RawContacts.STARRED, 0),
+ cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5,
+ RawContacts.STARRED, 1),
+ cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6,
+ RawContacts.STARRED, 1)
);
// aggregate raw contact 2 and 3 together.
@@ -7959,14 +7969,19 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test {
// pinned position
assertStoredValuesWithProjection(Contacts.CONTENT_URI,
cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1),
- cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2)
+ cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
+ cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 5),
+ cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
);
assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1),
cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2),
cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3),
- cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED)
+ cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED,
+ PinnedPositions.UNPINNED),
+ cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5),
+ cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6)
);
// split the aggregated raw contacts
@@ -7982,6 +7997,87 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test {
cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
RawContacts.STARRED, 1),
cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
+ RawContacts.STARRED, 0),
+ cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5,
+ RawContacts.STARRED, 1),
+ cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6,
+ RawContacts.STARRED, 1)
+ );
+
+
+
+ // now demote contact 5
+ final ContentValues cv = cv(i5.mContactId, PinnedPositions.DEMOTED);
+ mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().build(),
+ cv, null, null);
+
+ // Get new contact Ids for contacts composing of raw contacts 1 and 4 because they have
+ // changed.
+ final long cId1 = RawContactUtil.queryContactIdByRawContactId(mResolver, i1.mRawContactId);
+ final long cId4 = RawContactUtil.queryContactIdByRawContactId(mResolver, i4.mRawContactId);
+
+ assertStoredValuesWithProjection(Contacts.CONTENT_URI,
+ cv(Contacts._ID, cId1, Contacts.PINNED, PinnedPositions.UNPINNED),
+ cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
+ cv(Contacts._ID, cId4, Contacts.PINNED, PinnedPositions.UNPINNED),
+ cv(Contacts._ID, i5.mContactId, Contacts.PINNED, PinnedPositions.DEMOTED),
+ cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
+ );
+
+ // aggregate contacts 5 and 6 together
+ setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i5.mRawContactId,
+ i6.mRawContactId);
+
+ // The resulting contact should have a pinned value of 6
+ assertStoredValuesWithProjection(Contacts.CONTENT_URI,
+ cv(Contacts._ID, cId1, Contacts.PINNED, PinnedPositions.UNPINNED),
+ cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
+ cv(Contacts._ID, cId4, Contacts.PINNED, PinnedPositions.UNPINNED),
+ cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 6)
+ );
+ }
+
+ public void testPinnedPositionsAfterDemoteAndUndemote() {
+ final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
+ final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+ final ContentValues values = cv(i1.mContactId, 0, i2.mContactId, PinnedPositions.DEMOTED);
+
+ // Pin contact 1 and demote contact 2
+ mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().
+ appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").
+ build(), values, null, null);
+
+ assertStoredValuesWithProjection(Contacts.CONTENT_URI,
+ cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 0, Contacts.STARRED, 1),
+ cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.DEMOTED,
+ Contacts.STARRED, 0)
+ );
+
+ assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
+ cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 0,
+ RawContacts.STARRED, 1),
+ cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.DEMOTED,
+ RawContacts.STARRED, 0)
+ );
+
+ // Now undemote both contacts
+ final ContentValues values2 = cv(i1.mContactId, PinnedPositions.UNDEMOTE, i2.mContactId,
+ PinnedPositions.UNDEMOTE);
+ mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().
+ build(), values2, null, null);
+
+ // Contact 1 remains pinned at 0, while contact 2 becomes unpinned
+ assertStoredValuesWithProjection(Contacts.CONTENT_URI,
+ cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 0, Contacts.STARRED, 1),
+ cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED,
+ Contacts.STARRED, 0)
+ );
+
+ assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
+ cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 0,
+ RawContacts.STARRED, 1),
+ cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
RawContacts.STARRED, 0)
);
}