diff options
author | Ta-wei Yen <twyen@google.com> | 2017-01-17 19:28:13 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-01-17 19:28:13 +0000 |
commit | 51b15e88e873d21f1683db021b0ee72059c02126 (patch) | |
tree | 0e01f33efece35981b2b67c38b9ab449d4a2977e /src | |
parent | a4ae2c38359a9732138a13569392a431549735cd (diff) | |
parent | 79733da1e995680e27393c68755cf4e0762805cb (diff) | |
download | ContactsProvider-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.java | 42 | ||||
-rw-r--r-- | src/com/android/providers/contacts/DbModifierWithNotification.java | 33 |
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(); + } } |