Bug 708149 - Replace folder column with type in bookmarks table (r=rnewman)
authorLucas Rocha <lucasr@mozilla.com>
Tue, 20 Mar 2012 11:44:32 +0000
changeset 91941 a5223a4a37e8a6a11ac3863f1578e9c6a7355be7
parent 91940 56b4f77bbc10f12315b92d2f30bf4a8cef8189ad
child 91942 b0163319e529ef212b313d7b7399e4ce8325798a
push idunknown
push userunknown
push dateunknown
reviewersrnewman
bugs708149
milestone13.0a2
Bug 708149 - Replace folder column with type in bookmarks table (r=rnewman)
mobile/android/base/AwesomeBar.java
mobile/android/base/AwesomeBarTabs.java
mobile/android/base/ProfileMigrator.java
mobile/android/base/db/BrowserContract.java.in
mobile/android/base/db/BrowserProvider.java.in
mobile/android/base/db/LocalBrowserDB.java
mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java
mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java
mobile/android/base/sync/repositories/android/BrowserContractHelpers.java
mobile/android/base/tests/testBrowserProvider.java.in
--- a/mobile/android/base/AwesomeBar.java
+++ b/mobile/android/base/AwesomeBar.java
@@ -492,17 +492,18 @@ public class AwesomeBar extends Activity
             if (!(selectedItem instanceof Cursor)) {
                 Log.e(LOGTAG, "item at " + info.position + " is not a Cursor");
                 return;
             }
 
             Cursor cursor = (Cursor) selectedItem;
 
             // Don't show the context menu for folders
-            if (!(list == findViewById(R.id.bookmarks_list) && cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.IS_FOLDER)) == 1)) {
+            if (!(list == findViewById(R.id.bookmarks_list) &&
+                  cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.TYPE)) == Bookmarks.TYPE_FOLDER)) {
                 String keyword = null;
                 int keywordCol = cursor.getColumnIndex(URLColumns.KEYWORD);
                 if (keywordCol != -1)
                     keyword = cursor.getString(keywordCol);
 
                 mContextMenuSubject = new ContextMenuSubject(cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks._ID)),
                                                              cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL)),
                                                              cursor.getBlob(cursor.getColumnIndexOrThrow(URLColumns.FAVICON)),
--- a/mobile/android/base/AwesomeBarTabs.java
+++ b/mobile/android/base/AwesomeBarTabs.java
@@ -248,17 +248,17 @@ public class AwesomeBarTabs extends TabH
             mParentStack.addFirst(folderPair);
             refreshCurrentFolder();
         }
 
         public int getItemViewType(int position) {
             Cursor c = getCursor();
  
             if (c.moveToPosition(position) &&
-                c.getInt(c.getColumnIndexOrThrow(Bookmarks.IS_FOLDER)) == 1)
+                c.getInt(c.getColumnIndexOrThrow(Bookmarks.TYPE)) == Bookmarks.TYPE_FOLDER)
                 return VIEW_TYPE_FOLDER;
 
             // Default to retuning normal item type
             return VIEW_TYPE_ITEM;
         }
  
         @Override
         public int getViewTypeCount() {
@@ -867,18 +867,18 @@ public class AwesomeBarTabs extends TabH
         // If we tap on the header view, there's nothing to do
         if (position == 0)
             return;
 
         Cursor cursor = mBookmarksAdapter.getCursor();
         // The header view takes up a spot in the list
         cursor.moveToPosition(position - 1);
 
-        int isFolder = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.IS_FOLDER));
-        if (isFolder == 1) {
+        int type = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.TYPE));
+        if (type == Bookmarks.TYPE_FOLDER) {
             // If we're clicking on a folder, update mBookmarksAdapter to move to that folder
             int folderId = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks._ID));
             String folderTitle = mBookmarksAdapter.getFolderTitle(position - 1);
 
             mBookmarksAdapter.moveToChildFolder(folderId, folderTitle);
             return;
         }
 
