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

Side by Side Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/BookmarksPage.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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.ntp;
6
7 import android.content.Context;
8 import android.content.SharedPreferences;
9 import android.content.res.Resources;
10 import android.graphics.Bitmap;
11 import android.graphics.Canvas;
12 import android.preference.PreferenceManager;
13 import android.view.LayoutInflater;
14 import android.view.View;
15 import android.view.ViewGroup;
16
17 import com.google.android.apps.chrome.R;
18
19 import org.chromium.chrome.browser.BookmarksBridge;
20 import org.chromium.chrome.browser.BookmarksBridge.BookmarkItem;
21 import org.chromium.chrome.browser.BookmarksBridge.BookmarkModelObserver;
22 import org.chromium.chrome.browser.BookmarksBridge.BookmarksCallback;
23 import org.chromium.chrome.browser.NativePage;
24 import org.chromium.chrome.browser.Tab;
25 import org.chromium.chrome.browser.UrlConstants;
26 import org.chromium.chrome.browser.bookmark.EditBookmarkHelper;
27 import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareT humbnailProvider;
28 import org.chromium.chrome.browser.favicon.FaviconHelper;
29 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
30 import org.chromium.chrome.browser.ntp.BookmarksPageView.BookmarksPageManager;
31 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
32 import org.chromium.chrome.browser.profiles.Profile;
33 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
34 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
35 import org.chromium.chrome.browser.util.ViewUtils;
36 import org.chromium.components.bookmarks.BookmarkId;
37 import org.chromium.components.bookmarks.BookmarkType;
38 import org.chromium.content_public.browser.LoadUrlParams;
39
40 import java.util.List;
41
42 /**
43 * Provides functionality when the user interacts with the bookmarks page. This class supports
44 * the regular bookmarks page as well as "select bookmark mode", in which contex t menus are
45 * disabled and clicking a bookmark just notifies a listener instead of loading the bookmark URL.
46 */
47 public class BookmarksPage implements NativePage, InvalidationAwareThumbnailProv ider {
48
49 private static final String LAST_USED_BOOKMARK_FOLDER_ID = "last_used_folder _id";
50
51 private static final int PAGE_MODE_NORMAL = 0;
52 private static final int PAGE_MODE_SELECT_BOOKMARK = 1;
53 private static final int PAGE_MODE_DOCUMENT = 2;
54
55 private final Profile mProfile;
56 private BookmarksBridge mBookmarksBridge;
57 private FaviconHelper mFaviconHelper;
58
59 private final BookmarksPageView mPageView;
60 private final String mTitle;
61 private final int mBackgroundColor;
62
63 // Whether destroy() has been called.
64 private boolean mIsDestroyed;
65
66 private BookmarkId mCurrentFolderId;
67
68 private final SharedPreferences mSharedPreferences;
69
70 /**
71 * Interface to be notified when the user clicks on a bookmark. To be used w ith
72 * buildPageForShortcutActivity().
73 */
74 public interface BookmarkSelectedListener {
75 /**
76 * Called when a bookmark is selected.
77 * @param url The url of the selected bookmark.
78 * @param title The title of the selected bookmark.
79 * @param favicon The favicon of the selected bookmark.
80 */
81 void onBookmarkSelected(String url, String title, Bitmap favicon);
82
83 /**
84 * Called when a new tab has been opened in a new tab.
85 */
86 void onNewTabOpened();
87 }
88
89 /**
90 * Creates a BookmarksPage to be shown in a tab.
91 * @param context The view context for showing the page.
92 * @param tab The tab in which the page will be shown.
93 * @param tabModelSelector The TabModelSelector to use when opening new tabs from the bookmarks
94 * page.
95 * @return The new BookmarksPage object.
96 */
97 public static BookmarksPage buildPage(Context context, Tab tab,
98 TabModelSelector tabModelSelector) {
99 return new BookmarksPage(context, tab.getProfile(), tab, tabModelSelecto r, null,
100 PAGE_MODE_NORMAL);
101 }
102
103 /**
104 * Creates a BookmarksPage to be shown in the ShortcutActivity.
105 * @param context The view context for showing the page.
106 * @param profile The profile from which to load bookmarks.
107 * @param listener The BookmarkSelectedListener to notify when the user clic ks a bookmark.
108 * @return The new BookmarksPage object.
109 */
110 public static BookmarksPage buildPageInSelectBookmarkMode(Context context,
111 Profile profile, BookmarkSelectedListener listener) {
112 return new BookmarksPage(context, profile, null, null, listener, PAGE_MO DE_SELECT_BOOKMARK);
113 }
114
115 /**
116 * Creates a BookmarksPage to be shown in document mode.
117 * @param context The view context for showing the page.
118 * @param tab The tab from which bookmarks page is loaded.
119 * @param tabModelSelector The TabModelSelector to use when opening new tabs from the bookmarks
120 * page.
121 * @param profile The profile from which to load bookmarks.
122 * @param listener The BookmarkSelectedListener to notify when the user clic ks a bookmark.
123 * @return The new BookmarksPage object.
124 */
125 public static BookmarksPage buildPageInDocumentMode(Context context, Tab tab ,
126 TabModelSelector tabModelSelector, Profile profile, BookmarkSelected Listener listener) {
127 return new BookmarksPage(
128 context, profile, tab, tabModelSelector, listener, PAGE_MODE_DOC UMENT);
129 }
130
131 /**
132 * Delegates user triggered actions for the bookmarks page.
133 */
134 private class BookmarksPageManagerImpl implements BookmarksPageManager {
135 protected Tab mTab;
136 protected TabModelSelector mTabModelSelector;
137
138 public BookmarksPageManagerImpl(Tab tab, TabModelSelector tabModelSelect or) {
139 mTab = tab;
140 mTabModelSelector = tabModelSelector;
141 }
142
143 protected void recordOpenedBookmark() {
144 if (!isIncognito()) {
145 NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_BOOKMARK) ;
146 }
147 }
148
149 @Override
150 public boolean isDestroyed() {
151 return mIsDestroyed;
152 }
153
154 @Override
155 public boolean isIncognito() {
156 return mTab.isIncognito();
157 }
158
159 @Override
160 public boolean shouldShowOpenInNewTab() {
161 return !isIncognito();
162 }
163
164 @Override
165 public boolean shouldShowOpenInNewIncognitoTab() {
166 return PrefServiceBridge.getInstance().isIncognitoModeEnabled();
167 }
168
169 @Override
170 public boolean isContextMenuEnabled() {
171 return true;
172 }
173
174 @Override
175 public void open(BookmarkItemView item) {
176 if (item.isFolder()) {
177 mTab.loadUrl(new LoadUrlParams(
178 UrlConstants.BOOKMARKS_FOLDER_URL + item.getBookmarkId() .toString()));
179 } else {
180 recordOpenedBookmark();
181 mTab.loadUrl(new LoadUrlParams(item.getUrl()));
182 }
183 }
184
185 @Override
186 public void openInNewTab(BookmarkItemView item) {
187 assert !item.isFolder();
188 recordOpenedBookmark();
189 mTabModelSelector.openNewTab(new LoadUrlParams(item.getUrl()),
190 TabLaunchType.FROM_LONGPRESS_BACKGROUND, mTab,
191 mTabModelSelector.isIncognitoSelected());
192 }
193
194 @Override
195 public void openInNewIncognitoTab(BookmarkItemView item) {
196 assert !item.isFolder();
197 recordOpenedBookmark();
198 mTabModelSelector.openNewTab(new LoadUrlParams(item.getUrl()),
199 TabLaunchType.FROM_LONGPRESS_BACKGROUND, mTab, true);
200 }
201
202 @Override
203 public void openFolder(BookmarkFolderHierarchyItem item) {
204 mTab.loadUrl(new LoadUrlParams(
205 UrlConstants.BOOKMARKS_FOLDER_URL + item.getFolderId()));
206 }
207
208 @Override
209 public void delete(BookmarkItemView item) {
210 if (mBookmarksBridge == null) return;
211 mBookmarksBridge.deleteBookmark(item.getBookmarkId());
212 }
213
214 @Override
215 public void edit(BookmarkItemView item) {
216 BookmarksPage.this.edit(item);
217 }
218
219 @Override
220 public void getFaviconImageForUrl(
221 String url, int size, FaviconImageCallback faviconCallback) {
222 BookmarksPage.this.getFaviconImageForUrl(url, size, faviconCallback) ;
223 }
224 }
225
226 private class DocumentModeManager extends BookmarksPageManagerImpl {
227 private final BookmarkSelectedListener mListener;
228
229 public DocumentModeManager(Tab tab, TabModelSelector tabModelSelector,
230 BookmarkSelectedListener listener) {
231 super(tab, tabModelSelector);
232 mListener = listener;
233 }
234
235 @Override
236 public void openInNewTab(BookmarkItemView item) {
237 super.openInNewTab(item);
238 mListener.onNewTabOpened();
239 }
240
241 @Override
242 public void openInNewIncognitoTab(BookmarkItemView item) {
243 super.openInNewIncognitoTab(item);
244 mListener.onNewTabOpened();
245 }
246
247 @Override
248 public void open(BookmarkItemView item) {
249 if (item.isFolder()) {
250 updateBookmarksPageContents(item.getBookmarkId(), false);
251 } else {
252 recordOpenedBookmark();
253 mListener.onBookmarkSelected(item.getUrl(), item.getTitle(), ite m.getFavicon());
254 }
255 }
256
257 @Override
258 public void openFolder(BookmarkFolderHierarchyItem item) {
259 updateBookmarksPageContents(item.getFolderId(), false);
260 }
261 }
262
263 private BookmarksPage(Context context, Profile profile, Tab tab,
264 TabModelSelector tabModelSelector, BookmarkSelectedListener listener ,
265 int pageMode) {
266 mProfile = profile;
267 mFaviconHelper = new FaviconHelper();
268 mTitle = context.getResources().getString(R.string.ntp_bookmarks);
269 mBackgroundColor = context.getResources().getColor(R.color.ntp_bg);
270 mCurrentFolderId = new BookmarkId(BookmarkId.INVALID_FOLDER_ID, Bookmark Type.NORMAL);
271 mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(conte xt);
272
273 LayoutInflater inflater = LayoutInflater.from(context);
274 mPageView = (BookmarksPageView) inflater.inflate(R.layout.bookmarks_page , null);
275
276 if (pageMode == PAGE_MODE_NORMAL || pageMode == PAGE_MODE_DOCUMENT) {
277 // mPageView (which has a transparent background) needs top padding of size
278 // R.dimen.tab_strip_height so that the bookmarks page isn't drawn o ver the tab strip.
279 // mPageView's first child (which has a white background) needs top padding of size
280 // R.dimen.toolbar_height_no_shadow so that the bookmarks page conte nts start below
281 // the URL bar.
282 // TODO(newt): combine these padding values and apply them just to m PageView, once the
283 // classic NTP is gone. Until then, we need to draw white behind the URL bar so the
284 // animation shown when pressing the "+" button in the tab switcher to open a new tab
285 // on the bookmarks page looks good.
286 Resources res = context.getResources();
287 int tabStripHeight = res.getDimensionPixelOffset(R.dimen.tab_strip_h eight);
288 int toolbarHeightNoShadow = res.getDimensionPixelOffset(
289 R.dimen.toolbar_height_no_shadow);
290 mPageView.setPadding(mPageView.getPaddingLeft(), tabStripHeight,
291 mPageView.getPaddingRight(), mPageView.getPaddingBottom());
292 View v = ((ViewGroup) mPageView).getChildAt(0);
293 v.setPadding(v.getPaddingLeft(), toolbarHeightNoShadow, v.getPadding Right(),
294 v.getPaddingBottom());
295 }
296
297 BookmarksPageManager manager = null;
298 switch (pageMode) {
299 case PAGE_MODE_NORMAL:
300 manager = buildManager(tab, tabModelSelector);
301 break;
302 case PAGE_MODE_SELECT_BOOKMARK:
303 manager = buildManagerForSelectBookmarkMode(listener);
304 break;
305 case PAGE_MODE_DOCUMENT:
306 manager = buildManagerForDocumentMode(tab, tabModelSelector, lis tener);
307 break;
308 default:
309 assert false;
310 break;
311 }
312
313 mPageView.initialize(manager);
314
315 mBookmarksBridge = new BookmarksBridge(mProfile);
316 mBookmarksBridge.addObserver(new BookmarkModelObserver() {
317 private void updateIfNodeIsCurrentFolder(BookmarkId nodeId) {
318 updateIfEitherNodeIsCurrentFolder(nodeId, nodeId);
319 }
320
321 private void updateIfEitherNodeIsCurrentFolder(BookmarkId firstNodeI d,
322 BookmarkId secondNodeId) {
323 if ((mCurrentFolderId.equals(firstNodeId)
324 || mCurrentFolderId.equals(secondNodeId))) {
325 updateBookmarksPageContents(mCurrentFolderId, true);
326 }
327 }
328
329 @Override
330 public void bookmarkNodeMoved(BookmarkItem oldParent,
331 int oldIndex, BookmarkItem newParent, int newIndex) {
332 updateIfEitherNodeIsCurrentFolder(oldParent.getId(), newParent.g etId());
333 }
334
335 @Override
336 public void bookmarkNodeAdded(BookmarkItem parent, int index) {
337 updateIfNodeIsCurrentFolder(parent.getId());
338 }
339
340 @Override
341 public void bookmarkNodeRemoved(BookmarkItem parent, int oldIndex, B ookmarkItem node,
342 boolean isExtensiveBookmarkChangesHappening) {
343 // Since the node is already removed, it does not have a parent. Hence, we need
344 // to pass the old parent information to check if it is the curr ent folder.
345 // node.getParentId() is INVALID_FOLDER_ID.
346 updateIfEitherNodeIsCurrentFolder(node.getId(), parent.getId());
347 }
348
349 @Override
350 public void bookmarkNodeChanged(BookmarkItem node) {
351 updateIfEitherNodeIsCurrentFolder(node.getId(), node.getParentId ());
352 }
353
354 @Override
355 public void bookmarkNodeChildrenReordered(BookmarkItem node) {
356 updateIfNodeIsCurrentFolder(node.getId());
357 }
358
359 @Override
360 public void bookmarkModelLoaded() {
361 // Purposefully don't do anything because we will be getting cal lbacks.
362 }
363
364 @Override
365 public void bookmarkModelChanged() {
366 updateBookmarksPageContents(mCurrentFolderId, true);
367 }
368 });
369 }
370
371 private BookmarksPageManager buildManager(Tab tab, TabModelSelector tabModel Selector) {
372 return new BookmarksPageManagerImpl(tab, tabModelSelector);
373 }
374
375 private BookmarksPageManager buildManagerForDocumentMode(
376 Tab tab, TabModelSelector tabModelSelector, BookmarkSelectedListener listener) {
377 return new DocumentModeManager(tab, tabModelSelector, listener);
378 }
379
380 private BookmarksPageManager buildManagerForSelectBookmarkMode(
381 final BookmarkSelectedListener listener) {
382 return new BookmarksPageManager() {
383 @Override
384 public boolean isDestroyed() {
385 return mIsDestroyed;
386 }
387
388 @Override
389 public boolean isIncognito() {
390 return false;
391 }
392
393 @Override
394 public boolean shouldShowOpenInNewTab() {
395 return false;
396 }
397
398 @Override
399 public boolean shouldShowOpenInNewIncognitoTab() {
400 return false;
401 }
402
403 @Override
404 public boolean isContextMenuEnabled() {
405 return false;
406 }
407
408 @Override
409 public void open(BookmarkItemView item) {
410 if (item.isFolder()) {
411 updateBookmarksPageContents(item.getBookmarkId(), false);
412 } else {
413 listener.onBookmarkSelected(item.getUrl(), item.getTitle(), item.getFavicon());
414 }
415 }
416
417 @Override
418 public void openInNewTab(BookmarkItemView item) {
419 }
420
421 @Override
422 public void openInNewIncognitoTab(BookmarkItemView item) {
423 }
424
425 @Override
426 public void openFolder(BookmarkFolderHierarchyItem item) {
427 updateBookmarksPageContents(item.getFolderId(), false);
428 }
429
430 @Override
431 public void delete(BookmarkItemView item) {
432 }
433
434 @Override
435 public void edit(BookmarkItemView item) {
436 }
437
438 @Override
439 public void getFaviconImageForUrl(
440 String url, int size, FaviconImageCallback faviconCallback) {
441 BookmarksPage.this.getFaviconImageForUrl(url, size, faviconCallb ack);
442 }
443 };
444 }
445
446 private void getFaviconImageForUrl(String url, int size, FaviconImageCallbac k faviconCallback) {
447 if (mFaviconHelper == null) return;
448 mFaviconHelper.getLocalFaviconImageForURL(mProfile, url,
449 FaviconHelper.FAVICON | FaviconHelper.TOUCH_ICON
450 | FaviconHelper.TOUCH_PRECOMPOSED_ICON,
451 size, faviconCallback);
452 }
453
454 private void edit(BookmarkItemView item) {
455 Context context = mPageView.getContext();
456 if (item.getBookmarkId().getType() == BookmarkType.PARTNER) {
457 EditBookmarkHelper.editPartnerBookmark(context, mProfile, item.getBo okmarkId().getId(),
458 item.getTitle(), item.isFolder());
459 } else {
460 EditBookmarkHelper.editBookmark(context, item.getBookmarkId().getId( ), item.isFolder());
461 }
462 }
463
464 /**
465 * Updates the contents of the bookmark page if the current folder has chang ed.
466 * @param folderId The ID of the folder to load.
467 * @param force Whether to force the update even if the folder has not chang ed.
468 */
469 private void updateBookmarksPageContents(BookmarkId folderId, boolean force) {
470 if (mBookmarksBridge == null) return;
471 if (!force && mCurrentFolderId.equals(folderId)) return;
472 BookmarksCallback callbackWrapper = new BookmarksCallback() {
473 @Override
474 public void onBookmarksFolderHierarchyAvailable(BookmarkId folderId,
475 List<BookmarkItem> bookmarksList) {
476 mPageView.onBookmarksFolderHierarchyAvailable(folderId, bookmark sList);
477 }
478
479 @Override
480 public void onBookmarksAvailable(BookmarkId folderId,
481 List<BookmarkItem> bookmarksList) {
482 // Update the folder ID based on the response, as sometimes it w ill be changed
483 // from the passed in value (if the ID passed in was invalid).
484 mCurrentFolderId = folderId;
485 updateLastUsedFolderId();
486 mPageView.onBookmarksAvailable(folderId, bookmarksList);
487 }
488 };
489 mBookmarksBridge.getBookmarksForFolder(folderId, callbackWrapper);
490 mBookmarksBridge.getCurrentFolderHierarchy(folderId, callbackWrapper);
491 }
492
493 private void updateLastUsedFolderId() {
494 mSharedPreferences.edit().putString(
495 LAST_USED_BOOKMARK_FOLDER_ID, mCurrentFolderId.toString()).apply ();
496 }
497
498 /**
499 * @return The last used bookmark folder id with fallback to the root folder id.
500 */
501 private BookmarkId getLastUsedFolderId() {
502 // If null shared prefs returns null, getBookmarkIdFromString() returns root folder id.
503 return BookmarkId.getBookmarkIdFromString(mSharedPreferences.getString(
504 LAST_USED_BOOKMARK_FOLDER_ID, null));
505 }
506
507 // NativePage overrides
508
509 @Override
510 public String getUrl() {
511 if (mCurrentFolderId.getId() < 0) {
512 return UrlConstants.BOOKMARKS_URL;
513 } else {
514 return UrlConstants.BOOKMARKS_FOLDER_URL + mCurrentFolderId.toString ();
515 }
516 }
517
518 @Override
519 public String getTitle() {
520 return mTitle;
521 }
522
523 @Override
524 public int getBackgroundColor() {
525 return mBackgroundColor;
526 }
527
528 @Override
529 public View getView() {
530 return mPageView;
531 }
532
533 /**
534 * Releases internal resources. This must be called eventually, and the obje ct should not used
535 * after calling this.
536 */
537 @Override
538 public void destroy() {
539 if (mFaviconHelper != null) {
540 mFaviconHelper.destroy();
541 mFaviconHelper = null;
542 }
543 if (mBookmarksBridge != null) {
544 mBookmarksBridge.destroy();
545 mBookmarksBridge = null;
546 }
547 mIsDestroyed = true;
548 }
549
550 @Override
551 public String getHost() {
552 return UrlConstants.BOOKMARKS_HOST;
553 }
554
555 @Override
556 public void updateForUrl(String url) {
557 BookmarkId folderId = null;
558 if (url != null && url.startsWith(UrlConstants.BOOKMARKS_FOLDER_URL)) {
559 String fragment = url.substring(UrlConstants.BOOKMARKS_FOLDER_URL.le ngth());
560 if (!fragment.isEmpty()) {
561 folderId = BookmarkId.getBookmarkIdFromString(fragment);
562 }
563 }
564 if (folderId == null) folderId = getLastUsedFolderId();
565 updateBookmarksPageContents(folderId, false);
566 }
567
568 // InvalidationAwareThumbnailProvider
569
570 @Override
571 public boolean shouldCaptureThumbnail() {
572 return mPageView.shouldCaptureThumbnail();
573 }
574
575 @Override
576 public void captureThumbnail(Canvas canvas) {
577 ViewUtils.captureBitmap(mPageView, canvas);
578 mPageView.updateThumbnailState();
579 }
580 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698