| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.enhancedbookmarks; | 5 package org.chromium.chrome.browser.enhancedbookmarks; |
| 6 | 6 |
| 7 import android.app.ActivityManager; | 7 import android.app.ActivityManager; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.graphics.Bitmap; | 9 import android.graphics.Bitmap; |
| 10 import android.util.LruCache; | 10 import android.util.LruCache; |
| 11 import android.util.Pair; | 11 import android.util.Pair; |
| 12 | 12 |
| 13 import org.chromium.base.ApplicationStatus; | 13 import org.chromium.base.ApplicationStatus; |
| 14 import org.chromium.base.ObserverList; | 14 import org.chromium.base.ObserverList; |
| 15 import org.chromium.base.VisibleForTesting; | 15 import org.chromium.base.VisibleForTesting; |
| 16 import org.chromium.chrome.browser.BookmarksBridge; | 16 import org.chromium.chrome.browser.BookmarksBridge; |
| 17 import org.chromium.chrome.browser.favicon.LargeIconBridge; | 17 import org.chromium.chrome.browser.favicon.LargeIconBridge; |
| 18 import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback; | 18 import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback; |
| 19 import org.chromium.chrome.browser.offline_pages.OfflinePageBridge; | 19 import org.chromium.chrome.browser.offline_pages.OfflinePageBridge; |
| 20 import org.chromium.chrome.browser.offline_pages.OfflinePageBridge.OfflinePageMo
delObserver; |
| 21 import org.chromium.chrome.browser.offline_pages.OfflinePageBridge.SavePageCallb
ack; |
| 20 import org.chromium.chrome.browser.offline_pages.OfflinePageItem; | 22 import org.chromium.chrome.browser.offline_pages.OfflinePageItem; |
| 21 import org.chromium.chrome.browser.profiles.Profile; | 23 import org.chromium.chrome.browser.profiles.Profile; |
| 22 import org.chromium.components.bookmarks.BookmarkId; | 24 import org.chromium.components.bookmarks.BookmarkId; |
| 23 import org.chromium.components.bookmarks.BookmarkType; | 25 import org.chromium.components.bookmarks.BookmarkType; |
| 24 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; | 26 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; |
| 27 import org.chromium.components.offline_pages.SavePageResult; |
| 28 import org.chromium.content_public.browser.WebContents; |
| 25 | 29 |
| 26 import java.util.ArrayList; | 30 import java.util.ArrayList; |
| 27 import java.util.List; | 31 import java.util.List; |
| 28 | 32 |
| 29 /** | 33 /** |
| 30 * A class that encapsulates {@link BookmarksBridge} and provides extra features
such as undo, large | 34 * A class that encapsulates {@link BookmarksBridge} and provides extra features
such as undo, large |
| 31 * icon fetching, reader mode url redirecting, etc. This class should serve as t
he single class for | 35 * icon fetching, reader mode url redirecting, etc. This class should serve as t
he single class for |
| 32 * the UI to acquire data from the backend. | 36 * the UI to acquire data from the backend. |
| 33 */ | 37 */ |
| 34 public class EnhancedBookmarksModel extends BookmarksBridge { | 38 public class EnhancedBookmarksModel extends BookmarksBridge { |
| 35 private static final int FAVICON_MAX_CACHE_SIZE = 10 * 1024 * 1024; // 10MB | 39 private static final int FAVICON_MAX_CACHE_SIZE = 10 * 1024 * 1024; // 10MB |
| 36 | 40 |
| 37 /** | 41 /** |
| 42 * Callback for use with addBookmark. |
| 43 */ |
| 44 public interface AddBookmarkCallback { |
| 45 /** |
| 46 * Called when the bookmark has been added. |
| 47 * @param bookmarkId ID of the bookmark that has been added. |
| 48 */ |
| 49 void onBookmarkAdded(BookmarkId bookmarkId); |
| 50 } |
| 51 |
| 52 /** |
| 38 * Observer that listens to delete event. This interface is used by undo con
trollers to know | 53 * Observer that listens to delete event. This interface is used by undo con
trollers to know |
| 39 * which bookmarks were deleted. Note this observer only listens to events t
hat go through | 54 * which bookmarks were deleted. Note this observer only listens to events t
hat go through |
| 40 * enhanced bookmark model. | 55 * enhanced bookmark model. |
| 41 */ | 56 */ |
| 42 public interface EnhancedBookmarkDeleteObserver { | 57 public interface EnhancedBookmarkDeleteObserver { |
| 43 | 58 |
| 44 /** | 59 /** |
| 45 * Callback being triggered immediately before bookmarks are deleted. | 60 * Callback being triggered immediately before bookmarks are deleted. |
| 46 * @param titles All titles of the bookmarks to be deleted. | 61 * @param titles All titles of the bookmarks to be deleted. |
| 47 * @param isUndoable Whether the deletion is undoable. | 62 * @param isUndoable Whether the deletion is undoable. |
| 48 */ | 63 */ |
| 49 void onDeleteBookmarks(String[] titles, boolean isUndoable); | 64 void onDeleteBookmarks(String[] titles, boolean isUndoable); |
| 50 } | 65 } |
| 51 | 66 |
| 52 private LargeIconBridge mLargeIconBridge; | 67 private LargeIconBridge mLargeIconBridge; |
| 53 private ObserverList<EnhancedBookmarkDeleteObserver> mDeleteObservers = new
ObserverList<>(); | 68 private ObserverList<EnhancedBookmarkDeleteObserver> mDeleteObservers = new
ObserverList<>(); |
| 54 private LruCache<String, Pair<Bitmap, Integer>> mFaviconCache; | 69 private LruCache<String, Pair<Bitmap, Integer>> mFaviconCache; |
| 55 private OfflinePageBridge mOfflinePageBridge; | 70 private OfflinePageBridge mOfflinePageBridge; |
| 71 private boolean mIsOfflinePageModelLoaded; |
| 72 private OfflinePageModelObserver mOfflinePageModelObserver; |
| 56 | 73 |
| 57 /** | 74 /** |
| 58 * Initialize enhanced bookmark model for last used non-incognito profile. | 75 * Initialize enhanced bookmark model for last used non-incognito profile. |
| 59 */ | 76 */ |
| 60 public EnhancedBookmarksModel() { | 77 public EnhancedBookmarksModel() { |
| 61 this(Profile.getLastUsedProfile().getOriginalProfile()); | 78 this(Profile.getLastUsedProfile().getOriginalProfile()); |
| 62 } | 79 } |
| 63 | 80 |
| 64 @VisibleForTesting | 81 @VisibleForTesting |
| 65 public EnhancedBookmarksModel(Profile profile) { | 82 public EnhancedBookmarksModel(Profile profile) { |
| 66 super(profile); | 83 super(profile); |
| 67 mLargeIconBridge = new LargeIconBridge(); | 84 mLargeIconBridge = new LargeIconBridge(); |
| 68 | 85 |
| 69 ActivityManager activityManager = ((ActivityManager) ApplicationStatus | 86 ActivityManager activityManager = ((ActivityManager) ApplicationStatus |
| 70 .getApplicationContext().getSystemService(Context.ACTIVITY_SERVI
CE)); | 87 .getApplicationContext().getSystemService(Context.ACTIVITY_SERVI
CE)); |
| 71 int maxSize = Math.min(activityManager.getMemoryClass() / 4 * 1024 * 102
4, | 88 int maxSize = Math.min(activityManager.getMemoryClass() / 4 * 1024 * 102
4, |
| 72 FAVICON_MAX_CACHE_SIZE); | 89 FAVICON_MAX_CACHE_SIZE); |
| 73 mFaviconCache = new LruCache<String, Pair<Bitmap, Integer>>(maxSize) { | 90 mFaviconCache = new LruCache<String, Pair<Bitmap, Integer>>(maxSize) { |
| 74 @Override | 91 @Override |
| 75 protected int sizeOf(String key, Pair<Bitmap, Integer> icon) { | 92 protected int sizeOf(String key, Pair<Bitmap, Integer> icon) { |
| 76 int size = Integer.SIZE; | 93 int size = Integer.SIZE; |
| 77 if (icon.first != null) { | 94 if (icon.first != null) { |
| 78 size += icon.first.getByteCount(); | 95 size += icon.first.getByteCount(); |
| 79 } | 96 } |
| 80 return size; | 97 return size; |
| 81 } | 98 } |
| 82 }; | 99 }; |
| 83 | 100 |
| 84 if (OfflinePageBridge.isEnabled()) { | 101 if (OfflinePageBridge.isEnabled()) { |
| 85 // TODO(jianli): Make sure to wait until the bridge is loaded. | |
| 86 mOfflinePageBridge = new OfflinePageBridge(profile); | 102 mOfflinePageBridge = new OfflinePageBridge(profile); |
| 103 if (mOfflinePageBridge.isOfflinePageModelLoaded()) { |
| 104 mIsOfflinePageModelLoaded = true; |
| 105 } else { |
| 106 mOfflinePageModelObserver = new OfflinePageModelObserver() { |
| 107 @Override |
| 108 public void offlinePageModelLoaded() { |
| 109 mIsOfflinePageModelLoaded = true; |
| 110 if (isBookmarkModelLoaded()) { |
| 111 notifyBookmarkModelLoaded(); |
| 112 } |
| 113 } |
| 114 }; |
| 115 mOfflinePageBridge.addObserver(mOfflinePageModelObserver); |
| 116 } |
| 87 } | 117 } |
| 88 } | 118 } |
| 89 | 119 |
| 90 /** | 120 /** |
| 91 * Clean up all the bridges. This must be called after done using this class
. | 121 * Clean up all the bridges. This must be called after done using this class
. |
| 92 */ | 122 */ |
| 93 @Override | 123 @Override |
| 94 public void destroy() { | 124 public void destroy() { |
| 95 super.destroy(); | 125 if (mOfflinePageBridge != null) { |
| 126 mOfflinePageBridge.destroy(); |
| 127 mOfflinePageBridge = null; |
| 128 } |
| 96 mLargeIconBridge.destroy(); | 129 mLargeIconBridge.destroy(); |
| 97 mFaviconCache = null; | 130 mFaviconCache = null; |
| 131 |
| 132 super.destroy(); |
| 133 } |
| 134 |
| 135 @Override |
| 136 public boolean isBookmarkModelLoaded() { |
| 137 return super.isBookmarkModelLoaded() |
| 138 && (mOfflinePageBridge == null || mIsOfflinePageModelLoaded); |
| 98 } | 139 } |
| 99 | 140 |
| 100 /** | 141 /** |
| 101 * Add an observer that listens to delete events that go through enhanced bo
okmark model. | 142 * Add an observer that listens to delete events that go through enhanced bo
okmark model. |
| 102 * @param observer The observer to add. | 143 * @param observer The observer to add. |
| 103 */ | 144 */ |
| 104 public void addDeleteObserver(EnhancedBookmarkDeleteObserver observer) { | 145 public void addDeleteObserver(EnhancedBookmarkDeleteObserver observer) { |
| 105 mDeleteObservers.addObserver(observer); | 146 mDeleteObservers.addObserver(observer); |
| 106 } | 147 } |
| 107 | 148 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 /** | 190 /** |
| 150 * Calls {@link BookmarksBridge#moveBookmark(BookmarkId, BookmarkId, int)} i
n a reversed | 191 * Calls {@link BookmarksBridge#moveBookmark(BookmarkId, BookmarkId, int)} i
n a reversed |
| 151 * order of the list, in order to let the last item appear at the top. | 192 * order of the list, in order to let the last item appear at the top. |
| 152 */ | 193 */ |
| 153 public void moveBookmarks(List<BookmarkId> bookmarkIds, BookmarkId newParent
Id) { | 194 public void moveBookmarks(List<BookmarkId> bookmarkIds, BookmarkId newParent
Id) { |
| 154 for (int i = bookmarkIds.size() - 1; i >= 0; i--) { | 195 for (int i = bookmarkIds.size() - 1; i >= 0; i--) { |
| 155 moveBookmark(bookmarkIds.get(i), newParentId, 0); | 196 moveBookmark(bookmarkIds.get(i), newParentId, 0); |
| 156 } | 197 } |
| 157 } | 198 } |
| 158 | 199 |
| 159 @Override | 200 /** |
| 160 public BookmarkId addBookmark(BookmarkId parent, int index, String title, St
ring url) { | 201 * Add a new bookmark asynchronously. |
| 202 * |
| 203 * @param parent Folder where to add. |
| 204 * @param index The position where the bookmark will be placed in parent fol
der |
| 205 * @param title Title of the new bookmark. |
| 206 * @param url Url of the new bookmark |
| 207 * @param webContents A {@link WebContents} object. |
| 208 * @param callback The callback to be invoked when the bookmark is added. |
| 209 */ |
| 210 public void addBookmarkAsync(BookmarkId parent, int index, String title, Str
ing url, |
| 211 WebContents webContents, final AddBookmarkCallb
ack callback) { |
| 161 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); | 212 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); |
| 162 return super.addBookmark(parent, index, title, url); | 213 final BookmarkId enhancedId = addBookmark(parent, index, title, url); |
| 214 |
| 215 // If there is no need to save offline page, return now. |
| 216 if (mOfflinePageBridge == null) { |
| 217 callback.onBookmarkAdded(enhancedId); |
| 218 return; |
| 219 } |
| 220 |
| 221 mOfflinePageBridge.savePage(webContents, enhancedId, |
| 222 new SavePageCallback() { |
| 223 @Override |
| 224 public void onSavePageDone(int savePageResult, String url) { |
| 225 // TODO(jianli): Error handling. |
| 226 if (savePageResult == SavePageResult.SUCCESS) { |
| 227 callback.onBookmarkAdded(enhancedId); |
| 228 } |
| 229 } |
| 230 }); |
| 163 } | 231 } |
| 164 | 232 |
| 165 /** | 233 /** |
| 166 * @see org.chromium.chrome.browser.BookmarksBridge.BookmarkItem#getTitle() | 234 * @see org.chromium.chrome.browser.BookmarksBridge.BookmarkItem#getTitle() |
| 167 */ | 235 */ |
| 168 public String getBookmarkTitle(BookmarkId bookmarkId) { | 236 public String getBookmarkTitle(BookmarkId bookmarkId) { |
| 169 return getBookmarkById(bookmarkId).getTitle(); | 237 return getBookmarkById(bookmarkId).getTitle(); |
| 170 } | 238 } |
| 171 | 239 |
| 172 /** | 240 /** |
| 241 * Returns the url used to launch a bookmark. |
| 242 * |
| 243 * @param bookmarkId ID of the bookmark to launch. |
| 244 */ |
| 245 public String getBookmarkLaunchUrl(BookmarkId bookmarkId) { |
| 246 String url = getBookmarkById(bookmarkId).getUrl(); |
| 247 if (mOfflinePageBridge == null) { |
| 248 return url; |
| 249 } |
| 250 |
| 251 // Return the offline url for the offline page. |
| 252 OfflinePageItem page = mOfflinePageBridge.getPageByBookmarkId(bookmarkId
); |
| 253 return page == null ? url : page.getOfflineUrl(); |
| 254 } |
| 255 |
| 256 /** |
| 173 * Retrieves a favicon and fallback color for the given |url|. An LRU cache
is used to store the | 257 * Retrieves a favicon and fallback color for the given |url|. An LRU cache
is used to store the |
| 174 * favicons. If the favicon is not already present in the cache, it is retri
eved using | 258 * favicons. If the favicon is not already present in the cache, it is retri
eved using |
| 175 * LargeIconBridge#getLargeIconForUrl(). | 259 * LargeIconBridge#getLargeIconForUrl(). |
| 176 * | 260 * |
| 177 * @see LargeIconBridge#getLargeIconForUrl(Profile, String, int, LargeIconCa
llback) | 261 * @see LargeIconBridge#getLargeIconForUrl(Profile, String, int, LargeIconCa
llback) |
| 178 */ | 262 */ |
| 179 public void getLargeIcon(final String url, int minSize, final LargeIconCallb
ack callback) { | 263 public void getLargeIcon(final String url, int minSize, final LargeIconCallb
ack callback) { |
| 180 assert callback != null; | 264 assert callback != null; |
| 181 LargeIconCallback callbackWrapper = callback; | 265 LargeIconCallback callbackWrapper = callback; |
| 182 | 266 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 public List<BookmarkId> getBookmarkIDsByFilter(EnhancedBookmarkFilter filter
) { | 298 public List<BookmarkId> getBookmarkIDsByFilter(EnhancedBookmarkFilter filter
) { |
| 215 assert filter == EnhancedBookmarkFilter.OFFLINE_PAGES; | 299 assert filter == EnhancedBookmarkFilter.OFFLINE_PAGES; |
| 216 assert mOfflinePageBridge != null; | 300 assert mOfflinePageBridge != null; |
| 217 | 301 |
| 218 List<BookmarkId> bookmarkIds = new ArrayList<BookmarkId>(); | 302 List<BookmarkId> bookmarkIds = new ArrayList<BookmarkId>(); |
| 219 for (OfflinePageItem offlinePage : mOfflinePageBridge.getAllPages()) { | 303 for (OfflinePageItem offlinePage : mOfflinePageBridge.getAllPages()) { |
| 220 bookmarkIds.add(offlinePage.getBookmarkId()); | 304 bookmarkIds.add(offlinePage.getBookmarkId()); |
| 221 } | 305 } |
| 222 return bookmarkIds; | 306 return bookmarkIds; |
| 223 } | 307 } |
| 308 |
| 309 /** |
| 310 * @return Offline page bridge. |
| 311 */ |
| 312 public OfflinePageBridge getOfflinePageBridge() { |
| 313 return mOfflinePageBridge; |
| 314 } |
| 224 } | 315 } |
| OLD | NEW |