aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTa-wei Yen <twyen@google.com>2017-11-30 14:46:15 -0800
committerTa-wei Yen <twyen@google.com>2017-11-30 14:54:46 -0800
commit78ce51eacb3c0da4ea8fe88541d040a85b1bb9e6 (patch)
tree94c34239184320084ab64edbac8da7077636facb
parent29dc99f9e89e49c6e7e9ecc2cdd935ab719d6cb5 (diff)
downloadContactsProvider-78ce51eacb3c0da4ea8fe88541d040a85b1bb9e6.tar.gz
Implement DIRTY_RETAIN constant
Previously the DIRTY flag can only be automatically or explicitly set. There are no option to express "This operation does not change the DIRTY flag". This causes issue when the voicemail source is downloading changes from the server instead of uploading and would clobber the flag. After this CL, if DIRTY is updated with DIRTY_RETAIN, the flag will not be updated for the operation. Change-Id: I23a23a11f7d2177d10b65bbc33875b7eb838f7c1 Fixes: 64371667 Test: CtsProviderTestCases#VoicemailContractTest
-rw-r--r--src/com/android/providers/contacts/DbModifierWithNotification.java62
-rw-r--r--tests/src/com/android/providers/contacts/VoicemailProviderTest.java56
2 files changed, 90 insertions, 28 deletions
diff --git a/src/com/android/providers/contacts/DbModifierWithNotification.java b/src/com/android/providers/contacts/DbModifierWithNotification.java
index 36865fa1..0babe1b9 100644
--- a/src/com/android/providers/contacts/DbModifierWithNotification.java
+++ b/src/com/android/providers/contacts/DbModifierWithNotification.java
@@ -178,28 +178,21 @@ public class DbModifierWithNotification implements DatabaseModifier {
updateLastModified(table, whereClause, whereArgs);
}
if (isVoicemail) {
- // If a calling package is modifying its own entries, it means that the change came
- // from the server and thus is synced or "clean". Otherwise, it means that a local
- // change is being made to the database, so the entries should be marked as "dirty"
- // so that the corresponding sync adapter knows they need to be synced.
- int isDirty;
- Integer callerSetDirty = values.getAsInteger(Voicemails.DIRTY);
- if (callerSetDirty != null) {
- // Respect the calling package if it sets the dirty flag
- isDirty = callerSetDirty == 0 ? 0 : 1;
- } else {
- isDirty = isSelfModifyingOrInternal(packagesModified) ? 0 : 1;
- }
- values.put(VoicemailContract.Voicemails.DIRTY, isDirty);
-
- if (isDirty == 0 && values.containsKey(Calls.IS_READ) && getAsBoolean(values,
- Calls.IS_READ)) {
- // If the server has set the IS_READ, it should also unset the new flag
- if (!values.containsKey(Calls.NEW)) {
- values.put(Calls.NEW, 0);
- hasMarkedRead = true;
+ if (updateDirtyFlag(values, packagesModified)) {
+ if (values.containsKey(Calls.IS_READ)
+ && getAsBoolean(values,
+ Calls.IS_READ)) {
+ // If the server has set the IS_READ, it should also unset the new flag
+ if (!values.containsKey(Calls.NEW)) {
+ values.put(Calls.NEW, 0);
+ hasMarkedRead = true;
+ }
}
}
+ // updateDirtyFlag might remove the value and leave values empty.
+ if(values.isEmpty()){
+ return 0;
+ }
}
}
@@ -221,6 +214,29 @@ public class DbModifierWithNotification implements DatabaseModifier {
return count;
}
+ private boolean updateDirtyFlag(ContentValues values, Set<String> packagesModified) {
+ // If a calling package is modifying its own entries, it means that the change came
+ // from the server and thus is synced or "clean". Otherwise, it means that a local
+ // change is being made to the database, so the entries should be marked as "dirty"
+ // so that the corresponding sync adapter knows they need to be synced.
+ int isDirty;
+ Integer callerSetDirty = values.getAsInteger(Voicemails.DIRTY);
+ if (callerSetDirty != null) {
+ // Respect the calling package if it sets the dirty flag
+ if (callerSetDirty == Voicemails.DIRTY_RETAIN) {
+ values.remove(Voicemails.DIRTY);
+ return false;
+ } else {
+ isDirty = callerSetDirty == 0 ? 0 : 1;
+ }
+ } else {
+ isDirty = isSelfModifyingOrInternal(packagesModified) ? 0 : 1;
+ }
+
+ values.put(Voicemails.DIRTY, isDirty);
+ return isDirty == 0;
+ }
+
private void updateLastModified(String table, String whereClause, String[] whereArgs) {
ContentValues values = new ContentValues();
values.put(Calls.LAST_MODIFIED, getTimeMillis());
@@ -317,7 +333,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
/**
* @param packagesModified source packages that inserted the voicemail that is being modified
* @return {@code true} if the caller is modifying its own voicemail, or this is an internal
- * transaction, {@code false} otherwise.
+ * transaction, {@code false} otherwise.
*/
private boolean isSelfModifyingOrInternal(Set<String> packagesModified) {
final Collection<String> callingPackages = getCallingPackages();
@@ -328,7 +344,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
// but allows us to mock the results for testing.
return packagesModified.size() == 1 && (callingPackages.contains(
Iterables.getOnlyElement(packagesModified))
- || callingPackages.contains(mContext.getPackageName()));
+ || callingPackages.contains(mContext.getPackageName()));
}
/**
@@ -370,7 +386,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
}
@VisibleForTesting
- static void setVoicemailNotifierForTest(VoicemailNotifier notifier){
+ static void setVoicemailNotifierForTest(VoicemailNotifier notifier) {
sVoicemailNotifierForTest = notifier;
}
}
diff --git a/tests/src/com/android/providers/contacts/VoicemailProviderTest.java b/tests/src/com/android/providers/contacts/VoicemailProviderTest.java
index 1cd6646d..1bf0d847 100644
--- a/tests/src/com/android/providers/contacts/VoicemailProviderTest.java
+++ b/tests/src/com/android/providers/contacts/VoicemailProviderTest.java
@@ -16,6 +16,9 @@
package com.android.providers.contacts;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
@@ -31,7 +34,6 @@ import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.common.io.MoreCloseables;
-import org.mockito.Mockito;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -39,9 +41,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.mock;
+import org.mockito.Mockito;
/**
* Unit tests for {@link VoicemailContentProvider}.
@@ -202,7 +202,7 @@ public class VoicemailProviderTest extends BaseVoicemailProviderTest {
public void testUpdateOwnPackageVoicemail_RemovesDirtyStatus() {
ContentValues values = getTestVoicemailValues();
values.put(Voicemails.DIRTY, "1");
- final Uri uri = mResolver.insert(voicemailUri(), getTestVoicemailValues());
+ final Uri uri = mResolver.insert(voicemailUri(), values);
mResolver.update(uri, new ContentValues(), null, null);
// At this point, the voicemail should be set back to not dirty.
@@ -211,6 +211,52 @@ public class VoicemailProviderTest extends BaseVoicemailProviderTest {
assertStoredValues(uri, newValues);
}
+ public void testUpdateOwnPackageVoicemail_retainDirtyStatus_dirty() {
+ ContentValues values = getTestVoicemailValues();
+ values.put(Voicemails.DIRTY, "1");
+ final Uri uri = mResolver.insert(voicemailUri(), values);
+
+ ContentValues retainDirty = new ContentValues();
+ retainDirty.put(Voicemails.TRANSCRIPTION, "foo");
+ retainDirty.put(Voicemails.DIRTY, Voicemails.DIRTY_RETAIN);
+
+ mResolver.update(uri, retainDirty, null, null);
+ ContentValues newValues = getTestVoicemailValues();
+ newValues.put(Voicemails.DIRTY, "1");
+ newValues.put(Voicemails.TRANSCRIPTION, "foo");
+ assertStoredValues(uri, newValues);
+ }
+
+ public void testUpdateOwnPackageVoicemail_retainDirtyStatus_notDirty() {
+ ContentValues values = getTestVoicemailValues();
+ values.put(Voicemails.DIRTY, "0");
+ final Uri uri = mResolver.insert(voicemailUri(), values);
+
+ ContentValues retainDirty = new ContentValues();
+ retainDirty.put(Voicemails.TRANSCRIPTION, "foo");
+ retainDirty.put(Voicemails.DIRTY, Voicemails.DIRTY_RETAIN);
+
+ mResolver.update(uri, retainDirty, null, null);
+ ContentValues newValues = getTestVoicemailValues();
+ newValues.put(Voicemails.DIRTY, "0");
+ newValues.put(Voicemails.TRANSCRIPTION, "foo");
+ assertStoredValues(uri, newValues);
+ }
+
+ public void testUpdateOwnPackageVoicemail_retainDirtyStatus_noOtherValues() {
+ ContentValues values = getTestVoicemailValues();
+ values.put(Voicemails.DIRTY, "1");
+ final Uri uri = mResolver.insert(voicemailUri(), values);
+
+ ContentValues retainDirty = new ContentValues();
+ retainDirty.put(Voicemails.DIRTY, Voicemails.DIRTY_RETAIN);
+
+ mResolver.update(uri, retainDirty, null, null);
+ ContentValues newValues = getTestVoicemailValues();
+ newValues.put(Voicemails.DIRTY, "1");
+ assertStoredValues(uri, newValues);
+ }
+
public void testDeleteOwnPackageVoicemail_DeletesRow() {
setUpForFullPermission();
final Uri ownVoicemail = insertVoicemail();