--- a/mobile/android/base/ProfileMigrator.java
+++ b/mobile/android/base/ProfileMigrator.java
@@ -526,17 +526,17 @@ public class ProfileMigrator {
             values.put(SyncColumns.DATE_MODIFIED, modified);
             values.put(Bookmarks.POSITION, position);
             // Restore deleted record if possible
             values.put(Bookmarks.IS_DELETED, 0);
             if (mRerootMap.containsKey(parent)) {
                 parent = mRerootMap.get(parent);
             }
             values.put(Bookmarks.PARENT, parent);
-            values.put(Bookmarks.IS_FOLDER, (folder ? 1 : 0));
+            values.put(Bookmarks.TYPE, (folder ? Bookmarks.TYPE_FOLDER : Bookmarks.TYPE_BOOKMARK));
 
             Cursor cursor = null;
             ContentProviderOperation.Builder builder = null;
 
             if (url != null) {
                 try {
                     final String[] projection = new String[] {
                         Bookmarks._ID,
--- a/mobile/android/base/db/BrowserContract.java.in
+++ b/mobile/android/base/db/BrowserContract.java.in
@@ -103,24 +103,30 @@ public class BrowserContract {
 
         public static final String MOBILE_FOLDER_GUID = "mobile";
         public static final String PLACES_FOLDER_GUID = "places";
         public static final String MENU_FOLDER_GUID = "menu";
         public static final String TAGS_FOLDER_GUID = "tags";
         public static final String TOOLBAR_FOLDER_GUID = "toolbar";
         public static final String UNFILED_FOLDER_GUID = "unfiled";
 
+        public static final int TYPE_FOLDER = 0;
+        public static final int TYPE_BOOKMARK = 1;
+        public static final int TYPE_SEPARATOR = 2;
+        public static final int TYPE_LIVEMARK = 3;
+        public static final int TYPE_QUERY = 4;
+
         public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "bookmarks");
         public static final Uri PARENTS_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "parents");
         // Hacky API for bulk-updating positions. Bug 728783.
         public static final Uri POSITIONS_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "positions");
 
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/bookmark";
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/bookmark";
-        public static final String IS_FOLDER = "folder";
+        public static final String TYPE = "type";
         public static final String PARENT = "parent";
         public static final String POSITION = "position";
         public static final String TAGS = "tags";
         public static final String DESCRIPTION = "description";
         public static final String KEYWORD = "keyword";
     }
 
     public static final class History implements CommonColumns, URLColumns, ImageColumns, SyncColumns {
--- a/mobile/android/base/db/BrowserProvider.java.in
+++ b/mobile/android/base/db/BrowserProvider.java.in
@@ -50,17 +50,17 @@ import android.text.TextUtils;
 import android.util.Log;
 
 public class BrowserProvider extends ContentProvider {
     private static final String LOGTAG = "GeckoBrowserProvider";
     private Context mContext;
 
     static final String DATABASE_NAME = "browser.db";
 
-    static final int DATABASE_VERSION = 3;
+    static final int DATABASE_VERSION = 4;
 
     // Maximum age of deleted records to be cleaned up (20 days in ms)
     static final long MAX_AGE_OF_DELETED_RECORDS = 86400000 * 20;
 
     // Number of records marked as deleted to be removed
     static final long DELETED_RECORDS_PURGE_LIMIT = 5;
 
     static final String TABLE_BOOKMARKS = "bookmarks";
@@ -85,18 +85,18 @@ public class BrowserProvider extends Con
 
     // Image matches
     static final int IMAGES = 300;
     static final int IMAGES_ID = 301;
 
     // Schema matches
     static final int SCHEMA = 400;
 
-    static final String DEFAULT_BOOKMARKS_SORT_ORDER = Bookmarks.IS_FOLDER
-            + " DESC, " + Bookmarks.POSITION + " ASC, " + Bookmarks._ID
+    static final String DEFAULT_BOOKMARKS_SORT_ORDER = Bookmarks.TYPE
+            + " ASC, " + Bookmarks.POSITION + " ASC, " + Bookmarks._ID
             + " ASC";
 
     static final String DEFAULT_HISTORY_SORT_ORDER = History.DATE_LAST_VISITED + " DESC";
 
     static final String TABLE_BOOKMARKS_JOIN_IMAGES = TABLE_BOOKMARKS + " LEFT OUTER JOIN " +
             TABLE_IMAGES + " ON " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " = " +
             qualifyColumn(TABLE_IMAGES, Images.URL);
 
@@ -123,17 +123,17 @@ public class BrowserProvider extends Con
         URI_MATCHER.addURI(BrowserContract.AUTHORITY, "bookmarks/folder/#", BOOKMARKS_FOLDER_ID);
 
         map = new HashMap<String, String>();
         map.put(Bookmarks._ID, Bookmarks._ID);
         map.put(Bookmarks.TITLE, Bookmarks.TITLE);
         map.put(Bookmarks.URL, Bookmarks.URL);
         map.put(Bookmarks.FAVICON, Bookmarks.FAVICON);
         map.put(Bookmarks.THUMBNAIL, Bookmarks.THUMBNAIL);
-        map.put(Bookmarks.IS_FOLDER, Bookmarks.IS_FOLDER);
+        map.put(Bookmarks.TYPE, Bookmarks.TYPE);
         map.put(Bookmarks.PARENT, Bookmarks.PARENT);
         map.put(Bookmarks.POSITION, Bookmarks.POSITION);
         map.put(Bookmarks.TAGS, Bookmarks.TAGS);
         map.put(Bookmarks.DESCRIPTION, Bookmarks.DESCRIPTION);
         map.put(Bookmarks.KEYWORD, Bookmarks.KEYWORD);
         map.put(Bookmarks.DATE_CREATED, Bookmarks.DATE_CREATED);
         map.put(Bookmarks.DATE_MODIFIED, Bookmarks.DATE_MODIFIED);
         map.put(Bookmarks.GUID, Bookmarks.GUID);
@@ -183,16 +183,29 @@ public class BrowserProvider extends Con
     }
 
     private HashMap<String, DatabaseHelper> mDatabasePerProfile;
 
     private interface BookmarkMigrator {
         public void updateForNewTable(ContentValues bookmark);
     }
 
+    private class BookmarkMigrator3to4 implements BookmarkMigrator {
+        public void updateForNewTable(ContentValues bookmark) {
+            Integer isFolder = bookmark.getAsInteger("folder");
+            if (isFolder == null || isFolder != 1) {
+                bookmark.put(Bookmarks.TYPE, Bookmarks.TYPE_BOOKMARK);
+            } else {
+                bookmark.put(Bookmarks.TYPE, Bookmarks.TYPE_FOLDER);
+            }
+
+            bookmark.remove("folder");
+        }
+    }
+
     static final String qualifyColumn(String table, String column) {
         return table + "." + column;
     }
 
     private static boolean hasImagesInProjection(String[] projection) {
         if (projection == null) return true;
         for (int i = 0; i < projection.length; ++i) {
             if (projection[i].equals(Images.FAVICON) ||
@@ -234,17 +247,17 @@ public class BrowserProvider extends Con
                 foreignKeyOnParent = ", FOREIGN KEY (" + Bookmarks.PARENT +
                     ") REFERENCES " + TABLE_BOOKMARKS + "(" + Bookmarks._ID + ")";
             }
 
             db.execSQL("CREATE TABLE " + TABLE_BOOKMARKS + "(" +
                     Bookmarks._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                     Bookmarks.TITLE + " TEXT," +
                     Bookmarks.URL + " TEXT," +
-                    Bookmarks.IS_FOLDER + " INTEGER NOT NULL DEFAULT 0," +
+                    Bookmarks.TYPE + " INTEGER NOT NULL DEFAULT " + Bookmarks.TYPE_BOOKMARK + "," +
                     Bookmarks.PARENT + " INTEGER," +
                     Bookmarks.POSITION + " INTEGER NOT NULL," +
                     Bookmarks.KEYWORD + " TEXT," +
                     Bookmarks.DESCRIPTION + " TEXT," +
                     Bookmarks.TAGS + " TEXT," +
                     Bookmarks.DATE_CREATED + " INTEGER," +
                     Bookmarks.DATE_MODIFIED + " INTEGER," +
                     Bookmarks.GUID + " TEXT," +
@@ -355,17 +368,17 @@ public class BrowserProvider extends Con
             createOrUpdateSpecialFolder(db, Bookmarks.UNFILED_FOLDER_GUID,
                 R.string.bookmarks_folder_unfiled, 4);
         }
 
         private void createOrUpdateSpecialFolder(SQLiteDatabase db,
                 String guid, int titleId, int position) {
             ContentValues values = new ContentValues();
             values.put(Bookmarks.GUID, guid);
-            values.put(Bookmarks.IS_FOLDER, 1);
+            values.put(Bookmarks.TYPE, Bookmarks.TYPE_FOLDER);
             values.put(Bookmarks.POSITION, position);
 
             if (guid.equals(Bookmarks.PLACES_FOLDER_GUID))
                 values.put(Bookmarks._ID, Bookmarks.FIXED_ROOT_ID);
 
             // Set the parent to 0, which sync assumes is the root
             values.put(Bookmarks.PARENT, Bookmarks.FIXED_ROOT_ID);
 
@@ -456,18 +469,18 @@ public class BrowserProvider extends Con
                     }
 
                     if (migrator != null)
                         migrator.updateForNewTable(values);
 
                     debug("Migrating bookmark: " + values.getAsString(Bookmarks.TITLE));
                     db.insert(TABLE_BOOKMARKS, Bookmarks.URL, values);
 
-                    Integer isFolder = values.getAsInteger(Bookmarks.IS_FOLDER);
-                    if (isFolder != null && isFolder == 1)
+                    Integer type = values.getAsInteger(Bookmarks.TYPE);
+                    if (type != null && type == Bookmarks.TYPE_FOLDER)
                         subFolders.add(values.getAsInteger(Bookmarks._ID));
                 }
             } finally {
                 if (c != null)
                     c.close();
             }
 
             // At this point is safe to assume that the mobile folder is
@@ -536,16 +549,20 @@ public class BrowserProvider extends Con
             createBookmarksWithImagesView(db);
 
             debug("Dropping view: " + VIEW_HISTORY_WITH_IMAGES);
             db.execSQL("DROP VIEW IF EXISTS " + VIEW_HISTORY_WITH_IMAGES);
 
             createHistoryWithImagesView(db);
         }
 
+        private void upgradeDatabaseFrom3to4(SQLiteDatabase db) {
+            migrateBookmarksTable(db, new BookmarkMigrator3to4());
+        }
+
         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
             debug("Upgrading browser.db: " + db.getPath() + " from " +
                     oldVersion + " to " + newVersion);
 
             db.beginTransaction();
 
             // We have to do incremental upgrades until we reach the current
@@ -554,16 +571,20 @@ public class BrowserProvider extends Con
                 switch(v) {
                     case 2:
                         upgradeDatabaseFrom1to2(db);
                         break;
 
                     case 3:
                         upgradeDatabaseFrom2to3(db);
                         break;
+
+                    case 4:
+                        upgradeDatabaseFrom3to4(db);
+                        break;
                  }
              }
 
              db.setTransactionSuccessful();
              db.endTransaction();
         }
 
         @Override
