| Index: chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.java
|
| index 8d7a6cfb6bb1bd8bf75d35dd64ebc659a464c2c8..c62c332962cb118df83993ea3e52bc6ab439ad4b 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.java
|
| @@ -4,24 +4,36 @@
|
|
|
| package org.chromium.chrome.browser.enhancedbookmarks;
|
|
|
| +import android.annotation.TargetApi;
|
| import android.app.Activity;
|
| +import android.app.ActivityOptions;
|
| +import android.content.Intent;
|
| +import android.os.Build;
|
| import android.preference.PreferenceManager;
|
| import android.support.v4.widget.DrawerLayout;
|
| import android.util.Log;
|
| import android.view.Gravity;
|
| import android.view.View;
|
| import android.view.ViewGroup;
|
| +import android.widget.ViewSwitcher;
|
| +
|
| +import com.google.android.apps.chrome.R;
|
|
|
| import org.chromium.base.ObserverList;
|
| import org.chromium.base.metrics.RecordHistogram;
|
| -import org.chromium.chrome.R;
|
| import org.chromium.chrome.browser.BookmarksBridge.BookmarkItem;
|
| import org.chromium.chrome.browser.BookmarksBridge.BookmarkModelObserver;
|
| import org.chromium.chrome.browser.UrlConstants;
|
| +import org.chromium.chrome.browser.enhanced_bookmarks.EnhancedBookmarksBridge;
|
| +import org.chromium.chrome.browser.enhanced_bookmarks.EnhancedBookmarksBridge.FiltersObserver;
|
| +import org.chromium.chrome.browser.enhanced_bookmarks.EnhancedBookmarksModel;
|
| +import org.chromium.chrome.browser.enhanced_bookmarks.LaunchLocation;
|
| +import org.chromium.chrome.browser.enhanced_bookmarks.ViewMode;
|
| import org.chromium.chrome.browser.ntp.NewTabPageUma;
|
| import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
|
| import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarManageable;
|
| import org.chromium.components.bookmarks.BookmarkId;
|
| +import org.chromium.ui.base.DeviceFormFactor;
|
|
|
| import java.io.UnsupportedEncodingException;
|
| import java.net.URLDecoder;
|
| @@ -39,6 +51,7 @@ import java.util.Stack;
|
| */
|
| public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| private static final String PREF_LAST_USED_URL = "enhanced_bookmark_last_used_url";
|
| + static final String PREF_WAS_IN_LIST_MODE = "enhanced_bookmark_list_mode_choice";
|
|
|
| private Activity mActivity;
|
| private ViewGroup mMainView;
|
| @@ -47,8 +60,11 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| private final ObserverList<EnhancedBookmarkUIObserver> mUIObservers =
|
| new ObserverList<EnhancedBookmarkUIObserver>();
|
| private Set<BookmarkId> mSelectedBookmarks = new HashSet<>();
|
| + private boolean mListModeEnabled;
|
| private EnhancedBookmarkStateChangeListener mUrlChangeListener;
|
| private EnhancedBookmarkContentView mContentView;
|
| + private EnhancedBookmarkSearchView mSearchView;
|
| + private ViewSwitcher mViewSwitcher;
|
| private DrawerLayout mDrawer;
|
| private EnhancedBookmarkDrawerListView mDrawerListView;
|
| private final Stack<UIState> mStateStack = new Stack<>();
|
| @@ -58,7 +74,7 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| public void bookmarkNodeRemoved(BookmarkItem parent, int oldIndex, BookmarkItem node) {
|
| // If the folder is removed in folder mode, show the parent folder or falls back to all
|
| // bookmarks mode.
|
| - if (getCurrentState() == UIState.STATE_FOLDER
|
| + if (getCurrentState() == STATE_FOLDER
|
| && node.getId().equals(mStateStack.peek().mFolder)) {
|
| if (mEnhancedBookmarksModel.getTopLevelFolderIDs(true, true).contains(
|
| node.getId())) {
|
| @@ -85,13 +101,24 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| public void bookmarkModelChanged() {
|
| // If the folder no longer exists in folder mode, we need to fall back. Relying on the
|
| // default behavior by setting the folder mode again.
|
| - if (getCurrentState() == UIState.STATE_FOLDER) {
|
| + if (getCurrentState() == STATE_FOLDER) {
|
| setState(mStateStack.peek());
|
| }
|
| clearSelection();
|
| }
|
| };
|
|
|
| + private final FiltersObserver mFiltersObserver = new FiltersObserver() {
|
| + @Override
|
| + public void onFiltersChanged() {
|
| + // if the current selected filter was removed, we need to fall back. Relying on the
|
| + // default behavior by setting the filter mode again.
|
| + if (getCurrentState() == STATE_FILTER) {
|
| + setState(mStateStack.peek());
|
| + }
|
| + }
|
| + };
|
| +
|
| /**
|
| * Creates an instance of {@link EnhancedBookmarkManager}. It also initializes resources,
|
| * bookmark models and jni bridges.
|
| @@ -105,9 +132,11 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| mDrawerListView = (EnhancedBookmarkDrawerListView) mMainView.findViewById(
|
| R.id.eb_drawer_list);
|
| mContentView = (EnhancedBookmarkContentView) mMainView.findViewById(R.id.eb_content_view);
|
| + mViewSwitcher = (ViewSwitcher) mMainView.findViewById(R.id.eb_view_switcher);
|
| mUndoController = new EnhancedBookmarkUndoController(activity, mEnhancedBookmarksModel,
|
| ((SnackbarManageable) activity).getSnackbarManager());
|
| - mEnhancedBookmarksModel.addObserver(mBookmarkModelObserver);
|
| + mSearchView = (EnhancedBookmarkSearchView) getView().findViewById(R.id.eb_search_view);
|
| + mEnhancedBookmarksModel.addModelObserver(mBookmarkModelObserver);
|
| initializeIfBookmarkModelLoaded();
|
|
|
| // Load partner bookmarks explicitly. We load partner bookmarks in the deferred startup
|
| @@ -129,7 +158,8 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| mUndoController.destroy();
|
| mUndoController = null;
|
| }
|
| - mEnhancedBookmarksModel.removeObserver(mBookmarkModelObserver);
|
| + mEnhancedBookmarksModel.removeModelObserver(mBookmarkModelObserver);
|
| + mEnhancedBookmarksModel.removeFiltersObserver(mFiltersObserver);
|
| mEnhancedBookmarksModel.destroy();
|
| mEnhancedBookmarksModel = null;
|
| }
|
| @@ -207,20 +237,24 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| */
|
| private void initializeIfBookmarkModelLoaded() {
|
| if (mEnhancedBookmarksModel.isBookmarkModelLoaded()) {
|
| + mEnhancedBookmarksModel.addFiltersObserver(mFiltersObserver);
|
| + mSearchView.onEnhancedBookmarkDelegateInitialized(this);
|
| mDrawerListView.onEnhancedBookmarkDelegateInitialized(this);
|
| mContentView.onEnhancedBookmarkDelegateInitialized(this);
|
| if (mStateStack.isEmpty()) {
|
| setState(UIState.createStateFromUrl(getUrlFromPreference(),
|
| mEnhancedBookmarksModel));
|
| - } else if (mStateStack.peek().mState == UIState.STATE_LOADING) {
|
| + } else if (mStateStack.peek().mState == STATE_LOADING) {
|
| String url = mStateStack.pop().mUrl;
|
| setState(UIState.createStateFromUrl(url, mEnhancedBookmarksModel));
|
| }
|
| + // Restore the previous view mode selection saved in preference.
|
| + initListModeOptionTo(getListModePreference());
|
| } else {
|
| mContentView.showLoadingUi();
|
| mDrawerListView.showLoadingUi();
|
| mContentView.showLoadingUi();
|
| - if (mStateStack.isEmpty() || mStateStack.peek().mState != UIState.STATE_LOADING) {
|
| + if (mStateStack.isEmpty() || mStateStack.peek().mState != STATE_LOADING) {
|
| setState(UIState.createLoadingState(getUrlFromPreference()));
|
| } else if (!mStateStack.isEmpty()) {
|
| // Refresh the UI. This is needed because on tablet, updateForUrl might set up
|
| @@ -250,6 +284,34 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| PREF_LAST_USED_URL, UrlConstants.BOOKMARKS_URL);
|
| }
|
|
|
| + private void saveListModePreference() {
|
| + PreferenceManager.getDefaultSharedPreferences(mActivity).edit()
|
| + .putInt(PREF_WAS_IN_LIST_MODE, mListModeEnabled ? ViewMode.LIST : ViewMode.GRID)
|
| + .apply();
|
| + }
|
| +
|
| + private boolean getListModePreference() {
|
| + int mode = PreferenceManager.getDefaultSharedPreferences(mActivity).getInt(
|
| + PREF_WAS_IN_LIST_MODE, ViewMode.DEFAULT);
|
| +
|
| + if (mode == ViewMode.DEFAULT) mode = EnhancedBookmarksBridge.getDefaultViewMode();
|
| +
|
| + return mode == ViewMode.LIST ? true : false;
|
| + }
|
| +
|
| + private void initListModeOptionTo(boolean isListModeEnabled) {
|
| + mListModeEnabled = isListModeEnabled;
|
| + for (EnhancedBookmarkUIObserver observer: mUIObservers) {
|
| + observer.onListModeChange(isListModeEnabled);
|
| + }
|
| + // Every time the enhanced bookmark manager launches or the user clicks the list-mode
|
| + // toggle, we record the list view state.
|
| + int listViewstate = PreferenceManager.getDefaultSharedPreferences(getView().getContext())
|
| + .getInt(EnhancedBookmarkManager.PREF_WAS_IN_LIST_MODE,
|
| + ViewMode.DEFAULT);
|
| + RecordHistogram.recordEnumeratedHistogram("EnhancedBookmarks.ViewMode", listViewstate, 3);
|
| + }
|
| +
|
| /**
|
| * This is the ultimate internal method that updates UI and controls backstack. And it is the
|
| * only method that pushes states to {@link #mStateStack}.
|
| @@ -269,12 +331,12 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| }
|
| if (!mStateStack.isEmpty()) {
|
| if (mStateStack.peek().equals(state)) return;
|
| - if (mStateStack.peek().mState == UIState.STATE_LOADING) {
|
| + if (mStateStack.peek().mState == STATE_LOADING) {
|
| mStateStack.pop();
|
| }
|
| }
|
| mStateStack.push(state);
|
| - if (state.mState != UIState.STATE_LOADING) {
|
| + if (state.mState != STATE_LOADING) {
|
| // Loading state may be pushed to the stack but should never be stored in preferences.
|
| saveUrlToPreference(state.mUrl);
|
| // If a loading state is replaced by another loading state, do not notify this change.
|
| @@ -292,11 +354,19 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
|
|
| @Override
|
| public void openFolder(BookmarkId folder) {
|
| + closeSearchUI();
|
| setState(UIState.createFolderState(folder, mEnhancedBookmarksModel));
|
| }
|
|
|
| @Override
|
| + public void openFilter(String filter) {
|
| + closeSearchUI();
|
| + setState(UIState.createFilterState(filter, mEnhancedBookmarksModel));
|
| + }
|
| +
|
| + @Override
|
| public void openAllBookmarks() {
|
| + closeSearchUI();
|
| setState(UIState.createAllBookmarksState(mEnhancedBookmarksModel));
|
| }
|
|
|
| @@ -337,16 +407,30 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| }
|
|
|
| @Override
|
| + public void setListModeEnabled(boolean isListModeEnabled) {
|
| + initListModeOptionTo(isListModeEnabled);
|
| + saveListModePreference();
|
| + }
|
| +
|
| + @Override
|
| + public boolean isListModeEnabled() {
|
| + return mListModeEnabled;
|
| + }
|
| +
|
| + @Override
|
| public void notifyStateChange(EnhancedBookmarkUIObserver observer) {
|
| int state = getCurrentState();
|
| switch (state) {
|
| - case UIState.STATE_ALL_BOOKMARKS:
|
| + case STATE_ALL_BOOKMARKS:
|
| observer.onAllBookmarksStateSet();
|
| break;
|
| - case UIState.STATE_FOLDER:
|
| + case STATE_FOLDER:
|
| observer.onFolderStateSet(mStateStack.peek().mFolder);
|
| break;
|
| - case UIState.STATE_LOADING:
|
| + case STATE_FILTER:
|
| + observer.onFilterStateSet(mStateStack.peek().mFilter);
|
| + break;
|
| + case STATE_LOADING:
|
| // In loading state, onEnhancedBookmarkDelegateInitialized() is not called for all
|
| // UIObservers, which means that there will be no observers at the time. Do nothing.
|
| assert mUIObservers.isEmpty();
|
| @@ -375,16 +459,42 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| }
|
|
|
| @Override
|
| + @TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
| + public void startDetailActivity(BookmarkId bookmarkId, View view) {
|
| + Intent intent = new Intent(mActivity, EnhancedBookmarkDetailActivity.class);
|
| + intent.putExtra(EnhancedBookmarkDetailActivity.INTENT_BOOKMARK_ID, bookmarkId.toString());
|
| + // Shared element animation is disabled on tablet because of bad quality.
|
| + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || view == null
|
| + || DeviceFormFactor.isTablet(mActivity)) {
|
| + mActivity.startActivity(intent);
|
| + } else {
|
| + ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, view,
|
| + mActivity.getString(R.string.enhanced_bookmark_detail_transition_name));
|
| + mActivity.startActivity(intent, options.toBundle());
|
| + }
|
| + }
|
| +
|
| + @Override
|
| public void openBookmark(BookmarkId bookmark, int launchLocation) {
|
| clearSelection();
|
| - if (mEnhancedBookmarksModel.getBookmarkById(bookmark) != null) {
|
| - NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_BOOKMARK);
|
| - RecordHistogram.recordEnumeratedHistogram("Stars.LaunchLocation", launchLocation,
|
| - LaunchLocation.COUNT);
|
| - EnhancedBookmarkUtils.openBookmark(mActivity,
|
| - mEnhancedBookmarksModel.getBookmarkById(bookmark).getUrl());
|
| - finishActivityOnPhone();
|
| - }
|
| + NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_BOOKMARK);
|
| + RecordHistogram.recordEnumeratedHistogram("Stars.LaunchLocation", launchLocation,
|
| + LaunchLocation.COUNT);
|
| + EnhancedBookmarkUtils.openBookmark(mActivity,
|
| + mEnhancedBookmarksModel.getBookmarkById(bookmark).getUrl());
|
| + finishActivityOnPhone();
|
| + }
|
| +
|
| + @Override
|
| + public void openSearchUI() {
|
| + // Give search view focus, because it needs to handle back key event.
|
| + mViewSwitcher.showNext();
|
| + }
|
| +
|
| + @Override
|
| + public void closeSearchUI() {
|
| + if (mSearchView.getVisibility() != View.VISIBLE) return;
|
| + mViewSwitcher.showPrevious();
|
| }
|
|
|
| @Override
|
| @@ -412,7 +522,7 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
|
|
| @Override
|
| public int getCurrentState() {
|
| - if (mStateStack.isEmpty()) return UIState.STATE_LOADING;
|
| + if (mStateStack.isEmpty()) return STATE_LOADING;
|
| return mStateStack.peek().mState;
|
| }
|
|
|
| @@ -420,50 +530,56 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| * Internal state that represents a url. Note every state needs to have a _valid_ url. For
|
| * loading state, {@link #mUrl} indicates the target to open after the bookmark model is loaded.
|
| */
|
| - static class UIState {
|
| - private static final int STATE_INVALID = 0;
|
| - static final int STATE_LOADING = 1;
|
| - static final int STATE_ALL_BOOKMARKS = 2;
|
| - static final int STATE_FOLDER = 3;
|
| - static final int STATE_FILTER = 4;
|
| -
|
| + private static class UIState {
|
| private static final String TAG = "UIState";
|
| private static final String URL_CHARSET = "UTF-8";
|
| /**
|
| - * One of the STATE_* constants.
|
| + * One of the four states:
|
| + * {@link EnhancedBookmarkDelegate#STATE_ALL_BOOKMARKS},
|
| + * {@link EnhancedBookmarkDelegate#STATE_FILTER},
|
| + * {@link EnhancedBookmarkDelegate#STATE_FOLDER},
|
| + * {@link EnhancedBookmarkDelegate#STATE_LOADING},
|
| */
|
| - private int mState;
|
| - private String mUrl;
|
| - private BookmarkId mFolder;
|
| + int mState;
|
| + String mUrl;
|
| + BookmarkId mFolder;
|
| + String mFilter;
|
|
|
| - private static UIState createLoadingState(String url) {
|
| + static UIState createLoadingState(String url) {
|
| UIState state = new UIState();
|
| state.mUrl = url;
|
| state.mState = STATE_LOADING;
|
| return state;
|
| }
|
|
|
| - private static UIState createAllBookmarksState(EnhancedBookmarksModel bookmarkModel) {
|
| + static UIState createAllBookmarksState(EnhancedBookmarksModel bookmarkModel) {
|
| return createStateFromUrl(UrlConstants.BOOKMARKS_URL, bookmarkModel);
|
| }
|
|
|
| - private static UIState createFolderState(BookmarkId folder,
|
| - EnhancedBookmarksModel bookmarkModel) {
|
| + static UIState createFolderState(BookmarkId folder, EnhancedBookmarksModel bookmarkModel) {
|
| return createStateFromUrl(UrlConstants.BOOKMARKS_FOLDER_URL + folder.toString(),
|
| bookmarkModel);
|
| }
|
|
|
| + static UIState createFilterState(String filter, EnhancedBookmarksModel bookmarkModel) {
|
| + return createStateFromUrl(encodeUrl(UrlConstants.BOOKMARKS_FILTER_URL, filter),
|
| + bookmarkModel);
|
| + }
|
| +
|
| /**
|
| * @return A state corresponding to the url. If the url is not valid, return all_bookmarks.
|
| */
|
| - private static UIState createStateFromUrl(String url,
|
| - EnhancedBookmarksModel bookmarkModel) {
|
| + static UIState createStateFromUrl(String url, EnhancedBookmarksModel bookmarkModel) {
|
| UIState state = new UIState();
|
| - state.mState = STATE_INVALID;
|
| state.mUrl = url;
|
| -
|
| if (url.equals(UrlConstants.BOOKMARKS_URL)) {
|
| state.mState = STATE_ALL_BOOKMARKS;
|
| + } else if (url.startsWith(UrlConstants.BOOKMARKS_FILTER_URL)) {
|
| + String suffix = decodeSuffix(url, UrlConstants.BOOKMARKS_FILTER_URL);
|
| + if (!suffix.isEmpty()) {
|
| + state.mState = STATE_FILTER;
|
| + state.mFilter = suffix;
|
| + }
|
| } else if (url.startsWith(UrlConstants.BOOKMARKS_FOLDER_URL)) {
|
| String suffix = decodeSuffix(url, UrlConstants.BOOKMARKS_FOLDER_URL);
|
| if (!suffix.isEmpty()) {
|
| @@ -480,26 +596,26 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| return state;
|
| }
|
|
|
| - private UIState() {
|
| - }
|
| -
|
| /**
|
| * @return Whether this state is valid.
|
| */
|
| - private boolean isValid(EnhancedBookmarksModel bookmarkModel) {
|
| - if (mUrl == null || mState == STATE_INVALID) return false;
|
| -
|
| + boolean isValid(EnhancedBookmarksModel bookmarkModel) {
|
| + if (mUrl == null) return false;
|
| if (mState == STATE_FOLDER) {
|
| if (mFolder == null) return false;
|
|
|
| return bookmarkModel.doesBookmarkExist(mFolder)
|
| && !mFolder.equals(bookmarkModel.getRootFolderId());
|
| }
|
| + if (mState == STATE_FILTER) {
|
| + if (mFilter == null) return false;
|
| + else return bookmarkModel.getFilters().contains(mFilter);
|
| + }
|
|
|
| return true;
|
| }
|
|
|
| - private static String decodeSuffix(String url, String prefix) {
|
| + static String decodeSuffix(String url, String prefix) {
|
| String suffix = url.substring(prefix.length());
|
| try {
|
| suffix = URLDecoder.decode(suffix, URL_CHARSET);
|
| @@ -509,7 +625,7 @@ public class EnhancedBookmarkManager implements EnhancedBookmarkDelegate {
|
| return suffix;
|
| }
|
|
|
| - private static String encodeUrl(String prefix, String suffix) {
|
| + static String encodeUrl(String prefix, String suffix) {
|
| try {
|
| suffix = URLEncoder.encode(suffix, URL_CHARSET);
|
| } catch (UnsupportedEncodingException e) {
|
|
|