Index: chrome/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksProviderIterator.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksProviderIterator.java b/chrome/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksProviderIterator.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e0914d325b08caddb5d9ea6998bd2f2a37219095 |
--- /dev/null |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksProviderIterator.java |
@@ -0,0 +1,135 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.browser.partnerbookmarks; |
+ |
+import android.content.ContentResolver; |
+import android.database.Cursor; |
+import android.net.Uri; |
+import android.util.Log; |
+ |
+import java.util.NoSuchElementException; |
+ |
+/** |
+ * Imports bookmarks from partner content provider using the private provider API. |
+ */ |
+public class PartnerBookmarksProviderIterator implements PartnerBookmarksReader.BookmarkIterator { |
+ |
+ private static final String TAG = "PartnerBookmarksProviderIterator"; |
+ private static final String PROVIDER_AUTHORITY = "com.android.partnerbookmarks"; |
+ private static final Uri CONTENT_URI = new Uri.Builder().scheme("content") |
+ .authority(PROVIDER_AUTHORITY).build(); |
+ |
+ // Private bookmarks structure. |
+ private static final String BOOKMARKS_PATH = "bookmarks"; |
+ private static final Uri BOOKMARKS_CONTENT_URI = |
+ CONTENT_URI.buildUpon().appendPath(BOOKMARKS_PATH).build(); |
+ private static final String BOOKMARKS_COLUMN_ID = "_id"; |
+ private static final String BOOKMARKS_COLUMN_URL = "url"; |
+ private static final String BOOKMARKS_COLUMN_TITLE = "title"; |
+ private static final String BOOKMARKS_COLUMN_TYPE = "type"; |
+ private static final String BOOKMARKS_COLUMN_PARENT = "parent"; |
+ private static final String BOOKMARKS_COLUMN_FAVICON = "favicon"; |
+ private static final String BOOKMARKS_COLUMN_TOUCHICON = "touchicon"; |
+ |
+ private static final int BOOKMARK_TYPE_FOLDER = 2; |
+ |
+ // Bookmark id of the main container folder. |
+ private static final long BOOKMARK_CONTAINER_FOLDER_ID = 0; |
+ |
+ private static final String BOOKMARKS_SORT_ORDER = BOOKMARKS_COLUMN_TYPE |
+ + " DESC, " + BOOKMARKS_COLUMN_ID + " ASC"; |
+ |
+ private static final String[] BOOKMARKS_PROJECTION = { |
+ BOOKMARKS_COLUMN_ID, |
+ BOOKMARKS_COLUMN_URL, |
+ BOOKMARKS_COLUMN_TITLE, |
+ BOOKMARKS_COLUMN_TYPE, |
+ BOOKMARKS_COLUMN_PARENT, |
+ BOOKMARKS_COLUMN_FAVICON, |
+ BOOKMARKS_COLUMN_TOUCHICON |
+ }; |
+ |
+ private final Cursor mCursor; |
+ |
+ /** |
+ * Creates the bookmarks iterator if possible. |
+ * @param contentResolver The content resolver to use. |
+ * @return Iterator over bookmarks or null. |
+ */ |
+ public static PartnerBookmarksProviderIterator createIfAvailable( |
+ ContentResolver contentResolver) { |
+ Cursor cursor = contentResolver.query(BOOKMARKS_CONTENT_URI, |
+ BOOKMARKS_PROJECTION, null, null, BOOKMARKS_SORT_ORDER); |
+ if (cursor == null) return null; |
+ return new PartnerBookmarksProviderIterator(cursor); |
+ } |
+ |
+ private PartnerBookmarksProviderIterator(Cursor cursor) { |
+ mCursor = cursor; |
+ } |
+ |
+ @Override |
+ public void remove() { |
+ throw new UnsupportedOperationException(); |
+ } |
+ |
+ @Override |
+ public void close() { |
+ if (mCursor == null) throw new IllegalStateException(); |
+ mCursor.close(); |
+ } |
+ |
+ @Override |
+ public boolean hasNext() { |
+ if (mCursor == null) throw new IllegalStateException(); |
+ // While the combination of !isLast() && !isAfterLast() should have been |
+ // sufficient, Android Cursor API doesn't specify isAfterLast's behavior |
+ // in the case of an empty cursor; hence, we fall back to |
+ // getCount() > 0 check. |
+ return mCursor.getCount() > 0 && !mCursor.isLast() && !mCursor.isAfterLast(); |
+ } |
+ |
+ @Override |
+ public PartnerBookmarksReader.Bookmark next() { |
+ if (mCursor == null) throw new IllegalStateException(); |
+ if (!mCursor.moveToNext()) throw new NoSuchElementException(); |
+ |
+ PartnerBookmarksReader.Bookmark bookmark = new PartnerBookmarksReader.Bookmark(); |
+ try { |
+ bookmark.mId = mCursor.getLong(mCursor.getColumnIndexOrThrow(BOOKMARKS_COLUMN_ID)); |
+ // The container folder should not be among the results. |
+ if (bookmark.mId == BOOKMARK_CONTAINER_FOLDER_ID) { |
+ Log.i(TAG, "Dropping the bookmark: reserved _id was used"); |
+ return null; |
+ } |
+ |
+ bookmark.mParentId = |
+ mCursor.getLong(mCursor.getColumnIndexOrThrow(BOOKMARKS_COLUMN_PARENT)); |
+ if (bookmark.mParentId == BOOKMARK_CONTAINER_FOLDER_ID) { |
+ bookmark.mParentId = PartnerBookmarksReader.ROOT_FOLDER_ID; |
+ } |
+ bookmark.mIsFolder = |
+ mCursor.getInt(mCursor.getColumnIndexOrThrow(BOOKMARKS_COLUMN_TYPE)) |
+ == BOOKMARK_TYPE_FOLDER; |
+ bookmark.mUrl = mCursor.getString(mCursor.getColumnIndexOrThrow(BOOKMARKS_COLUMN_URL)); |
+ bookmark.mTitle = |
+ mCursor.getString(mCursor.getColumnIndexOrThrow(BOOKMARKS_COLUMN_TITLE)); |
+ bookmark.mFavicon = |
+ mCursor.getBlob(mCursor.getColumnIndexOrThrow(BOOKMARKS_COLUMN_FAVICON)); |
+ bookmark.mTouchicon = |
+ mCursor.getBlob(mCursor.getColumnIndexOrThrow(BOOKMARKS_COLUMN_TOUCHICON)); |
+ } catch (IllegalArgumentException e) { |
+ Log.i(TAG, "Dropping the bookmark: " + e.getMessage()); |
+ return null; |
+ } |
+ |
+ if ((!bookmark.mIsFolder && bookmark.mUrl == null) || bookmark.mTitle == null) { |
+ Log.i(TAG, "Dropping the bookmark: no title, or no url on a non-foler"); |
+ return null; |
+ } |
+ |
+ return bookmark; |
+ } |
+} |