aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTa-wei Yen <twyen@google.com>2017-01-17 19:28:13 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-01-17 19:28:13 +0000
commit51b15e88e873d21f1683db021b0ee72059c02126 (patch)
tree0e01f33efece35981b2b67c38b9ab449d4a2977e /src
parenta4ae2c38359a9732138a13569392a431549735cd (diff)
parent79733da1e995680e27393c68755cf4e0762805cb (diff)
downloadContactsProvider-51b15e88e873d21f1683db021b0ee72059c02126.tar.gz
Prevent LAST_MODIFIED from changing after deletion am: 687bef960a
am: 79733da1e9 Change-Id: I6678fcd89d52a1cd46ace7b6d97b2e24d4b06c96
Diffstat (limited to 'src')
-rw-r--r--src/com/android/providers/contacts/CallLogProvider.java42
-rw-r--r--src/com/android/providers/contacts/DbModifierWithNotification.java33
2 files changed, 68 insertions, 7 deletions
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java
index e0cb8360..c1a50b26 100644
--- a/src/com/android/providers/contacts/CallLogProvider.java
+++ b/src/com/android/providers/contacts/CallLogProvider.java
@@ -46,11 +46,11 @@ import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.providers.contacts.CallLogDatabaseHelper.DbProperties;
import com.android.providers.contacts.CallLogDatabaseHelper.Tables;
import com.android.providers.contacts.util.SelectionBuilder;
import com.android.providers.contacts.util.UserUtils;
-import com.google.common.annotations.VisibleForTesting;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -153,6 +153,19 @@ public class CallLogProvider extends ContentProvider {
sCallsProjectionMap.put(Calls.LAST_MODIFIED, Calls.LAST_MODIFIED);
}
+ private static final String ALLOWED_PACKAGE_FOR_TESTING = "com.android.providers.contacts";
+
+ @VisibleForTesting
+ static final String PARAM_KEY_QUERY_FOR_TESTING = "query_for_testing";
+
+ /**
+ * A long to override the clock used for timestamps, or "null" to reset to the system clock.
+ */
+ @VisibleForTesting
+ static final String PARAM_KEY_SET_TIME_FOR_TESTING = "set_time_for_testing";
+
+ private static Long sTimeForTestMillis;
+
private HandlerThread mBackgroundThread;
private Handler mBackgroundHandler;
private volatile CountDownLatch mReadAccessLatch;
@@ -223,6 +236,9 @@ public class CallLogProvider extends ContentProvider {
" order=[" + sortOrder + "] CPID=" + Binder.getCallingPid() +
" User=" + UserUtils.getCurrentUserHandle(getContext()));
}
+
+ queryForTesting(uri);
+
waitForAccess(mReadAccessLatch);
final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(Tables.CALLS);
@@ -278,6 +294,30 @@ public class CallLogProvider extends ContentProvider {
return c;
}
+ private void queryForTesting(Uri uri) {
+ if (!uri.getBooleanQueryParameter(PARAM_KEY_QUERY_FOR_TESTING, false)) {
+ return;
+ }
+ if (!getCallingPackage().equals(ALLOWED_PACKAGE_FOR_TESTING)) {
+ throw new IllegalArgumentException("query_for_testing set from foreign package "
+ + getCallingPackage());
+ }
+
+ String timeString = uri.getQueryParameter(PARAM_KEY_SET_TIME_FOR_TESTING);
+ if (timeString != null) {
+ if (timeString.equals("null")) {
+ sTimeForTestMillis = null;
+ } else {
+ sTimeForTestMillis = Long.parseLong(timeString);
+ }
+ }
+ }
+
+ @VisibleForTesting
+ static Long getTimeForTestMillis() {
+ return sTimeForTestMillis;
+ }
+
/**
* Gets an integer query parameter from a given uri.
*
diff --git a/src/com/android/providers/contacts/DbModifierWithNotification.java b/src/com/android/providers/contacts/DbModifierWithNotification.java
index ef1b847b..b3cf0ef4 100644
--- a/src/com/android/providers/contacts/DbModifierWithNotification.java
+++ b/src/com/android/providers/contacts/DbModifierWithNotification.java
@@ -63,7 +63,8 @@ public class DbModifierWithNotification implements DatabaseModifier {
private static final int SOURCE_PACKAGE_COLUMN_INDEX = 0;
private static final String NON_NULL_SOURCE_PACKAGE_SELECTION =
VoicemailContract.SOURCE_PACKAGE_FIELD + " IS NOT NULL";
-
+ private static final String NOT_DELETED_SELECTION =
+ Voicemails.DELETED + " == 0";
private final String mTableName;
private final SQLiteDatabase mDb;
private final InsertHelper mInsertHelper;
@@ -98,7 +99,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
public long insert(String table, String nullColumnHack, ContentValues values) {
Set<String> packagesModified = getModifiedPackages(values);
if (mIsCallsTable) {
- values.put(Calls.LAST_MODIFIED, System.currentTimeMillis());
+ values.put(Calls.LAST_MODIFIED, getTimeMillis());
}
long rowId = mDb.insert(table, nullColumnHack, values);
if (rowId > 0 && packagesModified.size() != 0) {
@@ -115,7 +116,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
public long insert(ContentValues values) {
Set<String> packagesModified = getModifiedPackages(values);
if (mIsCallsTable) {
- values.put(Calls.LAST_MODIFIED, System.currentTimeMillis());
+ values.put(Calls.LAST_MODIFIED, getTimeMillis());
}
long rowId = mInsertHelper.insert(values);
if (rowId > 0 && packagesModified.size() != 0) {
@@ -160,8 +161,12 @@ public class DbModifierWithNotification implements DatabaseModifier {
boolean hasMarkedRead = false;
if (mIsCallsTable) {
- values.put(Calls.LAST_MODIFIED, System.currentTimeMillis());
-
+ if (values.containsKey(Voicemails.DELETED)
+ && !values.getAsBoolean(Voicemails.DELETED)) {
+ values.put(Calls.LAST_MODIFIED, getTimeMillis());
+ } else {
+ 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
@@ -199,6 +204,15 @@ public class DbModifierWithNotification implements DatabaseModifier {
return count;
}
+ private void updateLastModified(String table, String whereClause, String[] whereArgs) {
+ ContentValues values = new ContentValues();
+ values.put(Calls.LAST_MODIFIED, getTimeMillis());
+
+ mDb.update(table, values,
+ DbQueryUtils.concatenateClauses(NOT_DELETED_SELECTION, whereClause),
+ whereArgs);
+ }
+
@Override
public int delete(String table, String whereClause, String[] whereArgs) {
Set<String> packagesModified = getModifiedPackages(whereClause, whereArgs);
@@ -217,7 +231,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
ContentValues values = new ContentValues();
values.put(VoicemailContract.Voicemails.DIRTY, 1);
values.put(VoicemailContract.Voicemails.DELETED, 1);
- values.put(VoicemailContract.Voicemails.LAST_MODIFIED, System.currentTimeMillis());
+ values.put(VoicemailContract.Voicemails.LAST_MODIFIED, getTimeMillis());
count = mDb.update(table, values, whereClause, whereArgs);
} else {
count = mDb.delete(table, whereClause, whereArgs);
@@ -363,4 +377,11 @@ public class DbModifierWithNotification implements DatabaseModifier {
}
return values.getAsBoolean(key);
}
+
+ private long getTimeMillis() {
+ if (CallLogProvider.getTimeForTestMillis() == null) {
+ return System.currentTimeMillis();
+ }
+ return CallLogProvider.getTimeForTestMillis();
+ }
}