Bug 1428434: Using Framework methods instead of DBUtils for concatenateWhere/appendSelectionArgs draft
authorConstantine Filin <constfilin@gmail.com>
Tue, 01 May 2018 18:00:15 -0700
changeset 791356 ff0b2a86f154c81c337972d38abbcf00ec861d3a
parent 790321 258fa1eb49c9a559f0f75bd0a597d14398b01430
push id108794
push userbmo:constfilin@gmail.com
push dateFri, 04 May 2018 05:56:26 +0000
bugs1428434
milestone61.0a1
Bug 1428434: Using Framework methods instead of DBUtils for concatenateWhere/appendSelectionArgs MozReview-Commit-ID: JF3Wsx9IYfs
mobile/android/base/java/org/mozilla/gecko/db/BrowserProvider.java
mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java
mobile/android/base/java/org/mozilla/gecko/db/HomeProvider.java
mobile/android/base/java/org/mozilla/gecko/db/LocalBrowserDB.java
mobile/android/base/java/org/mozilla/gecko/db/LoginsProvider.java
mobile/android/base/java/org/mozilla/gecko/db/TabsProvider.java
--- a/mobile/android/base/java/org/mozilla/gecko/db/BrowserProvider.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/BrowserProvider.java
@@ -575,33 +575,33 @@ public class BrowserProvider extends Sha
 
         final int match = URI_MATCHER.match(uri);
         int deleted = 0;
 
         switch (match) {
             case BOOKMARKS_ID:
                 trace("Delete on BOOKMARKS_ID: " + uri);
 
-                selection = DBUtils.concatenateWhere(selection, TABLE_BOOKMARKS + "._id = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, TABLE_BOOKMARKS + "._id = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case BOOKMARKS: {
                 trace("Deleting bookmarks: " + uri);
                 // Since we touch multiple records for most deletions, 'deleted' here really means 'affected'.
                 deleted = deleteBookmarks(uri, selection, selectionArgs);
                 deleteUnusedImages(uri);
                 break;
             }
 
             case HISTORY_ID:
                 trace("Delete on HISTORY_ID: " + uri);
 
-                selection = DBUtils.concatenateWhere(selection, TABLE_HISTORY + "._id = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, TABLE_HISTORY + "._id = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case HISTORY: {
                 trace("Deleting history: " + uri);
                 beginWrite(db);
                 /**
                  * Deletes from Sync are actual DELETE statements, which will cascade delete relevant visits.
                  * Fennec's deletes mark records as deleted and wipe out all information (except for GUID).
@@ -640,32 +640,32 @@ public class BrowserProvider extends Sha
                 expireThumbnails(db);
                 deleteUnusedImages(uri);
                 break;
             }
 
             case FAVICON_ID:
                 debug("Delete on FAVICON_ID: " + uri);
 
-                selection = DBUtils.concatenateWhere(selection, TABLE_FAVICONS + "._id = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, TABLE_FAVICONS + "._id = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case FAVICONS: {
                 trace("Deleting favicons: " + uri);
                 beginWrite(db);
                 deleted = deleteFavicons(uri, selection, selectionArgs);
                 break;
             }
 
             case THUMBNAIL_ID:
                 debug("Delete on THUMBNAIL_ID: " + uri);
 
-                selection = DBUtils.concatenateWhere(selection, TABLE_THUMBNAILS + "._id = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, TABLE_THUMBNAILS + "._id = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case THUMBNAILS: {
                 trace("Deleting thumbnails: " + uri);
                 beginWrite(db);
                 deleted = deleteThumbnails(uri, selection, selectionArgs);
                 break;
             }
@@ -678,18 +678,18 @@ public class BrowserProvider extends Sha
             case PAGE_METADATA:
                 trace("Delete on PAGE_METADATA: " + uri);
                 deleted = deletePageMetadata(uri, selection, selectionArgs);
                 break;
 
             case REMOTE_DEVICES_ID:
                 debug("Delete on REMOTE_DEVICES_ID: " + uri);
 
-                selection = DBUtils.concatenateWhere(selection, TABLE_REMOTE_DEVICES + "._ID = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, TABLE_REMOTE_DEVICES + "._ID = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case REMOTE_DEVICES: {
                 trace("Deleting FxA devices: " + uri);
                 beginWrite(db);
                 deleted = deleteRemoteDevices(uri, selection, selectionArgs);
                 break;
             }
@@ -838,35 +838,35 @@ public class BrowserProvider extends Sha
                 beginWrite(db);
                 updated = updateBookmarkParents(db, uri, values, selection, selectionArgs);
                 break;
             }
 
             case BOOKMARKS_ID:
                 debug("Update on BOOKMARKS_ID: " + uri);
 
-                selection = DBUtils.concatenateWhere(selection, TABLE_BOOKMARKS + "._id = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, TABLE_BOOKMARKS + "._id = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case BOOKMARKS: {
                 debug("Updating bookmark: " + uri);
                 if (shouldUpdateOrInsert(uri)) {
                     updated = updateOrInsertBookmark(uri, values, selection, selectionArgs);
                 } else {
                     updated = updateBookmarks(uri, values, selection, selectionArgs);
                 }
                 break;
             }
 
             case HISTORY_ID:
                 debug("Update on HISTORY_ID: " + uri);
 
-                selection = DBUtils.concatenateWhere(selection, TABLE_HISTORY + "._id = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, TABLE_HISTORY + "._id = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case HISTORY: {
                 debug("Updating history: " + uri);
                 if (shouldUpdateOrInsert(uri)) {
                     updated = updateOrInsertHistory(uri, values, selection, selectionArgs);
                 } else {
                     updated = updateHistory(uri, values, selection, selectionArgs);
@@ -1060,22 +1060,22 @@ public class BrowserProvider extends Sha
             } else {
                 hasProcessedAnySuggestedSites = true;
             }
             suggestedSitesBuilder.append(" SELECT" +
                                          " ? AS " + Bookmarks._ID + "," +
                                          " ? AS " + Bookmarks.URL + "," +
                                          " ? AS " + Bookmarks.TITLE);
 
-            suggestedSiteArgs = DBUtils.appendSelectionArgs(suggestedSiteArgs,
-                                                            new String[] {
-                                                                    suggestedSitesCursor.getString(idColumnIndex),
-                                                                    suggestedSitesCursor.getString(urlColumnIndex),
-                                                                    suggestedSitesCursor.getString(titleColumnIndex)
-                                                            });
+            suggestedSiteArgs = DatabaseUtils.appendSelectionArgs(suggestedSiteArgs,
+                                                                  new String[] {
+                                                                          suggestedSitesCursor.getString(idColumnIndex),
+                                                                          suggestedSitesCursor.getString(urlColumnIndex),
+                                                                          suggestedSitesCursor.getString(titleColumnIndex)
+                                                                  });
         }
         suggestedSitesCursor.close();
 
         // To restrict suggested sites to the grid, we simply subtract the number of topsites (which have already had
         // the pinned sites filtered out), and the number of pinned sites.
         // SQLite completely ignores negative limits, hence we need to manually limit to 0 in this case.
         final String suggestedLimitClause = " LIMIT MAX(0, (" + suggestedGridLimit + " - (SELECT COUNT(*) FROM " + TABLE_TOPSITES + ") - (SELECT COUNT(*) " + pinnedSitesFromClause + "))) ";
 
@@ -1282,27 +1282,27 @@ public class BrowserProvider extends Sha
 
         switch (match) {
             case BOOKMARKS_FOLDER_ID:
             case BOOKMARKS_ID:
             case BOOKMARKS: {
                 debug("Query is on bookmarks: " + uri);
 
                 if (match == BOOKMARKS_ID) {
-                    selection = DBUtils.concatenateWhere(selection, Bookmarks._ID + " = ?");
-                    selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                    selection = DatabaseUtils.concatenateWhere(selection, Bookmarks._ID + " = ?");
+                    selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                             new String[] { Long.toString(ContentUris.parseId(uri)) });
                 } else if (match == BOOKMARKS_FOLDER_ID) {
-                    selection = DBUtils.concatenateWhere(selection, Bookmarks.PARENT + " = ?");
-                    selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                    selection = DatabaseUtils.concatenateWhere(selection, Bookmarks.PARENT + " = ?");
+                    selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                             new String[] { Long.toString(ContentUris.parseId(uri)) });
                 }
 
                 if (!shouldShowDeleted(uri))
-                    selection = DBUtils.concatenateWhere(Bookmarks.IS_DELETED + " = 0", selection);
+                    selection = DatabaseUtils.concatenateWhere(Bookmarks.IS_DELETED + " = 0", selection);
 
                 if (TextUtils.isEmpty(sortOrder)) {
                     sortOrder = DEFAULT_BOOKMARKS_SORT_ORDER;
                 } else {
                     debug("Using sort order " + sortOrder + ".");
                 }
 
                 qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP);
@@ -1316,25 +1316,25 @@ public class BrowserProvider extends Sha
                 } else {
                     qb.setTables(TABLE_BOOKMARKS);
                 }
 
                 break;
             }
 
             case HISTORY_ID:
-                selection = DBUtils.concatenateWhere(selection, History._ID + " = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, History._ID + " = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case HISTORY: {
                 debug("Query is on history: " + uri);
 
                 if (!shouldShowDeleted(uri))
-                    selection = DBUtils.concatenateWhere(History.IS_DELETED + " = 0", selection);
+                    selection = DatabaseUtils.concatenateWhere(History.IS_DELETED + " = 0", selection);
 
                 if (TextUtils.isEmpty(sortOrder))
                     sortOrder = DEFAULT_HISTORY_SORT_ORDER;
 
                 qb.setProjectionMap(HISTORY_PROJECTION_MAP);
 
                 if (hasFaviconsInProjection(projection))
                     qb.setTables(VIEW_HISTORY_WITH_FAVICONS);
@@ -1350,32 +1350,32 @@ public class BrowserProvider extends Sha
                 qb.setTables(TABLE_VISITS);
 
                 if (TextUtils.isEmpty(sortOrder)) {
                     sortOrder = DEFAULT_VISITS_SORT_ORDER;
                 }
                 break;
 
             case FAVICON_ID:
-                selection = DBUtils.concatenateWhere(selection, Favicons._ID + " = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, Favicons._ID + " = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case FAVICONS: {
                 debug("Query is on favicons: " + uri);
 
                 qb.setProjectionMap(FAVICONS_PROJECTION_MAP);
                 qb.setTables(TABLE_FAVICONS);
 
                 break;
             }
 
             case THUMBNAIL_ID:
-                selection = DBUtils.concatenateWhere(selection, Thumbnails._ID + " = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, Thumbnails._ID + " = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case THUMBNAILS: {
                 debug("Query is on thumbnails: " + uri);
 
                 qb.setProjectionMap(THUMBNAILS_PROJECTION_MAP);
                 qb.setTables(TABLE_THUMBNAILS);
 
@@ -1425,18 +1425,18 @@ public class BrowserProvider extends Sha
                 debug("PageMetadata query: " + uri);
 
                 qb.setProjectionMap(PAGE_METADATA_PROJECTION_MAP);
                 qb.setTables(TABLE_PAGE_METADATA);
                 break;
             }
 
             case REMOTE_DEVICES_ID:
-                selection = DBUtils.concatenateWhere(selection, RemoteDevices._ID + " = ?");
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, RemoteDevices._ID + " = ?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case REMOTE_DEVICES: {
                 debug("FxA devices query: " + uri);
 
                 qb.setProjectionMap(REMOTE_DEVICES_PROJECTION_MAP);
                 qb.setTables(TABLE_REMOTE_DEVICES);
 
--- a/mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java
@@ -28,48 +28,16 @@ public class DBUtils {
     private static final String LOGTAG = "GeckoDBUtils";
 
     public static final int SQLITE_MAX_VARIABLE_NUMBER = 999;
 
     public static final String qualifyColumn(String table, String column) {
         return table + "." + column;
     }
 
-    // This is available in Android >= 11. Implemented locally to be
-    // compatible with older versions.
-    public static String concatenateWhere(String a, String b) {
-        if (TextUtils.isEmpty(a)) {
-            return b;
-        }
-
-        if (TextUtils.isEmpty(b)) {
-            return a;
-        }
-
-        return "(" + a + ") AND (" + b + ")";
-    }
-
-    // This is available in Android >= 11. Implemented locally to be
-    // compatible with older versions.
-    public static String[] appendSelectionArgs(String[] originalValues, String[] newValues) {
-        if (originalValues == null || originalValues.length == 0) {
-            return newValues;
-        }
-
-        if (newValues == null || newValues.length == 0) {
-            return originalValues;
-        }
-
-        String[] result = new String[originalValues.length + newValues.length];
-        System.arraycopy(originalValues, 0, result, 0, originalValues.length);
-        System.arraycopy(newValues, 0, result, originalValues.length, newValues.length);
-
-        return result;
-    }
-
     /**
      * Concatenate multiple lists of selection arguments. <code>values</code> may be <code>null</code>.
      */
     public static String[] concatenateSelectionArgs(String[]... values) {
         // Since we're most likely to be concatenating a few arrays of many values, it is most
         // efficient to iterate over the arrays once to obtain their lengths, allowing us to create one target array
         // (as opposed to copying arrays on every iteration, which would result in many more copies).
         int totalLength = 0;
--- a/mobile/android/base/java/org/mozilla/gecko/db/HomeProvider.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/HomeProvider.java
@@ -14,16 +14,17 @@ import org.mozilla.gecko.db.BrowserContr
 import org.mozilla.gecko.db.DBUtils;
 import org.mozilla.gecko.sqlite.SQLiteBridge;
 import org.mozilla.gecko.util.RawResource;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.UriMatcher;
 import android.database.Cursor;
+import android.database.DatabaseUtils;
 import android.database.MatrixCursor;
 import android.net.Uri;
 import android.util.Log;
 
 public class HomeProvider extends SQLiteBridgeContentProvider {
     private static final String LOGTAG = "GeckoHomeProvider";
 
     // This should be kept in sync with the db version in mobile/android/modules/HomeProvider.jsm
@@ -76,19 +77,19 @@ public class HomeProvider extends SQLite
             return queryFakeItems(uri, projection, selection, selectionArgs, sortOrder);
         }
 
         final String datasetId = uri.getQueryParameter(BrowserContract.PARAM_DATASET_ID);
         if (datasetId == null) {
             throw new IllegalArgumentException("All queries should contain a dataset ID parameter");
         }
 
-        selection = DBUtils.concatenateWhere(selection, HomeItems.DATASET_ID + " = ?");
-        selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
-                                                    new String[] { datasetId });
+        selection = DatabaseUtils.concatenateWhere(selection, HomeItems.DATASET_ID + " = ?");
+        selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
+                                                          new String[] { datasetId });
 
         // Otherwise, let the SQLiteContentProvider implementation take care of this query for us!
         Cursor c = super.query(uri, projection, selection, selectionArgs, sortOrder);
 
         // SQLiteBridgeContentProvider may return a null Cursor if the database hasn't been created yet.
         // However, we need a non-null cursor in order to listen for notifications.
         if (c == null) {
             c = new MatrixCursor(projection != null ? projection : HomeItems.DEFAULT_PROJECTION);
--- a/mobile/android/base/java/org/mozilla/gecko/db/LocalBrowserDB.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/LocalBrowserDB.java
@@ -48,16 +48,17 @@ import org.mozilla.gecko.util.StringUtil
 
 import android.content.ContentProviderClient;
 import android.content.ContentProviderOperation;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.ContentObserver;
 import android.database.Cursor;
+import android.database.DatabaseUtils;
 import android.database.MatrixCursor;
 import android.database.MergeCursor;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.drawable.BitmapDrawable;
 import android.net.Uri;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -657,27 +658,27 @@ public class LocalBrowserDB extends Brow
         // The combined history/bookmarks selection queries for sites with a URL or title containing
         // the constraint string(s), treating space-separated words as separate constraints
         if (!TextUtils.isEmpty(constraint)) {
             final String[] constraintWords = constraint.toString().split(" ");
 
             // Only create a filter query with a maximum of 10 constraint words.
             final int constraintCount = Math.min(constraintWords.length, 10);
             for (int i = 0; i < constraintCount; i++) {
-                selection = DBUtils.concatenateWhere(selection, "(" + Combined.URL + " LIKE ? OR " +
-                                                                      Combined.TITLE + " LIKE ?)");
+                selection = DatabaseUtils.concatenateWhere(selection, "(" + Combined.URL + " LIKE ? OR " +
+                                                                            Combined.TITLE + " LIKE ?)");
                 String constraintWord =  "%" + constraintWords[i] + "%";
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
-                                                            new String[] { constraintWord, constraintWord });
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
+                                                                  new String[] { constraintWord, constraintWord });
             }
         }
 
         if (urlFilter != null) {
-            selection = DBUtils.concatenateWhere(selection, "(" + Combined.URL + " NOT LIKE ?)");
-            selectionArgs = DBUtils.appendSelectionArgs(selectionArgs, new String[] { urlFilter.toString() });
+            selection = DatabaseUtils.concatenateWhere(selection, "(" + Combined.URL + " NOT LIKE ?)");
+            selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, new String[] { urlFilter.toString() });
         }
 
         // Order by combined remote+local frecency score.
         // Local visits are preferred, so they will by far outweigh remote visits.
         // Bookmarked history items get extra frecency points.
         final String sortOrder = BrowserContract.getCombinedFrecencySortOrder(true, false);
 
         return cr.query(combinedUriWithLimit(limit),
--- a/mobile/android/base/java/org/mozilla/gecko/db/LoginsProvider.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/LoginsProvider.java
@@ -153,18 +153,18 @@ public class LoginsProvider extends Shar
         final int match = URI_MATCHER.match(uri);
         final String table;
         final SQLiteDatabase db = getWritableDatabase(uri);
 
         beginWrite(db);
         switch (match) {
             case LOGINS_ID:
                 trace("Delete on LOGINS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_LOGINS, Logins._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_LOGINS, Logins._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[]{Long.toString(ContentUris.parseId(uri))});
                 // Store the deleted client in deleted-logins table.
                 final String guid = getLoginGUIDByID(selection, selectionArgs, db);
                 if (guid == null) {
                     // No matching logins found for the id.
                     return 0;
                 }
                 boolean isInsertSuccessful = storeDeletedLoginForGUIDInTransaction(guid, db);
@@ -175,29 +175,29 @@ public class LoginsProvider extends Shar
             // fall through
             case LOGINS:
                 trace("Delete on LOGINS: " + uri);
                 table = TABLE_LOGINS;
                 break;
 
             case DELETED_LOGINS_ID:
                 trace("Delete on DELETED_LOGINS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_DELETED_LOGINS, DeletedLogins._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_DELETED_LOGINS, DeletedLogins._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[]{Long.toString(ContentUris.parseId(uri))});
             // fall through
             case DELETED_LOGINS:
                 trace("Delete on DELETED_LOGINS_ID: " + uri);
                 table = TABLE_DELETED_LOGINS;
                 break;
 
             case DISABLED_HOSTS_HOSTNAME:
                 trace("Delete on DISABLED_HOSTS_HOSTNAME: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_DISABLED_HOSTS, LoginsDisabledHosts.HOSTNAME));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_DISABLED_HOSTS, LoginsDisabledHosts.HOSTNAME));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[]{uri.getLastPathSegment()});
             // fall through
             case DISABLED_HOSTS:
                 trace("Delete on DISABLED_HOSTS: " + uri);
                 table = TABLE_DISABLED_HOSTS;
                 break;
 
             default:
@@ -216,18 +216,18 @@ public class LoginsProvider extends Shar
         final int match = URI_MATCHER.match(uri);
         final SQLiteDatabase db = getWritableDatabase(uri);
         final String table;
 
         beginWrite(db);
         switch (match) {
             case LOGINS_ID:
                 trace("Update on LOGINS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_LOGINS, Logins._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_LOGINS, Logins._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[]{Long.toString(ContentUris.parseId(uri))});
 
             case LOGINS:
                 trace("Update on LOGINS: " + uri);
                 table = TABLE_LOGINS;
                 // Encrypt sensitive data.
                 encryptContentValueFields(values);
                 break;
@@ -250,18 +250,18 @@ public class LoginsProvider extends Shar
         final int match = URI_MATCHER.match(uri);
         final String groupBy = null;
         final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
         final String limit = uri.getQueryParameter(BrowserContract.PARAM_LIMIT);
 
         switch (match) {
             case LOGINS_ID:
                 trace("Query is on LOGINS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_LOGINS, Logins._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_LOGINS, Logins._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
 
             // fall through
             case LOGINS:
                 trace("Query is on LOGINS: " + uri);
                 if (TextUtils.isEmpty(sortOrder)) {
                     sortOrder = DEFAULT_LOGINS_SORT_ORDER;
                 } else {
@@ -269,18 +269,18 @@ public class LoginsProvider extends Shar
                 }
 
                 qb.setProjectionMap(LOGIN_PROJECTION_MAP);
                 qb.setTables(TABLE_LOGINS);
                 break;
 
             case DELETED_LOGINS_ID:
                 trace("Query is on DELETED_LOGINS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_DELETED_LOGINS, DeletedLogins._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_DELETED_LOGINS, DeletedLogins._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
 
             // fall through
             case DELETED_LOGINS:
                 trace("Query is on DELETED_LOGINS: " + uri);
                 if (TextUtils.isEmpty(sortOrder)) {
                     sortOrder = DEFAULT_DELETED_LOGINS_SORT_ORDER;
                 } else {
@@ -288,18 +288,18 @@ public class LoginsProvider extends Shar
                 }
 
                 qb.setProjectionMap(DELETED_LOGIN_PROJECTION_MAP);
                 qb.setTables(TABLE_DELETED_LOGINS);
                 break;
 
             case DISABLED_HOSTS_HOSTNAME:
                 trace("Query is on DISABLED_HOSTS_HOSTNAME: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_DISABLED_HOSTS, LoginsDisabledHosts.HOSTNAME));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_DISABLED_HOSTS, LoginsDisabledHosts.HOSTNAME));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { uri.getLastPathSegment() });
 
             // fall through
             case DISABLED_HOSTS:
                 trace("Query is on DISABLED_HOSTS: " + uri);
                 if (TextUtils.isEmpty(sortOrder)) {
                     sortOrder = DEFAULT_DISABLED_HOSTS_SORT_ORDER;
                 } else {
--- a/mobile/android/base/java/org/mozilla/gecko/db/TabsProvider.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/TabsProvider.java
@@ -10,16 +10,17 @@ import java.util.Map;
 
 import org.mozilla.gecko.db.BrowserContract.Clients;
 import org.mozilla.gecko.db.BrowserContract.Tabs;
 
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.UriMatcher;
 import android.database.Cursor;
+import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
 import android.text.TextUtils;
 
 public class TabsProvider extends SharedBrowserDatabaseProvider {
     private static final long ONE_DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
     private static final long ONE_WEEK_IN_MILLISECONDS = 7 * ONE_DAY_IN_MILLISECONDS;
@@ -156,29 +157,29 @@ public class TabsProvider extends Shared
         trace("Calling delete in transaction on URI: " + uri);
 
         final int match = URI_MATCHER.match(uri);
         int deleted = 0;
 
         switch (match) {
             case CLIENTS_ID:
                 trace("Delete on CLIENTS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case CLIENTS:
                 trace("Delete on CLIENTS: " + uri);
                 deleted = deleteValues(uri, selection, selectionArgs, TABLE_CLIENTS);
                 break;
 
             case TABS_ID:
                 trace("Delete on TABS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_TABS, Tabs._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_TABS, Tabs._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case TABS:
                 trace("Deleting on TABS: " + uri);
                 deleted = deleteValues(uri, selection, selectionArgs, TABLE_TABS);
                 break;
 
             default:
@@ -228,29 +229,29 @@ public class TabsProvider extends Shared
         trace("Calling update in transaction on URI: " + uri);
 
         int match = URI_MATCHER.match(uri);
         int updated = 0;
 
         switch (match) {
             case CLIENTS_ID:
                 trace("Update on CLIENTS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case CLIENTS:
                 trace("Update on CLIENTS: " + uri);
                 updated = updateValues(uri, values, selection, selectionArgs, TABLE_CLIENTS);
                 break;
 
             case TABS_ID:
                 trace("Update on TABS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_TABS, Tabs._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_TABS, Tabs._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case TABS:
                 trace("Update on TABS: " + uri);
                 updated = updateValues(uri, values, selection, selectionArgs, TABLE_TABS);
                 break;
 
             default:
@@ -271,18 +272,18 @@ public class TabsProvider extends Shared
 
         String groupBy = null;
         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
         String limit = uri.getQueryParameter(BrowserContract.PARAM_LIMIT);
 
         switch (match) {
             case TABS_ID:
                 trace("Query is on TABS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_TABS, Tabs._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_TABS, Tabs._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case TABS:
                 trace("Query is on TABS: " + uri);
                 if (TextUtils.isEmpty(sortOrder)) {
                     sortOrder = DEFAULT_TABS_SORT_ORDER;
                 } else {
                     debug("Using sort order " + sortOrder + ".");
@@ -292,18 +293,18 @@ public class TabsProvider extends Shared
                 qb.setTables(TABLE_TABS + " LEFT OUTER JOIN " + TABLE_CLIENTS + " ON (" + TABLE_TABS + "." + Tabs.CLIENT_GUID + " = " + TABLE_CLIENTS + "." + Clients.GUID +
                              " OR (" + TABLE_TABS + "." + Tabs.CLIENT_GUID + " IS NULL AND " + TABLE_CLIENTS + "." + Clients.GUID + " IS NULL))");
                 // 2nd OR clause is because the local client GUID is NULL and we can't assume that SQLite will compare NULL values with the equal operator
                 // More info here: http://stackoverflow.com/questions/5423751/how-do-the-sql-is-and-operators-differ/5424558#5424558
                 break;
 
             case CLIENTS_ID:
                 trace("Query is on CLIENTS_ID: " + uri);
-                selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients._ID));
-                selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
+                selection = DatabaseUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients._ID));
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
                         new String[] { Long.toString(ContentUris.parseId(uri)) });
                 // fall through
             case CLIENTS:
                 trace("Query is on CLIENTS: " + uri);
                 if (TextUtils.isEmpty(sortOrder)) {
                     sortOrder = DEFAULT_CLIENTS_SORT_ORDER;
                 } else {
                     debug("Using sort order " + sortOrder + ".");