@@ -945,20 +966,20 @@ public class BrowserProvider extends Con
 
                 if (!values.containsKey(Bookmarks.POSITION)) {
                     debug("Inserting bookmark with no position for URI");
                     values.put(Bookmarks.POSITION, Long.toString(Long.MIN_VALUE));
                 }
 
                 String url = values.getAsString(Bookmarks.URL);
                 ContentValues imageValues = extractImageValues(values, url);
-                Integer isFolder = values.getAsInteger(Bookmarks.IS_FOLDER);
+                Integer type = values.getAsInteger(Bookmarks.TYPE);
 
-                if ((isFolder == null || isFolder != 1) && imageValues != null
-                        && !TextUtils.isEmpty(url)) {
+                if ((type == null || type != Bookmarks.TYPE_FOLDER)
+                        && imageValues != null && !TextUtils.isEmpty(url)) {
                     debug("Inserting bookmark image for URL: " + url);
                     updateOrInsertImage(uri, imageValues, Images.URL + " = ?",
                             new String[] { url });
                 }
 
                 debug("Inserting bookmark in database with URL: " + url);
                 id = db.insertOrThrow(TABLE_BOOKMARKS, Bookmarks.TITLE, values);
                 break;
--- a/mobile/android/base/db/LocalBrowserDB.java
+++ b/mobile/android/base/db/LocalBrowserDB.java
@@ -90,17 +90,17 @@ public class LocalBrowserDB implements B
     private final Uri mImagesUriWithProfile;
     private final Uri mDeletedHistoryUriWithProfile;
 
     private static final String[] DEFAULT_BOOKMARK_COLUMNS =
             new String[] { Bookmarks._ID,
                            Bookmarks.GUID,
                            Bookmarks.URL,
                            Bookmarks.TITLE,
-                           Bookmarks.IS_FOLDER,
+                           Bookmarks.TYPE,
                            Bookmarks.PARENT,
                            Bookmarks.FAVICON }; 
 
     public LocalBrowserDB(String profile) {
         mProfile = profile;
         mMobileFolderId = -1;
         mDesktopBookmarksExist = null;
 
@@ -361,20 +361,25 @@ public class LocalBrowserDB implements B
                          Bookmarks.GUID + " = ?)",
                          new String[] { String.valueOf(folderId),
                                         Bookmarks.MOBILE_FOLDER_GUID,
                                         Bookmarks.TOOLBAR_FOLDER_GUID,
                                         Bookmarks.MENU_FOLDER_GUID,
                                         Bookmarks.UNFILED_FOLDER_GUID },
                          null);
         } else {
+            // Right now, we only support showing folder and bookmark type of
+            // entries. We should add support for other types though (bug 737024)
             c = cr.query(mBookmarksUriWithProfile,
                          DEFAULT_BOOKMARK_COLUMNS,
-                         Bookmarks.PARENT + " = ? ",
-                         new String[] { String.valueOf(folderId) },
+                         Bookmarks.PARENT + " = ? AND " +
+                         "(" + Bookmarks.TYPE + " = ? OR " + Bookmarks.TYPE + " = ?)",
+                         new String[] { String.valueOf(folderId),
+                                        String.valueOf(Bookmarks.TYPE_BOOKMARK),
+                                        String.valueOf(Bookmarks.TYPE_FOLDER) },
                          null);
         }
 
         return new LocalDBCursor(c);
     }
 
     // Returns true if any desktop bookmarks exist, which will be true if the user
     // has set up sync at one point, or done a profile migration from XUL fennec.
