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

Side by Side Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.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.enhancedbookmarks;
6
7 import android.annotation.TargetApi;
8 import android.app.Activity;
9 import android.app.ActivityOptions;
10 import android.content.Intent;
11 import android.os.Build;
12 import android.preference.PreferenceManager;
13 import android.support.v4.widget.DrawerLayout;
14 import android.util.Log;
15 import android.view.Gravity;
16 import android.view.View;
17 import android.view.ViewGroup;
18 import android.widget.ViewSwitcher;
19
20 import com.google.android.apps.chrome.R;
21
22 import org.chromium.base.ObserverList;
23 import org.chromium.base.metrics.RecordHistogram;
24 import org.chromium.chrome.browser.BookmarksBridge.BookmarkItem;
25 import org.chromium.chrome.browser.BookmarksBridge.BookmarkModelObserver;
26 import org.chromium.chrome.browser.UrlConstants;
27 import org.chromium.chrome.browser.enhanced_bookmarks.EnhancedBookmarksBridge.Fi ltersObserver;
28 import org.chromium.chrome.browser.enhanced_bookmarks.EnhancedBookmarksModel;
29 import org.chromium.chrome.browser.enhanced_bookmarks.LaunchLocation;
30 import org.chromium.chrome.browser.ntp.NewTabPageUma;
31 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
32 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarManageable;
33 import org.chromium.components.bookmarks.BookmarkId;
34 import org.chromium.ui.base.DeviceFormFactor;
35
36 import java.io.UnsupportedEncodingException;
37 import java.net.URLDecoder;
38 import java.net.URLEncoder;
39 import java.util.ArrayList;
40 import java.util.HashSet;
41 import java.util.List;
42 import java.util.Set;
43 import java.util.Stack;
44
45 /**
46 * The new bookmark manager that is planned to replace the existing bookmark man ager. It holds all
47 * views and shared logics between tablet and phone. For tablet/phone specific l ogics, see
48 * {@link EnhancedBookmarkActivity} (phone) and {@link EnhancedBookmarkPage} (ta blet).
49 */
50 public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
51 private static final String PREF_LAST_USED_URL = "enhanced_bookmark_last_use d_url";
52 static final String PREF_WAS_IN_LIST_MODE = "enhanced_bookmark_list_mode_cho ice";
53 // TODO(ianwen): upstream these metrics upstream.
54 // UI modes for bookmarks presentation. Default option is grid mode.
55 static final int DEFAULT_MODE = 0;
56 static final int LIST_MODE = 1;
57 static final int GRID_MODE = 2;
58
59 private Activity mActivity;
60 private ViewGroup mMainView;
61 private EnhancedBookmarksModel mEnhancedBookmarksModel;
62 private EnhancedBookmarkUndoController mUndoController;
63 private final ObserverList<EnhancedBookmarkUIObserver> mUIObservers =
64 new ObserverList<EnhancedBookmarkUIObserver>();
65 private Set<BookmarkId> mSelectedBookmarks = new HashSet<>();
66 private boolean mListModeEnabled;
67 private EnhancedBookmarkStateChangeListener mUrlChangeListener;
68 private EnhancedBookmarkContentView mContentView;
69 private EnhancedBookmarkSearchView mSearchView;
70 private ViewSwitcher mViewSwitcher;
71 private DrawerLayout mDrawer;
72 private EnhancedBookmarkDrawerListView mDrawerListView;
73 private final Stack<UIState> mStateStack = new Stack<>();
74
75 private final BookmarkModelObserver mBookmarkModelObserver = new BookmarkMod elObserver() {
76 @Override
77 public void bookmarkNodeRemoved(BookmarkItem parent, int oldIndex, Bookm arkItem node) {
78 // If the folder is removed in folder mode, show the parent folder o r falls back to all
79 // bookmarks mode.
80 if (getCurrentState() == STATE_FOLDER
81 && node.getId().equals(mStateStack.peek().mFolder)) {
82 if (mEnhancedBookmarksModel.getTopLevelFolderIDs(true, true).con tains(
83 node.getId())) {
84 openAllBookmarks();
85 } else {
86 openFolder(parent.getId());
87 }
88 }
89 clearSelection();
90 }
91
92 @Override
93 public void bookmarkNodeMoved(BookmarkItem oldParent, int oldIndex, Book markItem newParent,
94 int newIndex) {
95 clearSelection();
96 }
97
98 @Override
99 public void bookmarkModelLoaded() {
100 initializeIfBookmarkModelLoaded();
101 }
102
103 @Override
104 public void bookmarkModelChanged() {
105 // If the folder no longer exists in folder mode, we need to fall ba ck. Relying on the
106 // default behavior by setting the folder mode again.
107 if (getCurrentState() == STATE_FOLDER) {
108 setState(mStateStack.peek());
109 }
110 clearSelection();
111 }
112 };
113
114 private final FiltersObserver mFiltersObserver = new FiltersObserver() {
115 @Override
116 public void onFiltersChanged() {
117 // if the current selected filter was removed, we need to fall back. Relying on the
118 // default behavior by setting the filter mode again.
119 if (getCurrentState() == STATE_FILTER) {
120 setState(mStateStack.peek());
121 }
122 }
123 };
124
125 /**
126 * Creates an instance of {@link EnhancedBookmarkManager}. It also initializ es resources,
127 * bookmark models and jni bridges.
128 * @param activity The activity context to use.
129 */
130 public EnhancedBookmarkManager(Activity activity) {
131 mActivity = activity;
132 mEnhancedBookmarksModel = new EnhancedBookmarksModel();
133 mMainView = (ViewGroup) mActivity.getLayoutInflater().inflate(R.layout.e b_main, null);
134 mDrawer = (DrawerLayout) mMainView.findViewById(R.id.eb_drawer_layout);
135 mDrawerListView = (EnhancedBookmarkDrawerListView) mMainView.findViewByI d(
136 R.id.eb_drawer_list);
137 mContentView = (EnhancedBookmarkContentView) mMainView.findViewById(R.id .eb_content_view);
138 mViewSwitcher = (ViewSwitcher) mMainView.findViewById(R.id.eb_view_switc her);
139 mUndoController = new EnhancedBookmarkUndoController(activity, mEnhanced BookmarksModel,
140 ((SnackbarManageable) activity).getSnackbarManager());
141 mSearchView = (EnhancedBookmarkSearchView) getView().findViewById(R.id.e b_search_view);
142 mEnhancedBookmarksModel.addModelObserver(mBookmarkModelObserver);
143 initializeIfBookmarkModelLoaded();
144
145 // Load partner bookmarks explicitly. We load partner bookmarks in the d eferred startup
146 // code, but that might be executed much later. Especially on L, showing loading
147 // progress bar blocks that so it won't be loaded. http://crbug.com/4293 83
148 PartnerBookmarksShim.kickOffReading(activity);
149 }
150
151 /**
152 * Destroys and cleans up itself. This must be called after done using this class.
153 */
154 public void destroy() {
155 for (EnhancedBookmarkUIObserver observer : mUIObservers) {
156 observer.onDestroy();
157 }
158 assert mUIObservers.size() == 0;
159
160 if (mUndoController != null) {
161 mUndoController.destroy();
162 mUndoController = null;
163 }
164 mEnhancedBookmarksModel.removeModelObserver(mBookmarkModelObserver);
165 mEnhancedBookmarksModel.removeFiltersObserver(mFiltersObserver);
166 mEnhancedBookmarksModel.destroy();
167 mEnhancedBookmarksModel = null;
168 }
169
170 /**
171 * Called when the user presses the back key. This is only going to be calle d on Phone.
172 * @return True if manager handles this event, false if it decides to ignore .
173 */
174 public boolean onBackPressed() {
175 if (doesDrawerExist()) {
176 if (mDrawer.isDrawerVisible(Gravity.START)) {
177 mDrawer.closeDrawer(Gravity.START);
178 return true;
179 }
180 }
181
182 if (mContentView.onBackPressed()) return true;
183
184 if (!mStateStack.empty()) {
185 mStateStack.pop();
186 if (!mStateStack.empty()) {
187 setState(mStateStack.pop());
188 return true;
189 }
190 }
191 return false;
192 }
193
194 public View getView() {
195 return mMainView;
196 }
197
198 /**
199 * Sets the listener that reacts upon the change of the UI state of bookmark manager.
200 */
201 public void setUrlChangeListener(EnhancedBookmarkStateChangeListener urlList ner) {
202 mUrlChangeListener = urlListner;
203 }
204
205 /**
206 * @return Current URL representing the UI state of bookmark manager. If no state has been shown
207 * yet in this session, on phone return last used state stored in pr eference; on tablet
208 * return the url previously set by {@link #updateForUrl(String)}.
209 */
210 public String getCurrentUrl() {
211 if (mStateStack.isEmpty()) return null;
212 return mStateStack.peek().mUrl;
213 }
214
215 /**
216 * Updates UI based on the new URL on tablet. If the bookmark model is not l oaded yet, creates a
217 * temporary loading state carrying this url. This method is supposed to ali gn with
218 * {@link EnhancedBookmarkPage#updateForUrl(String)}
219 * <p>
220 * @param url The url to navigate to.
221 */
222 public void updateForUrl(String url) {
223 if (mEnhancedBookmarksModel != null && mEnhancedBookmarksModel.isBookmar kModelLoaded()) {
224 setState(UIState.createStateFromUrl(url, mEnhancedBookmarksModel));
225 } else {
226 // Note this does not guarantee to update the UI, as at this time th e onCreateView()
227 // might not has even been called yet.
228 setState(UIState.createLoadingState(url));
229 }
230 }
231
232 /**
233 * Initialization method that has 3 different behaviors based on whether boo kmark model is
234 * loaded. If the bookmark model is not loaded yet, it pushes a loading stat e to backstack which
235 * contains the url from preference. If the model is loaded and the backstac k is empty, it
236 * creates a state by fetching the last visited bookmark url stored in prefe rence. If the
237 * bookmark model is loaded but backstack contains a pending loading state, it creates a new
238 * state by getting the url of the loading state and replace the previous lo ading state with the
239 * new normal state.
240 */
241 private void initializeIfBookmarkModelLoaded() {
242 if (mEnhancedBookmarksModel.isBookmarkModelLoaded()) {
243 mEnhancedBookmarksModel.addFiltersObserver(mFiltersObserver);
244 mSearchView.onEnhancedBookmarkDelegateInitialized(this);
245 mDrawerListView.onEnhancedBookmarkDelegateInitialized(this);
246 mContentView.onEnhancedBookmarkDelegateInitialized(this);
247 if (mStateStack.isEmpty()) {
248 setState(UIState.createStateFromUrl(getUrlFromPreference(),
249 mEnhancedBookmarksModel));
250 } else if (mStateStack.peek().mState == STATE_LOADING) {
251 String url = mStateStack.pop().mUrl;
252 setState(UIState.createStateFromUrl(url, mEnhancedBookmarksModel ));
253 }
254 // Restore the previous view mode selection saved in preference.
255 initListModeOptionTo(getListModePreference());
256 } else {
257 mContentView.showLoadingUi();
258 mDrawerListView.showLoadingUi();
259 mContentView.showLoadingUi();
260 if (mStateStack.isEmpty() || mStateStack.peek().mState != STATE_LOAD ING) {
261 setState(UIState.createLoadingState(getUrlFromPreference()));
262 } else if (!mStateStack.isEmpty()) {
263 // Refresh the UI. This is needed because on tablet, updateForUr l might set up
264 // loading state too early and at that time all UI components ar e not created yet.
265 // Therefore we need to set the previous loading state once agai n to trigger all UI
266 // updates.
267 setState(mStateStack.pop());
268 }
269 }
270 }
271
272 /**
273 * Saves url to preference. Note this method should be used after the main v iew is attached to
274 * an activity.
275 */
276 private void saveUrlToPreference(String url) {
277 PreferenceManager.getDefaultSharedPreferences(mActivity).edit()
278 .putString(PREF_LAST_USED_URL, url).apply();
279 }
280
281 /**
282 * Fetches url to preference. Note this method should be used after the main view is attached to
283 * an activity.
284 */
285 private String getUrlFromPreference() {
286 return PreferenceManager.getDefaultSharedPreferences(mActivity).getStrin g(
287 PREF_LAST_USED_URL, UrlConstants.BOOKMARKS_URL);
288 }
289
290 private void saveListModePreference() {
291 PreferenceManager.getDefaultSharedPreferences(mActivity).edit()
292 .putInt(PREF_WAS_IN_LIST_MODE, mListModeEnabled ? LIST_MODE : GR ID_MODE).apply();
293 }
294
295 private boolean getListModePreference() {
296 int mode = PreferenceManager.getDefaultSharedPreferences(mActivity).getI nt(
297 PREF_WAS_IN_LIST_MODE, DEFAULT_MODE);
298 return mode == LIST_MODE ? true : false;
299 }
300
301 private void initListModeOptionTo(boolean isListModeEnabled) {
302 mListModeEnabled = isListModeEnabled;
303 for (EnhancedBookmarkUIObserver observer: mUIObservers) {
304 observer.onListModeChange(isListModeEnabled);
305 }
306 // Every time the enhanced bookmark manager launches or the user clicks the list-mode
307 // toggle, we record the list view state.
308 int listViewstate = PreferenceManager.getDefaultSharedPreferences(getVie w().getContext())
309 .getInt(EnhancedBookmarkManager.PREF_WAS_IN_LIST_MODE,
310 EnhancedBookmarkManager.DEFAULT_MODE);
311 RecordHistogram.recordEnumeratedHistogram("EnhancedBookmarks.ViewMode", listViewstate, 3);
312 }
313
314 /**
315 * This is the ultimate internal method that updates UI and controls backsta ck. And it is the
316 * only method that pushes states to {@link #mStateStack}.
317 * <p>
318 * If the given state is not valid, all_bookmark state will be shown. Afterw ards, this method
319 * checks the current state: if currently in loading state, it pops it out a nd adds the new
320 * state to the back stack. It also notifies the {@link #mUrlChangeListener} (if any) that the
321 * url has changed.
322 * <p>
323 * Also note that even if we store states to {@link #mStateStack}, on tablet the back navigation
324 * and back button are not controlled by the manager: the tab handles back k ey and backstack
325 * navigation.
326 */
327 private void setState(UIState state) {
328 if (!state.isValid(mEnhancedBookmarksModel)) {
329 state = UIState.createAllBookmarksState(mEnhancedBookmarksModel);
330 }
331 if (!mStateStack.isEmpty()) {
332 if (mStateStack.peek().equals(state)) return;
333 if (mStateStack.peek().mState == STATE_LOADING) {
334 mStateStack.pop();
335 }
336 }
337 mStateStack.push(state);
338 if (state.mState != STATE_LOADING) {
339 // Loading state may be pushed to the stack but should never be stor ed in preferences.
340 saveUrlToPreference(state.mUrl);
341 // If a loading state is replaced by another loading state, do not n otify this change.
342 if (mUrlChangeListener != null) mUrlChangeListener.onBookmarkUIState Change(state.mUrl);
343 }
344
345 clearSelection();
346
347 for (EnhancedBookmarkUIObserver observer : mUIObservers) {
348 notifyStateChange(observer);
349 }
350 }
351
352 // EnhancedBookmarkDelegate implementations.
353
354 @Override
355 public void openFolder(BookmarkId folder) {
356 closeSearchUI();
357 setState(UIState.createFolderState(folder, mEnhancedBookmarksModel));
358 }
359
360 @Override
361 public void openFilter(String filter) {
362 closeSearchUI();
363 setState(UIState.createFilterState(filter, mEnhancedBookmarksModel));
364 }
365
366 @Override
367 public void openAllBookmarks() {
368 closeSearchUI();
369 setState(UIState.createAllBookmarksState(mEnhancedBookmarksModel));
370 }
371
372 @Override
373 public void clearSelection() {
374 mSelectedBookmarks.clear();
375 for (EnhancedBookmarkUIObserver observer : mUIObservers) {
376 observer.onSelectionStateChange(new ArrayList<BookmarkId>(mSelectedB ookmarks));
377 }
378 }
379
380 @Override
381 public boolean toggleSelectionForBookmark(BookmarkId bookmark) {
382 if (!mEnhancedBookmarksModel.getBookmarkById(bookmark).isEditable()) ret urn false;
383
384 if (mSelectedBookmarks.contains(bookmark)) mSelectedBookmarks.remove(boo kmark);
385 else mSelectedBookmarks.add(bookmark);
386 for (EnhancedBookmarkUIObserver observer : mUIObservers) {
387 observer.onSelectionStateChange(new ArrayList<BookmarkId>(mSelectedB ookmarks));
388 }
389
390 return isBookmarkSelected(bookmark);
391 }
392
393 @Override
394 public boolean isBookmarkSelected(BookmarkId bookmark) {
395 return mSelectedBookmarks.contains(bookmark);
396 }
397
398 @Override
399 public boolean isSelectionEnabled() {
400 return !mSelectedBookmarks.isEmpty();
401 }
402
403 @Override
404 public List<BookmarkId> getSelectedBookmarks() {
405 return new ArrayList<BookmarkId>(mSelectedBookmarks);
406 }
407
408 @Override
409 public void setListModeEnabled(boolean isListModeEnabled) {
410 initListModeOptionTo(isListModeEnabled);
411 saveListModePreference();
412 }
413
414 @Override
415 public boolean isListModeEnabled() {
416 return mListModeEnabled;
417 }
418
419 @Override
420 public void notifyStateChange(EnhancedBookmarkUIObserver observer) {
421 int state = getCurrentState();
422 switch (state) {
423 case STATE_ALL_BOOKMARKS:
424 observer.onAllBookmarksStateSet();
425 break;
426 case STATE_FOLDER:
427 observer.onFolderStateSet(mStateStack.peek().mFolder);
428 break;
429 case STATE_FILTER:
430 observer.onFilterStateSet(mStateStack.peek().mFilter);
431 break;
432 case STATE_LOADING:
433 // In loading state, onEnhancedBookmarkDelegateInitialized() is not called for all
434 // UIObservers, which means that there will be no observers at t he time. Do nothing.
435 assert mUIObservers.isEmpty();
436 break;
437 default:
438 assert false : "State not valid";
439 break;
440 }
441 }
442
443 @Override
444 public boolean doesDrawerExist() {
445 return mDrawer != null;
446 }
447
448 @Override
449 public void closeDrawer() {
450 if (!doesDrawerExist()) return;
451
452 mDrawer.closeDrawer(Gravity.START);
453 }
454
455 @Override
456 public DrawerLayout getDrawerLayout() {
457 return mDrawer;
458 }
459
460 @Override
461 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
462 public void startDetailActivity(BookmarkId bookmarkId, View view) {
463 Intent intent = new Intent(mActivity, EnhancedBookmarkDetailActivity.cla ss);
464 intent.putExtra(EnhancedBookmarkDetailActivity.INTENT_BOOKMARK_ID, bookm arkId.toString());
465 // Shared element animation is disabled on tablet because of bad quality .
466 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || view == null
467 || DeviceFormFactor.isTablet(mActivity)) {
468 mActivity.startActivity(intent);
469 } else {
470 ActivityOptions options = ActivityOptions.makeSceneTransitionAnimati on(mActivity, view,
471 mActivity.getString(R.string.enhanced_bookmark_detail_transi tion_name));
472 mActivity.startActivity(intent, options.toBundle());
473 }
474 }
475
476 @Override
477 public void openBookmark(BookmarkId bookmark, int launchLocation) {
478 clearSelection();
479 NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_BOOKMARK);
480 RecordHistogram.recordEnumeratedHistogram("Stars.LaunchLocation", launch Location,
481 LaunchLocation.COUNT);
482 EnhancedBookmarkUtils.openBookmark(mActivity,
483 mEnhancedBookmarksModel.getBookmarkById(bookmark).getUrl());
484 finishActivityOnPhone();
485 }
486
487 @Override
488 public void openSearchUI() {
489 // Give search view focus, because it needs to handle back key event.
490 mViewSwitcher.showNext();
491 }
492
493 @Override
494 public void closeSearchUI() {
495 if (mSearchView.getVisibility() != View.VISIBLE) return;
496 mViewSwitcher.showPrevious();
497 }
498
499 @Override
500 public void finishActivityOnPhone() {
501 Activity activity = mActivity;
502 if (activity instanceof EnhancedBookmarkActivity) {
503 activity.finish();
504 }
505 }
506
507 @Override
508 public void addUIObserver(EnhancedBookmarkUIObserver observer) {
509 mUIObservers.addObserver(observer);
510 }
511
512 @Override
513 public void removeUIObserver(EnhancedBookmarkUIObserver observer) {
514 mUIObservers.removeObserver(observer);
515 }
516
517 @Override
518 public EnhancedBookmarksModel getModel() {
519 return mEnhancedBookmarksModel;
520 }
521
522 @Override
523 public int getCurrentState() {
524 if (mStateStack.isEmpty()) return STATE_LOADING;
525 return mStateStack.peek().mState;
526 }
527
528 /**
529 * Internal state that represents a url. Note every state needs to have a _v alid_ url. For
530 * loading state, {@link #mUrl} indicates the target to open after the bookm ark model is loaded.
531 */
532 private static class UIState {
533 private static final String TAG = "UIState";
534 private static final String URL_CHARSET = "UTF-8";
535 /**
536 * One of the four states:
537 * {@link EnhancedBookmarkDelegate#STATE_ALL_BOOKMARKS},
538 * {@link EnhancedBookmarkDelegate#STATE_FILTER},
539 * {@link EnhancedBookmarkDelegate#STATE_FOLDER},
540 * {@link EnhancedBookmarkDelegate#STATE_LOADING},
541 */
542 int mState;
543 String mUrl;
544 BookmarkId mFolder;
545 String mFilter;
546
547 static UIState createLoadingState(String url) {
548 UIState state = new UIState();
549 state.mUrl = url;
550 state.mState = STATE_LOADING;
551 return state;
552 }
553
554 static UIState createAllBookmarksState(EnhancedBookmarksModel bookmarkMo del) {
555 return createStateFromUrl(UrlConstants.BOOKMARKS_URL, bookmarkModel) ;
556 }
557
558 static UIState createFolderState(BookmarkId folder, EnhancedBookmarksMod el bookmarkModel) {
559 return createStateFromUrl(UrlConstants.BOOKMARKS_FOLDER_URL + folder .toString(),
560 bookmarkModel);
561 }
562
563 static UIState createFilterState(String filter, EnhancedBookmarksModel b ookmarkModel) {
564 return createStateFromUrl(encodeUrl(UrlConstants.BOOKMARKS_FILTER_UR L, filter),
565 bookmarkModel);
566 }
567
568 /**
569 * @return A state corresponding to the url. If the url is not valid, re turn all_bookmarks.
570 */
571 static UIState createStateFromUrl(String url, EnhancedBookmarksModel boo kmarkModel) {
572 UIState state = new UIState();
573 state.mUrl = url;
574 if (url.equals(UrlConstants.BOOKMARKS_URL)) {
575 state.mState = STATE_ALL_BOOKMARKS;
576 } else if (url.startsWith(UrlConstants.BOOKMARKS_FILTER_URL)) {
577 String suffix = decodeSuffix(url, UrlConstants.BOOKMARKS_FILTER_ URL);
578 if (!suffix.isEmpty()) {
579 state.mState = STATE_FILTER;
580 state.mFilter = suffix;
581 }
582 } else if (url.startsWith(UrlConstants.BOOKMARKS_FOLDER_URL)) {
583 String suffix = decodeSuffix(url, UrlConstants.BOOKMARKS_FOLDER_ URL);
584 if (!suffix.isEmpty()) {
585 state.mFolder = BookmarkId.getBookmarkIdFromString(suffix);
586 state.mState = STATE_FOLDER;
587 }
588 }
589
590 if (!state.isValid(bookmarkModel)) {
591 state.mState = STATE_ALL_BOOKMARKS;
592 state.mUrl = UrlConstants.BOOKMARKS_URL;
593 }
594
595 return state;
596 }
597
598 /**
599 * @return Whether this state is valid.
600 */
601 boolean isValid(EnhancedBookmarksModel bookmarkModel) {
602 if (mUrl == null) return false;
603 if (mState == STATE_FOLDER) {
604 if (mFolder == null) return false;
605
606 return bookmarkModel.doesBookmarkExist(mFolder)
607 && !mFolder.equals(bookmarkModel.getRootFolderId());
608 }
609 if (mState == STATE_FILTER) {
610 if (mFilter == null) return false;
611 else return bookmarkModel.getFilters().contains(mFilter);
612 }
613
614 return true;
615 }
616
617 static String decodeSuffix(String url, String prefix) {
618 String suffix = url.substring(prefix.length());
619 try {
620 suffix = URLDecoder.decode(suffix, URL_CHARSET);
621 } catch (UnsupportedEncodingException e) {
622 Log.w(TAG, "Bookmark URL parsing failed. " + URL_CHARSET + " not supported.");
623 }
624 return suffix;
625 }
626
627 static String encodeUrl(String prefix, String suffix) {
628 try {
629 suffix = URLEncoder.encode(suffix, URL_CHARSET);
630 } catch (UnsupportedEncodingException e) {
631 Log.w(TAG, "Bookmark URL parsing failed. " + URL_CHARSET + " not supported.");
632 }
633 return prefix + suffix;
634 }
635
636 @Override
637 public int hashCode() {
638 return 31 * mUrl.hashCode() + mState;
639 }
640
641 @Override
642 public boolean equals(Object obj) {
643 if (!(obj instanceof UIState)) return false;
644 UIState other = (UIState) obj;
645 return mState == other.mState && mUrl.equals(other.mUrl);
646 }
647 }
648 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698