Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4665)

Unified Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/BookmarksPageView.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/BookmarksPageView.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/BookmarksPageView.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/BookmarksPageView.java
new file mode 100644
index 0000000000000000000000000000000000000000..a950e5256512631577e6798fb71220104ff4b374
--- /dev/null
+++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/BookmarksPageView.java
@@ -0,0 +1,384 @@
+// Copyright 2015 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.ntp;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.LruCache;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.BaseAdapter;
+import android.widget.HorizontalScrollView;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.google.android.apps.chrome.R;
+
+import org.chromium.chrome.browser.BookmarksBridge.BookmarkItem;
+import org.chromium.chrome.browser.BookmarksBridge.BookmarksCallback;
+import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
+import org.chromium.components.bookmarks.BookmarkId;
+import org.chromium.ui.base.LocalizationUtils;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The native bookmarks page, represented by some basic data such as folder contents,
+ * folder hierarchy, and an Android View that displays the page.
+ */
+public class BookmarksPageView extends LinearLayout implements BookmarksCallback {
+
+ private static final int MAX_NUM_FAVICONS_TO_CACHE = 256;
+
+ private BookmarksPageManager mManager;
+ private HorizontalScrollView mHierarchyContainer;
+ private LinearLayout mHierarchyLayout;
+ private Bitmap mDefaultFavicon;
+ private BookmarkItemView.DrawingData mDrawingData;
+ private final int mDesiredFaviconSize;
+ private final LruCache<String, Bitmap> mFaviconCache;
+
+ private final BookmarkListAdapter mAdapter;
+ private BookmarksListView mBookmarksList;
+ private TextView mEmptyView;
+ private int mSavedListPosition = 0;
+ private int mSavedListTop = 0;
+
+ private boolean mSnapshotBookmarksChanged;
+ private int mSnapshotWidth;
+ private int mSnapshotHeight;
+ private int mSnapshotBookmarksListPosition;
+ private int mSnapshotBookmarksListTop;
+ private int mSnapshotBookmarksHierarchyScrollX;
+
+ /**
+ * Manages the view interaction with the rest of the system.
+ */
+ public interface BookmarksPageManager {
+ /**
+ * @return True, if destroy() has been called.
+ */
+ boolean isDestroyed();
+
+ /**
+ * @return Whether this bookmarks page should use incognito mode.
+ */
+ boolean isIncognito();
+
+ /**
+ * @return Whether "Open in new tab" should be shown in the context menu
+ * when long pressing a bookmark.
+ */
+ boolean shouldShowOpenInNewTab();
+
+ /**
+ * @return Whether "Open in new incognito tab" should be shown in the context menu
+ * when long pressing a bookmark.
+ */
+ boolean shouldShowOpenInNewIncognitoTab();
+
+ /**
+ * @return Whether to show a context menu on long press.
+ */
+ boolean isContextMenuEnabled();
+
+ /**
+ * Opens the bookmark item. If item is a bookmark then it opens the page else,
+ * if folder, it displays the folder contents.
+ * @param item BookmarkItem to be opened.
+ */
+ void open(BookmarkItemView item);
+
+ /**
+ * Opens a bookmark item in a new tab.
+ * @param item The bookmark item to open.
+ */
+ void openInNewTab(BookmarkItemView item);
+
+ /**
+ * Opens a bookmark item in a new incognito tab.
+ * @param item The bookmark item to open.
+ */
+ void openInNewIncognitoTab(BookmarkItemView item);
+
+ /**
+ * Opens the bookmark folder to display the folder contents.
+ * @param item BookmarkFolderHierarchyItem to be opened.
+ */
+ void openFolder(BookmarkFolderHierarchyItem item);
+
+ /**
+ * Deletes a bookmark entry.
+ * @param item The bookmark item to remove.
+ */
+ void delete(BookmarkItemView item);
+
+ /**
+ * Edits a bookmark entry.
+ * @param item The bookmark item to be edited.
+ */
+ void edit(BookmarkItemView item);
+
+ /**
+ * Gets the favicon image for a given URL.
+ * @param url The URL of the site whose favicon is being requested.
+ * @param size The desired size of the favicon in pixels.
+ * @param faviconCallback The callback to be notified when the favicon is available.
+ */
+ void getFaviconImageForUrl(String url, int size, FaviconImageCallback faviconCallback);
+ }
+
+ /**
+ * Constructor for inflating from XML.
+ */
+ public BookmarksPageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ mDesiredFaviconSize = getResources().getDimensionPixelSize(
+ R.dimen.ntp_list_item_favicon_size);
+ mFaviconCache = new LruCache<String, Bitmap>(MAX_NUM_FAVICONS_TO_CACHE);
+ mAdapter = new BookmarkListAdapter();
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ mHierarchyContainer =
+ (HorizontalScrollView) findViewById(R.id.folder_structure_scroll_view);
+ mHierarchyContainer.setSmoothScrollingEnabled(true);
+ mHierarchyLayout = (LinearLayout) findViewById(R.id.bookmark_folder_structure);
+
+ mBookmarksList = (BookmarksListView) findViewById(R.id.bookmarks_list_view);
+ mBookmarksList.setAdapter(mAdapter);
+
+ mEmptyView = (TextView) findViewById(R.id.bookmarks_empty_view);
+ mBookmarksList.setEmptyView(mEmptyView);
+ }
+
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ // Fixes lanscape transitions when unfocusing the URL bar: crbug.com/288546
+ outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
+ return super.onCreateInputConnection(outAttrs);
+ }
+
+ /**
+ * Handles initializing the view.
+ * @param manager The manager handling the external dependencies of this view.
+ */
+ void initialize(BookmarksPageManager manager) {
+ mManager = manager;
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ mSavedListPosition = mBookmarksList.getFirstVisiblePosition();
+ View v = mBookmarksList.getChildAt(0);
+ mSavedListTop = (v == null) ? 0 : v.getTop();
+ super.onDetachedFromWindow();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mBookmarksList.setSelectionFromTop(mSavedListPosition, mSavedListTop);
+ }
+
+ /**
+ * @see org.chromium.chrome.browser.compositor.layouts.content
+ * .InvalidationAwareThumbnailProvider#shouldCaptureThumbnail()
+ */
+ boolean shouldCaptureThumbnail() {
+ if (getWidth() == 0 || getHeight() == 0) return false;
+
+ View topItem = mBookmarksList.getChildAt(0);
+ return mSnapshotBookmarksChanged
+ || getWidth() != mSnapshotWidth
+ || getHeight() != mSnapshotHeight
+ || mSnapshotBookmarksListPosition != mBookmarksList.getFirstVisiblePosition()
+ || mSnapshotBookmarksListTop != (topItem == null ? 0 : topItem.getTop())
+ || mHierarchyContainer.getScrollX() != mSnapshotBookmarksHierarchyScrollX;
+ }
+
+ /**
+ * Triggered after a thumbnail has been captured to update the thumbnail visual state used to
+ * determine dirtiness.
+ */
+ void updateThumbnailState() {
+ mSnapshotWidth = getWidth();
+ mSnapshotHeight = getHeight();
+ mSnapshotBookmarksListPosition = mBookmarksList.getFirstVisiblePosition();
+ View topItem = mBookmarksList.getChildAt(0);
+ mSnapshotBookmarksListTop = topItem == null ? 0 : topItem.getTop();
+ mSnapshotBookmarksHierarchyScrollX = mHierarchyContainer.getScrollX();
+ mSnapshotBookmarksChanged = false;
+ }
+
+ // BookmarksCallback overrides
+
+ @Override
+ public void onBookmarksAvailable(BookmarkId folderId, List<BookmarkItem> bookmarksList) {
+ if (mEmptyView.length() == 0) {
+ // Set the empty view's text now that the first bookmarks callback has happened. If we
+ // set the text earlier, the user will see the "No bookmarks here" message while we're
+ // waiting for the callback.
+ mEmptyView.setText(R.string.bookmarks_folder_empty);
+ }
+
+ mAdapter.setBookmarksList(bookmarksList);
+ mAdapter.notifyDataSetChanged();
+
+ // In theory, the adapter should trigger a re-layout when the bookmarks list changes. In
+ // practice, if the bookmarks page is in the background and hence not attached to the view
+ // hierarchy, this doesn't happen. So, trigger the re-layout explicitly.
+ mBookmarksList.requestLayout();
+ mBookmarksList.invalidate();
+
+ // Cause the scroll bar to appear then fade out again if this folder is scrollable.
+ mBookmarksList.awakenScrollBars();
+
+ mSnapshotBookmarksChanged = true;
+ }
+
+ @Override
+ public void onBookmarksFolderHierarchyAvailable(BookmarkId folderId,
+ List<BookmarkItem> bookmarksList) {
+ if (mManager.isDestroyed()) return;
+ mHierarchyLayout.removeAllViews();
+ for (int i = bookmarksList.size() - 1; i >= 0; i--) {
+ BookmarkItem bookmark = bookmarksList.get(i);
+ addItemToHierarchyView(bookmark.getTitle(), bookmark.getId(), (i == 0) ? true : false);
+ }
+ mHierarchyLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ mHierarchyLayout.removeOnLayoutChangeListener(this);
+ mHierarchyContainer.fullScroll(LocalizationUtils.isLayoutRtl()
+ ? View.FOCUS_LEFT : View.FOCUS_RIGHT);
+ }
+ });
+
+ mSnapshotBookmarksChanged = true;
+ }
+
+ /**
+ * Add a BookmarkFolderHierarchyItem item to the hierarchy layout.
+ * @param title Title of the folder
+ * @param id Id of the folder
+ * @param isCurrentFolder Whether the folder is the current folder.
+ */
+ private void addItemToHierarchyView(String title, final BookmarkId id,
+ boolean isCurrentFolder) {
+ if (TextUtils.isEmpty(title)) {
+ // TODO(cramya): Need to check why we cannot get "Bookmarks" folder information.
+ title = getResources().getString(R.string.ntp_bookmarks);
+ } else {
+ ImageView separator = new ImageView(getContext());
+ separator.setImageResource(R.drawable.breadcrumb_arrow);
+ mHierarchyLayout.addView(separator);
+ }
+ final BookmarkFolderHierarchyItem item = new BookmarkFolderHierarchyItem(
+ getContext(), mManager, id, title, isCurrentFolder);
+ mHierarchyLayout.addView(item);
+ }
+
+ /**
+ * List Adapter for Bookmarks List View.
+ */
+ private class BookmarkListAdapter extends BaseAdapter {
+
+ public List<BookmarkItem> mBookmarks = Collections.emptyList();
+
+ /**
+ * Sets the bookmarks list for adapter.
+ * @param bookmarks BookmarkItem list.
+ */
+ public void setBookmarksList(List<BookmarkItem> bookmarks) {
+ mBookmarks = bookmarks;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (mDrawingData == null) mDrawingData = new BookmarkItemView.DrawingData(getContext());
+ final BookmarkItem bookmark = getItem(position);
+ final BookmarkItemView item;
+ if (convertView instanceof BookmarkItemView) {
+ item = (BookmarkItemView) convertView;
+ if (!item.reset(bookmark.getId(), bookmark.getTitle(), bookmark.getUrl(),
+ bookmark.isEditable(), bookmark.isManaged())) {
+ return item;
+ }
+ } else {
+ item = new BookmarkItemView(getContext(), mManager,
+ bookmark.getId(), bookmark.getTitle(), bookmark.getUrl(),
+ bookmark.isEditable(), bookmark.isManaged(), mDrawingData);
+ }
+ if (!bookmark.isFolder() && !TextUtils.isEmpty(bookmark.getUrl())) {
+ Bitmap favicon = mFaviconCache.get(bookmark.getUrl());
+ if (favicon != null) {
+ item.setFavicon(favicon);
+ } else if (!mManager.isDestroyed()) {
+ FaviconImageCallback faviconCallback = new FaviconImageCallback() {
+ @Override
+ public void onFaviconAvailable(Bitmap image, String iconUrl) {
+ if (image == null) {
+ if (mDefaultFavicon == null) {
+ mDefaultFavicon = BitmapFactory.decodeResource(
+ getResources(), R.drawable.default_favicon);
+ }
+ image = mDefaultFavicon;
+ }
+ mFaviconCache.put(bookmark.getUrl(), image);
+ // It's possible the BookmarkItemView has been recycled and is now
+ // displaying a different bookmark. Don't update the favicon in this
+ // case.
+ if (bookmark.getUrl().equals(item.getUrl())) {
+ item.setFavicon(image);
+ mSnapshotBookmarksChanged = true;
+ }
+ }
+ };
+ mManager.getFaviconImageForUrl(bookmark.getUrl(), mDesiredFaviconSize,
+ faviconCallback);
+ }
+ }
+ return item;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getCount() {
+ return mBookmarks.size();
+ }
+
+ @Override
+ public BookmarkItem getItem(int position) {
+ return mBookmarks.get(position);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return mBookmarks.isEmpty();
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698