--- a/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java
+++ b/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java
@@ -21,17 +21,18 @@ import android.net.Uri;
 
 public class AndroidBrowserBookmarksDataAccessor extends AndroidBrowserRepositoryDataAccessor {
 
   private static final String LOG_TAG = "BookmarksDataAccessor";
 
   /*
    * Fragments of SQL to make our lives easier.
    */
-  private static final String BOOKMARK_IS_FOLDER = BrowserContract.Bookmarks.IS_FOLDER + " = 1";
+  private static final String BOOKMARK_IS_FOLDER = BrowserContract.Bookmarks.TYPE + " = " +
+                                                   BrowserContract.Bookmarks.TYPE_FOLDER;
   private static final String GUID_NOT_TAGS_OR_PLACES = BrowserContract.SyncColumns.GUID + " NOT IN ('" +
                                                         BrowserContract.Bookmarks.TAGS_FOLDER_GUID + "', '" +
                                                         BrowserContract.Bookmarks.PLACES_FOLDER_GUID + "')";
 
   private static final String EXCLUDE_SPECIAL_GUIDS_WHERE_CLAUSE;
   static {
     if (AndroidBrowserBookmarksRepositorySession.SPECIAL_GUIDS.length > 0) {
       StringBuilder b = new StringBuilder(BrowserContract.SyncColumns.GUID + " NOT IN (");
@@ -201,17 +202,19 @@ public class AndroidBrowserBookmarksData
     }
     cv.put(BrowserContract.Bookmarks.TAGS,        rec.tags.toJSONString());
     cv.put(BrowserContract.Bookmarks.KEYWORD,     rec.keyword);
     cv.put(BrowserContract.Bookmarks.PARENT,      rec.androidParentID);
     cv.put(BrowserContract.Bookmarks.POSITION,    rec.androidPosition);
 
     // Only bookmark and folder types should make it this far.
     // Other types should be filtered out and dropped.
-    cv.put(BrowserContract.Bookmarks.IS_FOLDER,   rec.type.equalsIgnoreCase(TYPE_FOLDER) ? 1 : 0);
+    cv.put(BrowserContract.Bookmarks.TYPE, rec.type.equalsIgnoreCase(TYPE_FOLDER) ?
+                                           BrowserContract.Bookmarks.TYPE_FOLDER :
+                                           BrowserContract.Bookmarks.TYPE_BOOKMARK);
 
     // Note that we don't set the modified timestamp: we allow the
     // content provider to do that for us.
     return cv;
   }
   
   /**
    * Returns a cursor over non-deleted records that list the given androidID as a parent.
--- a/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java
+++ b/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java
@@ -192,17 +192,18 @@ public class AndroidBrowserBookmarksRepo
       SPECIAL_GUIDS_MAP = Collections.unmodifiableMap(m);
     }
 
     dbHelper = new AndroidBrowserBookmarksDataAccessor(context);
     dataAccessor = (AndroidBrowserBookmarksDataAccessor) dbHelper;
   }
 
   private boolean rowIsFolder(Cursor cur) {
-    return RepoUtils.getLongFromCursor(cur, BrowserContract.Bookmarks.IS_FOLDER) == 1;
+    long type = RepoUtils.getLongFromCursor(cur, BrowserContract.Bookmarks.TYPE);
+    return type == BrowserContract.Bookmarks.TYPE_FOLDER;
   }
 
   private String getGUIDForID(long androidID) {
     String guid = idToGuid.get(androidID);
     trace("  " + androidID + " => " + guid);
     return guid;
   }
 
@@ -832,17 +833,18 @@ public class AndroidBrowserBookmarksRepo
     final boolean deleted   = isDeleted(cur);
     BookmarkRecord rec = new BookmarkRecord(guid, collection, lastModified, deleted);
 
     // No point in populating it.
     if (deleted) {
       return logBookmark(rec);
     }
 
-    boolean isFolder  = RepoUtils.getIntFromCursor(cur, BrowserContract.Bookmarks.IS_FOLDER) == 1;
+    long type = RepoUtils.getIntFromCursor(cur, BrowserContract.Bookmarks.TYPE);
+    boolean isFolder = type == BrowserContract.Bookmarks.TYPE_FOLDER;
 
     rec.title = RepoUtils.getStringFromCursor(cur, BrowserContract.Bookmarks.TITLE);
     rec.bookmarkURI = RepoUtils.getStringFromCursor(cur, BrowserContract.Bookmarks.URL);
     rec.description = RepoUtils.getStringFromCursor(cur, BrowserContract.Bookmarks.DESCRIPTION);
     rec.tags = RepoUtils.getJSONArrayFromCursor(cur, BrowserContract.Bookmarks.TAGS);
     rec.keyword = RepoUtils.getStringFromCursor(cur, BrowserContract.Bookmarks.KEYWORD);
     rec.type = isFolder ? AndroidBrowserBookmarksDataAccessor.TYPE_FOLDER :
                           AndroidBrowserBookmarksDataAccessor.TYPE_BOOKMARK;
--- a/mobile/android/base/sync/repositories/android/BrowserContractHelpers.java
+++ b/mobile/android/base/sync/repositories/android/BrowserContractHelpers.java
@@ -65,16 +65,16 @@ public class BrowserContractHelpers exte
   public static final String[] BookmarkColumns = new String[] {
     CommonColumns._ID,
     SyncColumns.GUID,
     SyncColumns.DATE_CREATED,
     SyncColumns.DATE_MODIFIED,
     SyncColumns.IS_DELETED,
     Bookmarks.TITLE,
     Bookmarks.URL,
-    Bookmarks.IS_FOLDER,
+    Bookmarks.TYPE,
     Bookmarks.PARENT,
     Bookmarks.POSITION,
     Bookmarks.TAGS,
     Bookmarks.DESCRIPTION,
     Bookmarks.KEYWORD
   };
 }
--- a/mobile/android/base/tests/testBrowserProvider.java.in
+++ b/mobile/android/base/tests/testBrowserProvider.java.in
@@ -33,25 +33,27 @@ public class testBrowserProvider extends
     private Uri mImagesUri;
 
     private String mBookmarksIdCol;
     private String mBookmarksTitleCol;
     private String mBookmarksUrlCol;
     private String mBookmarksFaviconCol;
     private String mBookmarksThumbnailCol;
     private String mBookmarksParentCol;
-    private String mBookmarksIsFolderCol;
+    private String mBookmarksTypeCol;
     private String mBookmarksPositionCol;
     private String mBookmarksTagsCol;
     private String mBookmarksDescriptionCol;
     private String mBookmarksKeywordCol;
     private String mBookmarksGuidCol;
     private String mBookmarksIsDeletedCol;
     private String mBookmarksDateCreatedCol;
     private String mBookmarksDateModifiedCol;
+    private int mBookmarksTypeFolder;
+    private int mBookmarksTypeBookmark;
     private long mMobileFolderId;
 
     private String mHistoryIdCol;
     private String mHistoryTitleCol;
     private String mHistoryUrlCol;
     private String mHistoryVisitsCol;
     private String mHistoryFaviconCol;
     private String mHistoryThumbnailCol;
@@ -78,26 +80,29 @@ public class testBrowserProvider extends
         UNFILED_FOLDER_GUID = getStringColumn("Bookmarks", "UNFILED_FOLDER_GUID");
 
         mBookmarksIdCol = getStringColumn("Bookmarks", "_ID");
         mBookmarksTitleCol = getStringColumn("Bookmarks", "TITLE");
         mBookmarksUrlCol = getStringColumn("Bookmarks", "URL");
         mBookmarksFaviconCol = getStringColumn("Bookmarks", "FAVICON");
         mBookmarksThumbnailCol = getStringColumn("Bookmarks", "THUMBNAIL");
         mBookmarksParentCol = getStringColumn("Bookmarks", "PARENT");
-        mBookmarksIsFolderCol = getStringColumn("Bookmarks", "IS_FOLDER");
+        mBookmarksTypeCol = getStringColumn("Bookmarks", "TYPE");
         mBookmarksPositionCol = getStringColumn("Bookmarks", "POSITION");
         mBookmarksTagsCol = getStringColumn("Bookmarks", "TAGS");
         mBookmarksDescriptionCol = getStringColumn("Bookmarks", "DESCRIPTION");
         mBookmarksKeywordCol= getStringColumn("Bookmarks", "KEYWORD");
         mBookmarksGuidCol = getStringColumn("Bookmarks", "GUID");
         mBookmarksIsDeletedCol = getStringColumn("Bookmarks", "IS_DELETED");
         mBookmarksDateCreatedCol = getStringColumn("Bookmarks", "DATE_CREATED");
         mBookmarksDateModifiedCol = getStringColumn("Bookmarks", "DATE_MODIFIED");
 
+        mBookmarksTypeFolder = getIntColumn("Bookmarks", "TYPE_FOLDER");
+        mBookmarksTypeBookmark = getIntColumn("Bookmarks", "TYPE_BOOKMARK");
+
         mHistoryIdCol = getStringColumn("History", "_ID");
         mHistoryTitleCol = getStringColumn("History", "TITLE");
         mHistoryUrlCol = getStringColumn("History", "URL");
         mHistoryVisitsCol = getStringColumn("History", "VISITS");
         mHistoryLastVisitedCol = getStringColumn("History", "DATE_LAST_VISITED");
         mHistoryFaviconCol = getStringColumn("History", "FAVICON");
         mHistoryThumbnailCol = getStringColumn("History", "THUMBNAIL");
         mHistoryGuidCol = getStringColumn("History", "GUID");
@@ -144,35 +149,34 @@ public class testBrowserProvider extends
         mAsserter.is(c.getCount(), 0, "All history entries were deleted");
 
         mProvider.delete(appendUriParam(mImagesUri, "PARAM_IS_SYNC", "1"), null, null);
         c = mProvider.query(appendUriParam(mImagesUri, "PARAM_SHOW_DELETED", "1"), null, null, null, null);
         mAsserter.is(c.getCount(), 0, "All images were deleted");
     }
 
     private ContentValues createBookmark(String title, String url, long parentId,
-            int isFolder, int position, String tags, String description,
-                String keyword) throws Exception {
+            int type, int position, String tags, String description, String keyword) throws Exception {
         ContentValues bookmark = new ContentValues();
 
         bookmark.put(mBookmarksTitleCol, title);
         bookmark.put(mBookmarksUrlCol, url);
         bookmark.put(mBookmarksParentCol, parentId);
-        bookmark.put(mBookmarksIsFolderCol, isFolder);
+        bookmark.put(mBookmarksTypeCol, type);
         bookmark.put(mBookmarksPositionCol, position);
         bookmark.put(mBookmarksTagsCol, tags);
         bookmark.put(mBookmarksDescriptionCol, description);
         bookmark.put(mBookmarksKeywordCol, keyword);
 
         return bookmark;
     }
 
     private ContentValues createOneBookmark() throws Exception {
         return createBookmark("Example", "http://example.com", mMobileFolderId,
-                0, 0, "tags", "description", "keyword");
+                mBookmarksTypeBookmark, 0, "tags", "description", "keyword");
     }
 
     private Cursor getBookmarkByGuid(String guid) throws Exception {
         return mProvider.query(mBookmarksUri, null,
                                mBookmarksGuidCol + " = ?",
                                new String[] { guid },
                                null);
     }
@@ -355,43 +359,53 @@ public class testBrowserProvider extends
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksTagsCol)), b.getAsString(mBookmarksTagsCol),
                          "Inserted bookmark has correct tags");
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksKeywordCol)), b.getAsString(mBookmarksKeywordCol),
                          "Inserted bookmark has correct keyword");
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksDescriptionCol)), b.getAsString(mBookmarksDescriptionCol),
                          "Inserted bookmark has correct description");
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksPositionCol)), b.getAsString(mBookmarksPositionCol),
                          "Inserted bookmark has correct position");
-            mAsserter.is(c.getString(c.getColumnIndex(mBookmarksIsFolderCol)), b.getAsString(mBookmarksIsFolderCol),
-                         "Inserted bookmark has correct is-folder flag");
+            mAsserter.is(c.getString(c.getColumnIndex(mBookmarksTypeCol)), b.getAsString(mBookmarksTypeCol),
+                         "Inserted bookmark has correct type");
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksParentCol)), b.getAsString(mBookmarksParentCol),
                          "Inserted bookmark has correct parent ID");
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksIsDeletedCol)), String.valueOf(0),
                          "Inserted bookmark has correct is-deleted state");
 
             id = insertWithNullCol(mBookmarksPositionCol);
             mAsserter.is(new Long(id), new Long(-1),
                          "Should not be able to insert bookmark with null position");
 
-            id = insertWithNullCol(mBookmarksIsFolderCol);
+            id = insertWithNullCol(mBookmarksTypeCol);
             mAsserter.is(new Long(id), new Long(-1),
-                         "Should not be able to insert bookmark with null is-folder flag");
+                         "Should not be able to insert bookmark with null type");
 
             b = createOneBookmark();
             b.put(mBookmarksParentCol, -1);
             id = -1;
 
             if (Build.VERSION.SDK_INT >= 8) {
                 try {
                     id = ContentUris.parseId(mProvider.insert(mBookmarksUri, b));
                 } catch (Exception e) {}
 
                 mAsserter.is(new Long(id), new Long(-1),
                              "Should not be able to insert bookmark with invalid parent");
             }
+
+            b = createOneBookmark();
+            b.remove(mBookmarksTypeCol);
+            id = ContentUris.parseId(mProvider.insert(mBookmarksUri, b));
+            c = getBookmarkById(id);
+
+            mAsserter.is(c.moveToFirst(), true, "Inserted bookmark found");
+
+            mAsserter.is(c.getString(c.getColumnIndex(mBookmarksTypeCol)), String.valueOf(mBookmarksTypeBookmark),
+                         "Inserted bookmark has correct default type");
         }
     }
 
     class TestInsertBookmarksImages extends Test {
         public void test() throws Exception {
             ContentValues b = createOneBookmark();
 
             final String favicon = "FAVICON";
@@ -459,24 +473,24 @@ public class testBrowserProvider extends
                          "Inserted bookmark was deleted using URI with id");
 
             c = getBookmarkById(id);
             mAsserter.is(c.moveToFirst(), false,
                          "Inserted bookmark can't be found after deletion using URI with ID");
 
             if (Build.VERSION.SDK_INT >= 8) {
                 ContentValues b = createBookmark("Folder", null, mMobileFolderId,
-                        1 /* is folder */, 0, "folderTags", "folderDescription", "folderKeyword");
+                        mBookmarksTypeFolder, 0, "folderTags", "folderDescription", "folderKeyword");
 
                 long parentId = ContentUris.parseId(mProvider.insert(mBookmarksUri, b));
                 c = getBookmarkById(parentId);
                 mAsserter.is(c.moveToFirst(), true, "Inserted bookmarks folder found");
 
