summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/speeddial
diff options
context:
space:
mode:
authorcalderwoodra <calderwoodra@google.com>2017-12-19 15:58:58 -0800
committerEric Erfanian <erfanian@google.com>2017-12-22 08:50:09 -0800
commitc35c7580d48516eb8fedaad1142a40428c780946 (patch)
treeeba88ee0b18884e3fd2660e89a9a42df1efb3b9a /java/com/android/dialer/speeddial
parente2da6ef8a56bd9f7eedfa1c6d89e968590e0c09b (diff)
Implemented SpeedDialEntry Room Database.
This CL includes everything needed to interface with the SpeedDialEntry database. As an excersice to demonstrate it's functionlity, it also updates favorites to read from SpeedDialEntry database and the add favorites screen to insert into it. Bug: 36841782 Test: existing PiperOrigin-RevId: 179615699 Change-Id: I8938ef87244dffbd240506c112b445d147a88193
Diffstat (limited to 'java/com/android/dialer/speeddial')
-rw-r--r--java/com/android/dialer/speeddial/AddFavoriteActivity.java12
-rw-r--r--java/com/android/dialer/speeddial/DisambigDialog.java2
-rw-r--r--java/com/android/dialer/speeddial/FavoritesViewHolder.java2
-rw-r--r--java/com/android/dialer/speeddial/SpeedDialAdapter.java2
-rw-r--r--java/com/android/dialer/speeddial/SpeedDialCursor.java77
-rw-r--r--java/com/android/dialer/speeddial/StrequentContactsCursorLoader.java39
-rw-r--r--java/com/android/dialer/speeddial/room/SpeedDialDatabaseComponent.java38
-rw-r--r--java/com/android/dialer/speeddial/room/SpeedDialDatabaseModule.java35
-rw-r--r--java/com/android/dialer/speeddial/room/SpeedDialEntry.java58
-rw-r--r--java/com/android/dialer/speeddial/room/SpeedDialEntryDao.java44
-rw-r--r--java/com/android/dialer/speeddial/room/SpeedDialEntryDatabase.java55
11 files changed, 317 insertions, 47 deletions
diff --git a/java/com/android/dialer/speeddial/AddFavoriteActivity.java b/java/com/android/dialer/speeddial/AddFavoriteActivity.java
index eea6e840e..93cd536df 100644
--- a/java/com/android/dialer/speeddial/AddFavoriteActivity.java
+++ b/java/com/android/dialer/speeddial/AddFavoriteActivity.java
@@ -31,6 +31,8 @@ import com.android.dialer.common.Assert;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.contactsfragment.ContactsFragment;
import com.android.dialer.contactsfragment.ContactsFragment.OnContactSelectedListener;
+import com.android.dialer.speeddial.room.SpeedDialDatabaseComponent;
+import com.android.dialer.speeddial.room.SpeedDialEntry;
/**
* Activity for selecting a single contact and adding it to favorites.
@@ -93,13 +95,19 @@ public class AddFavoriteActivity extends AppCompatActivity implements OnContactS
@WorkerThread
private int markContactStarred(long contactId) {
- // TODO(calderwoodra): For now, we will just mark contacts as starred. This means that contacts
- // will only be able to exist once in favorites until we implement multiple contact avenues.
+ // Insert into SpeedDialEntry database
+ SpeedDialDatabaseComponent.get(getApplicationContext())
+ .speedDialDatabase()
+ .getSpeedDialEntryDao()
+ .insert(SpeedDialEntry.newSpeedDialEntry(contactId));
+
+ // Insert into Cp2
ContentValues contentValues = new ContentValues();
contentValues.put(Contacts.STARRED, 1);
String where = Contacts._ID + " = ?";
String[] selectionArgs = new String[] {Long.toString(contactId)};
+
return getContentResolver().update(Contacts.CONTENT_URI, contentValues, where, selectionArgs);
}
diff --git a/java/com/android/dialer/speeddial/DisambigDialog.java b/java/com/android/dialer/speeddial/DisambigDialog.java
index ca02f41eb..5598d1e48 100644
--- a/java/com/android/dialer/speeddial/DisambigDialog.java
+++ b/java/com/android/dialer/speeddial/DisambigDialog.java
@@ -234,6 +234,8 @@ public class DisambigDialog extends DialogFragment {
ArrayList<String> projection =
new ArrayList<>(Arrays.asList(LookupContactInfoWorker.projection));
projection.add(Phone.LOOKUP_KEY);
+ projection.add(Phone.CONTACT_ID);
+ projection.add(Phone.STARRED);
return projection.toArray(new String[projection.size()]);
}
diff --git a/java/com/android/dialer/speeddial/FavoritesViewHolder.java b/java/com/android/dialer/speeddial/FavoritesViewHolder.java
index c25b05ead..f9eec8e79 100644
--- a/java/com/android/dialer/speeddial/FavoritesViewHolder.java
+++ b/java/com/android/dialer/speeddial/FavoritesViewHolder.java
@@ -122,7 +122,7 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder
public interface FavoriteContactsListener {
/** Called when the user clicks on a favorite contact that doesn't have a default number. */
- void onAmbiguousContactClicked(String contactId);
+ void onAmbiguousContactClicked(String lookupKey);
/** Called when the user clicks on a favorite contact. */
void onClick(String number, boolean isVideoCall);
diff --git a/java/com/android/dialer/speeddial/SpeedDialAdapter.java b/java/com/android/dialer/speeddial/SpeedDialAdapter.java
index 5f7b68e5c..b72647550 100644
--- a/java/com/android/dialer/speeddial/SpeedDialAdapter.java
+++ b/java/com/android/dialer/speeddial/SpeedDialAdapter.java
@@ -90,7 +90,7 @@ final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
switch (cursor.getRowType(position)) {
case RowType.HEADER:
((HeaderViewHolder) holder).setHeaderText(cursor.getHeader());
- ((HeaderViewHolder) holder).showAddButton(cursor.hasFavorites() && position == 0);
+ ((HeaderViewHolder) holder).showAddButton(position == 0);
break;
case RowType.STARRED:
((FavoritesViewHolder) holder).bind(context, cursor);
diff --git a/java/com/android/dialer/speeddial/SpeedDialCursor.java b/java/com/android/dialer/speeddial/SpeedDialCursor.java
index 1208daefd..d693f94db 100644
--- a/java/com/android/dialer/speeddial/SpeedDialCursor.java
+++ b/java/com/android/dialer/speeddial/SpeedDialCursor.java
@@ -22,14 +22,19 @@ import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.support.annotation.IntDef;
import android.support.annotation.StringRes;
+import android.util.ArraySet;
import com.android.dialer.common.Assert;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.speeddial.room.SpeedDialEntry;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
+import java.util.Set;
/** Cursor for favorites contacts. */
-final class SpeedDialCursor extends MergeCursor {
+public final class SpeedDialCursor extends MergeCursor {
/**
* Caps the speed dial list to contain at most 20 contacts, including favorites and suggestions.
@@ -49,50 +54,55 @@ final class SpeedDialCursor extends MergeCursor {
int SUGGESTION = 2;
}
- public static SpeedDialCursor newInstance(Cursor strequentCursor) {
+ public static SpeedDialCursor newInstance(Cursor strequentCursor, List<SpeedDialEntry> entries) {
if (strequentCursor == null || strequentCursor.getCount() == 0) {
return null;
}
- SpeedDialCursor cursor = new SpeedDialCursor(buildCursors(strequentCursor));
+ SpeedDialCursor cursor = new SpeedDialCursor(buildCursors(strequentCursor, entries));
strequentCursor.close();
return cursor;
}
- private static Cursor[] buildCursors(Cursor strequentCursor) {
+ private static Cursor[] buildCursors(Cursor strequentCursor, List<SpeedDialEntry> entries) {
MatrixCursor starred = new MatrixCursor(StrequentContactsCursorLoader.PHONE_PROJECTION);
MatrixCursor suggestions = new MatrixCursor(StrequentContactsCursorLoader.PHONE_PROJECTION);
- strequentCursor.moveToPosition(-1);
- while (strequentCursor.moveToNext()) {
- if (strequentCursor.getPosition() != 0) {
- long contactId = strequentCursor.getLong(StrequentContactsCursorLoader.PHONE_CONTACT_ID);
- int position = strequentCursor.getPosition();
- boolean duplicate = false;
- // Iterate backwards through the cursor to check that this isn't a duplicate contact
- // TODO(calderwoodra): improve this algorithm (currently O(n^2)).
- while (strequentCursor.moveToPrevious() && !duplicate) {
- duplicate |=
- strequentCursor.getLong(StrequentContactsCursorLoader.PHONE_CONTACT_ID) == contactId;
- }
- strequentCursor.moveToPosition(position);
- if (duplicate) {
- continue;
- }
+ // Build starred cursor
+ for (SpeedDialEntry entry : entries) {
+ if (!moveToContactEntry(strequentCursor, entry)) {
+ LogUtil.e("SpeedDialCursor.buildCursors", "Entry not found: " + entry);
+ continue;
}
- if (strequentCursor.getInt(StrequentContactsCursorLoader.PHONE_STARRED) == 1) {
- StrequentContactsCursorLoader.addToCursor(starred, strequentCursor);
- } else if (starred.getCount() + suggestions.getCount() < SPEED_DIAL_CONTACT_LIST_SOFT_LIMIT) {
- // Since all starred contacts come before each non-starred contact, it's safe to assume that
- // this list will never exceed the soft limit unless there are more starred contacts than
- // the limit permits.
- StrequentContactsCursorLoader.addToCursor(suggestions, strequentCursor);
+ if (strequentCursor.getInt(StrequentContactsCursorLoader.PHONE_STARRED) != 1) {
+ LogUtil.e("SpeedDialCursor.buildCursors", "SpeedDialEntry contact is no longer starred");
+ continue;
}
+ StrequentContactsCursorLoader.addToCursor(starred, strequentCursor);
}
+ // Build suggestions cursor
+ strequentCursor.moveToFirst();
+ Set<Long> contactIds = new ArraySet<>();
+ do {
+ if (strequentCursor.getInt(StrequentContactsCursorLoader.PHONE_STARRED) == 1) {
+ // Starred contact
+ continue;
+ }
+
+ long contactId = strequentCursor.getLong(StrequentContactsCursorLoader.PHONE_CONTACT_ID);
+ if (!contactIds.add(contactId)) {
+ // duplicate contact
+ continue;
+ }
+
+ StrequentContactsCursorLoader.addToCursor(suggestions, strequentCursor);
+ } while (strequentCursor.moveToNext()
+ && starred.getCount() + suggestions.getCount() < SPEED_DIAL_CONTACT_LIST_SOFT_LIMIT);
+
List<Cursor> cursorList = new ArrayList<>();
+ cursorList.add(createHeaderCursor(R.string.favorites_header));
if (starred.getCount() > 0) {
- cursorList.add(createHeaderCursor(R.string.favorites_header));
cursorList.add(starred);
}
if (suggestions.getCount() > 0) {
@@ -102,6 +112,17 @@ final class SpeedDialCursor extends MergeCursor {
return cursorList.toArray(new Cursor[cursorList.size()]);
}
+ private static boolean moveToContactEntry(Cursor strequentCursor, SpeedDialEntry entry) {
+ boolean matchFound;
+ strequentCursor.moveToFirst();
+ do {
+ long contactId = strequentCursor.getLong(StrequentContactsCursorLoader.PHONE_CONTACT_ID);
+ String number = strequentCursor.getString(StrequentContactsCursorLoader.PHONE_NUMBER);
+ matchFound = contactId == entry.contactId || Objects.equals(number, entry.number);
+ } while (!matchFound && strequentCursor.moveToNext());
+ return matchFound;
+ }
+
private static Cursor createHeaderCursor(@StringRes int header) {
MatrixCursor cursor = new MatrixCursor(HEADER_CURSOR_PROJECTION);
cursor.newRow().add(HEADER_CURSOR_PROJECTION[HEADER_COLUMN_POSITION], header);
diff --git a/java/com/android/dialer/speeddial/StrequentContactsCursorLoader.java b/java/com/android/dialer/speeddial/StrequentContactsCursorLoader.java
index e9e3e32da..b8da47562 100644
--- a/java/com/android/dialer/speeddial/StrequentContactsCursorLoader.java
+++ b/java/com/android/dialer/speeddial/StrequentContactsCursorLoader.java
@@ -24,24 +24,27 @@ import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
+import com.android.dialer.speeddial.room.SpeedDialDatabaseComponent;
+import com.android.dialer.speeddial.room.SpeedDialEntry;
+import java.util.List;
/** Cursor Loader for strequent contacts. */
-final class StrequentContactsCursorLoader extends CursorLoader {
+public final class StrequentContactsCursorLoader extends CursorLoader {
- static final int PHONE_ID = 0;
- static final int PHONE_DISPLAY_NAME = 1;
- static final int PHONE_STARRED = 2;
- static final int PHONE_PHOTO_URI = 3;
- static final int PHONE_LOOKUP_KEY = 4;
- static final int PHONE_PHOTO_ID = 5;
- static final int PHONE_NUMBER = 6;
- static final int PHONE_TYPE = 7;
- static final int PHONE_LABEL = 8;
- static final int PHONE_IS_SUPER_PRIMARY = 9;
- static final int PHONE_PINNED = 10;
- static final int PHONE_CONTACT_ID = 11;
+ public static final int PHONE_ID = 0;
+ public static final int PHONE_DISPLAY_NAME = 1;
+ public static final int PHONE_STARRED = 2;
+ public static final int PHONE_PHOTO_URI = 3;
+ public static final int PHONE_LOOKUP_KEY = 4;
+ public static final int PHONE_PHOTO_ID = 5;
+ public static final int PHONE_NUMBER = 6;
+ public static final int PHONE_TYPE = 7;
+ public static final int PHONE_LABEL = 8;
+ public static final int PHONE_IS_SUPER_PRIMARY = 9;
+ public static final int PHONE_PINNED = 10;
+ public static final int PHONE_CONTACT_ID = 11;
- static final String[] PHONE_PROJECTION =
+ public static final String[] PHONE_PROJECTION =
new String[] {
Phone._ID, // 0
Phone.DISPLAY_NAME, // 1
@@ -92,6 +95,12 @@ final class StrequentContactsCursorLoader extends CursorLoader {
@Override
public Cursor loadInBackground() {
- return SpeedDialCursor.newInstance(super.loadInBackground());
+ Cursor strequentCursor = super.loadInBackground();
+ List<SpeedDialEntry> entries =
+ SpeedDialDatabaseComponent.get(getContext().getApplicationContext())
+ .speedDialDatabase()
+ .getSpeedDialEntryDao()
+ .getAllEntries();
+ return SpeedDialCursor.newInstance(strequentCursor, entries);
}
}
diff --git a/java/com/android/dialer/speeddial/room/SpeedDialDatabaseComponent.java b/java/com/android/dialer/speeddial/room/SpeedDialDatabaseComponent.java
new file mode 100644
index 000000000..c415fd767
--- /dev/null
+++ b/java/com/android/dialer/speeddial/room/SpeedDialDatabaseComponent.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.speeddial.room;
+
+import android.content.Context;
+import com.android.dialer.inject.HasRootComponent;
+import dagger.Subcomponent;
+
+/** Dagger component for the speed dial room database. */
+@Subcomponent
+public abstract class SpeedDialDatabaseComponent {
+
+ public abstract SpeedDialEntryDatabase speedDialDatabase();
+
+ public static SpeedDialDatabaseComponent get(Context context) {
+ return ((HasComponent) ((HasRootComponent) context.getApplicationContext()).component())
+ .speedDialDatabaseComponent();
+ }
+
+ /** Used to refer to the root application component. */
+ public interface HasComponent {
+ SpeedDialDatabaseComponent speedDialDatabaseComponent();
+ }
+}
diff --git a/java/com/android/dialer/speeddial/room/SpeedDialDatabaseModule.java b/java/com/android/dialer/speeddial/room/SpeedDialDatabaseModule.java
new file mode 100644
index 000000000..8bb510087
--- /dev/null
+++ b/java/com/android/dialer/speeddial/room/SpeedDialDatabaseModule.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.speeddial.room;
+
+import android.content.Context;
+import com.android.dialer.inject.ApplicationContext;
+import dagger.Module;
+import dagger.Provides;
+import javax.inject.Singleton;
+
+/** Dagger module which satisfies speed dial database dependencies. */
+@Module
+public class SpeedDialDatabaseModule {
+
+ @Provides
+ @Singleton
+ static SpeedDialEntryDatabase provideSpeedDialEntryDatabase(
+ @ApplicationContext Context appContext) {
+ return SpeedDialEntryDatabase.create(appContext);
+ }
+}
diff --git a/java/com/android/dialer/speeddial/room/SpeedDialEntry.java b/java/com/android/dialer/speeddial/room/SpeedDialEntry.java
new file mode 100644
index 000000000..37d2d8b98
--- /dev/null
+++ b/java/com/android/dialer/speeddial/room/SpeedDialEntry.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.speeddial.room;
+
+import android.arch.persistence.room.Entity;
+import android.arch.persistence.room.PrimaryKey;
+import android.support.annotation.IntDef;
+import android.support.annotation.Nullable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** SpeedDialEntry Entity. Represents a single element in favorites. */
+@Entity
+public class SpeedDialEntry {
+
+ public static final int UNKNOWN = 0;
+ public static final int VOICE = 1;
+ public static final int VIDEO = 2;
+
+ /** An Enum for the different row view types shown by this adapter. */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({UNKNOWN, VOICE, VIDEO})
+ public @interface Type {}
+
+ @PrimaryKey(autoGenerate = true)
+ public Integer id;
+
+ @Nullable public final String number;
+
+ public final long contactId;
+
+ @Type public final int type;
+
+ /** Build an unknown speed dial entry. */
+ public static SpeedDialEntry newSpeedDialEntry(long contactId) {
+ return new SpeedDialEntry(null, contactId, UNKNOWN);
+ }
+
+ public SpeedDialEntry(@Nullable String number, long contactId, @Type int type) {
+ this.number = number;
+ this.contactId = contactId;
+ this.type = type;
+ }
+}
diff --git a/java/com/android/dialer/speeddial/room/SpeedDialEntryDao.java b/java/com/android/dialer/speeddial/room/SpeedDialEntryDao.java
new file mode 100644
index 000000000..3e440deab
--- /dev/null
+++ b/java/com/android/dialer/speeddial/room/SpeedDialEntryDao.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.speeddial.room;
+
+import android.arch.persistence.room.Dao;
+import android.arch.persistence.room.Delete;
+import android.arch.persistence.room.Insert;
+import android.arch.persistence.room.Query;
+import android.arch.persistence.room.Update;
+import java.util.List;
+
+/** Data access object for {@link SpeedDialEntry}. */
+@Dao
+public interface SpeedDialEntryDao {
+
+ @Query("SELECT * FROM speeddialentry")
+ List<SpeedDialEntry> getAllEntries();
+
+ @Query("DELETE FROM speeddialentry")
+ void nukeTable();
+
+ @Insert
+ void insert(SpeedDialEntry... entries);
+
+ @Update
+ void update(SpeedDialEntry... entries);
+
+ @Delete
+ void delete(SpeedDialEntry... entries);
+}
diff --git a/java/com/android/dialer/speeddial/room/SpeedDialEntryDatabase.java b/java/com/android/dialer/speeddial/room/SpeedDialEntryDatabase.java
new file mode 100644
index 000000000..ff8e23743
--- /dev/null
+++ b/java/com/android/dialer/speeddial/room/SpeedDialEntryDatabase.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.speeddial.room;
+
+import android.arch.persistence.room.Database;
+import android.arch.persistence.room.Room;
+import android.arch.persistence.room.RoomDatabase;
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+import javax.inject.Singleton;
+
+/** Database of {@link SpeedDialEntry}. */
+@Database(
+ entities = {SpeedDialEntry.class},
+ // Version should not change unless SpeedDialEntry schema changes, then it should be incremented
+ version = 3
+)
+@Singleton
+public abstract class SpeedDialEntryDatabase extends RoomDatabase {
+
+ private static final String DB_NAME = "speedDialEntryoDatabase.db";
+ private static boolean allowMainThreadQueriesForTesting;
+
+ /* package-private */ static SpeedDialEntryDatabase create(Context appContext) {
+ RoomDatabase.Builder<SpeedDialEntryDatabase> builder =
+ Room.databaseBuilder(appContext, SpeedDialEntryDatabase.class, DB_NAME)
+ // TODO(calderwoodra): implement migration plan for database upgrades
+ .fallbackToDestructiveMigration();
+ if (allowMainThreadQueriesForTesting) {
+ builder.allowMainThreadQueries();
+ }
+ return builder.build();
+ }
+
+ public abstract SpeedDialEntryDao getSpeedDialEntryDao();
+
+ @VisibleForTesting
+ public static void allowMainThreadQueriesForTesting() {
+ allowMainThreadQueriesForTesting = true;
+ }
+}