| 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;
|
| + }
|
| +}
|
|
|