-                b = createBookmark("Example", "http://example.com", parentId, 0, 0, "tags",
-                        "description", "keyword");
+                b = createBookmark("Example", "http://example.com", parentId,
+                        mBookmarksTypeBookmark, 0, "tags", "description", "keyword");
 
                 id = ContentUris.parseId(mProvider.insert(mBookmarksUri, b));
                 c = getBookmarkById(id);
                 mAsserter.is(c.moveToFirst(), true, "Inserted bookmark found");
 
                 deleted = 0;
                 try {
                     Uri uri = ContentUris.withAppendedId(mBookmarksUri, parentId);
@@ -533,17 +547,17 @@ public class testBrowserProvider extends
             long dateModified = c.getLong(c.getColumnIndex(mBookmarksDateModifiedCol));
 
             ContentValues u = new ContentValues();
             u.put(mBookmarksTitleCol, b.getAsString(mBookmarksTitleCol) + "CHANGED");
             u.put(mBookmarksUrlCol, b.getAsString(mBookmarksUrlCol) + "/more/stuff");
             u.put(mBookmarksTagsCol, b.getAsString(mBookmarksTagsCol) + "CHANGED");
             u.put(mBookmarksDescriptionCol, b.getAsString(mBookmarksDescriptionCol) + "CHANGED");
             u.put(mBookmarksKeywordCol, b.getAsString(mBookmarksKeywordCol) + "CHANGED");
-            u.put(mBookmarksIsFolderCol, 1);
+            u.put(mBookmarksTypeCol, mBookmarksTypeFolder);
             u.put(mBookmarksPositionCol, 10);
 
             int updated = mProvider.update(mBookmarksUri, u,
                                            mBookmarksIdCol + " = ?",
                                            new String[] { String.valueOf(id) });
 
             mAsserter.is((updated == 1), true, "Inserted bookmark was updated");
 
@@ -557,34 +571,34 @@ public class testBrowserProvider extends
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksTagsCol)), u.getAsString(mBookmarksTagsCol),
                          "Inserted bookmark has correct tags");
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksKeywordCol)), u.getAsString(mBookmarksKeywordCol),
                          "Inserted bookmark has correct keyword");
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksDescriptionCol)), u.getAsString(mBookmarksDescriptionCol),
                          "Inserted bookmark has correct description");
             mAsserter.is(c.getString(c.getColumnIndex(mBookmarksPositionCol)), u.getAsString(mBookmarksPositionCol),
                          "Inserted bookmark has correct position");
