summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMakoto Onuki <omakoto@google.com>2014-08-11 10:27:39 -0700
committerMakoto Onuki <omakoto@google.com>2014-08-11 10:29:57 -0700
commit11d1e5f60f518e805c5f358f5376b87c08ef69d9 (patch)
tree8374eace979466b494b964fbd6b72b0ddf8266eb
parent9c9432da4380689419c9b18fb8955eeaec8ca86d (diff)
downloadpackages_providers_ContactsProvider-11d1e5f60f518e805c5f358f5376b87c08ef69d9.zip
packages_providers_ContactsProvider-11d1e5f60f518e805c5f358f5376b87c08ef69d9.tar.gz
packages_providers_ContactsProvider-11d1e5f60f518e805c5f358f5376b87c08ef69d9.tar.bz2
Fix getMimeTypeId/getPackageId
In the old code we only put ids to the cache in the insert case, but the select case. This means once the process restarts it'd never put anything in the cache. Also added the test for the conflict case. Bug 16574964 Change-Id: I9979b61b6e1a3f04a81bcf2b78a678378f1a009c
-rw-r--r--src/com/android/providers/contacts/ContactsDatabaseHelper.java1
-rw-r--r--tests/src/com/android/providers/contacts/ContactsDatabaseHelperTest.java56
2 files changed, 57 insertions, 0 deletions
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index a0f22f8..c8990ea 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -4510,6 +4510,7 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
// Then, try the database.
long id = queryIdWithOneArg(db, querySql, value);
if (id >= 0) {
+ cache.put(value, id);
return id;
}
diff --git a/tests/src/com/android/providers/contacts/ContactsDatabaseHelperTest.java b/tests/src/com/android/providers/contacts/ContactsDatabaseHelperTest.java
index a7229dc..eb995c3 100644
--- a/tests/src/com/android/providers/contacts/ContactsDatabaseHelperTest.java
+++ b/tests/src/com/android/providers/contacts/ContactsDatabaseHelperTest.java
@@ -18,6 +18,7 @@ package com.android.providers.contacts;
import android.database.sqlite.SQLiteDatabase;
import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.providers.contacts.ContactsDatabaseHelper.MimetypesColumns;
@@ -193,5 +194,60 @@ public class ContactsDatabaseHelperTest extends BaseContactsProvider2Test {
// Make sure the caches are also updated.
assertEquals(packageId2, (long) mDbHelper.mPackageCache.get("value2"));
assertEquals(mimetypeId2, (long) mDbHelper.mMimetypeCache.get("value2"));
+
+ // Clear the cache, but they should still return the values, selecting from the database.
+ mDbHelper.mPackageCache.clear();
+ mDbHelper.mMimetypeCache.clear();
+ assertEquals(packageId1, mDbHelper.getPackageId("value1"));
+ assertEquals(mimetypeId1, mDbHelper.getMimeTypeId("value1"));
+
+ // Empty the table
+ mDb.execSQL("DELETE FROM " + Tables.MIMETYPES);
+
+ // We should still have the cached value.
+ assertEquals(mimetypeId1, mDbHelper.getMimeTypeId("value1"));
+ }
+
+ /**
+ * Try to cause conflicts in getMimeTypeId() by calling it from multiple threads with
+ * the current time as the argument and make sure it won't crash.
+ *
+ * We don't know from the test if there have actually been conflits, but if you look at
+ * logcat you'll see a lot of conflict warnings.
+ */
+ @LargeTest
+ public void testGetMimeTypeId_conflict() {
+
+ final int NUM_THREADS = 4;
+ final int DURATION_SECONDS = 5;
+
+ final long finishTime = System.currentTimeMillis() + DURATION_SECONDS * 1000;
+
+ final Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ for (;;) {
+ final long now = System.currentTimeMillis();
+ if (now >= finishTime) {
+ return;
+ }
+ assertTrue(mDbHelper.getMimeTypeId(String.valueOf(now)) > 0);
+ }
+ }
+ };
+ final Thread[] threads = new Thread[NUM_THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new Thread(r);
+ threads[i].setDaemon(true);
+ }
+ for (int i = 0; i < threads.length; i++) {
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++) {
+ try {
+ threads[i].join();
+ } catch (InterruptedException ignore) {
+ }
+ }
}
}