-            mAsserter.is(c.getString(c.getColumnIndex(mBookmarksIsFolderCol)), u.getAsString(mBookmarksIsFolderCol),
-                         "Inserted bookmark has correct is-folder flag");
+            mAsserter.is(c.getString(c.getColumnIndex(mBookmarksTypeCol)), u.getAsString(mBookmarksTypeCol),
+                         "Inserted bookmark has correct type");
 
             mAsserter.is(new Long(c.getLong(c.getColumnIndex(mBookmarksDateCreatedCol))),
                          new Long(dateCreated),
                          "Updated bookmark has same creation date");
 
             mAsserter.isnot(new Long(c.getLong(c.getColumnIndex(mBookmarksDateModifiedCol))),
                             new Long(dateModified),
                             "Updated bookmark has new modification date");
 
             updated = updateWithNullCol(id, mBookmarksPositionCol);
             mAsserter.is((updated > 0), false,
                          "Should not be able to update bookmark with null position");
 
-            updated = updateWithNullCol(id, mBookmarksIsFolderCol);
+            updated = updateWithNullCol(id, mBookmarksTypeCol);
             mAsserter.is((updated > 0), false,
-                         "Should not be able to update bookmark with null is-folder flag");
+                         "Should not be able to update bookmark with null type");
 
             u = new ContentValues();
             u.put(mBookmarksUrlCol, "http://examples2.com");
 
             updated = mProvider.update(ContentUris.withAppendedId(mBookmarksUri, id), u, null, null);
 
             c = getBookmarkById(id);
             mAsserter.is(c.moveToFirst(), true, "Updated bookmark found");