Commit f4786b70 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Read later: Introduce BookmarkListEntry.

BookmarkItemsAdapter currently uses the backend data class BookmarkItem
as its data object. This is not flexible to add decorative or non
bookmark ViewHolders to its recycler view.

Also the sync promo header uses null to identify itself to the recycler
view, which is kind of hacky, and UI logic assumes null is the place
holder for sync promo header.

This CL introduces BookmarkListEntry, which can represent any kind of
ViewHolders, and carries different kind of data objects. Sync promo
header also has a BookmarkListEntry object.

Bug: 1128074
Change-Id: Id11c0164eb06cf3a59b35eb6cad7e33e4f9d19f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2461724
Commit-Queue: Xing Liu <xingliu@chromium.org>
Reviewed-by: default avatarBrandon Wylie <wylieb@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816421}
parent d5f8ffec
......@@ -156,6 +156,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java",
......
......@@ -10,7 +10,6 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ViewGroup;
import androidx.annotation.IntDef;
import androidx.annotation.LayoutRes;
import androidx.annotation.VisibleForTesting;
import androidx.recyclerview.widget.RecyclerView;
......@@ -20,6 +19,7 @@ import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
import org.chromium.chrome.browser.bookmarks.BookmarkListEntry.ViewType;
import org.chromium.chrome.browser.bookmarks.BookmarkRow.Location;
import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
import org.chromium.chrome.browser.sync.ProfileSyncService;
......@@ -28,41 +28,23 @@ import org.chromium.components.bookmarks.BookmarkType;
import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableListAdapter;
import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
/**
* BaseAdapter for {@link RecyclerView}. It manages bookmarks to list there.
*/
class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkListEntry>
implements BookmarkUIObserver, ProfileSyncService.SyncStateChangedListener {
/**
* Specifies the view types that the bookmark delegate screen can contain.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({ViewType.INVALID_PROMO, ViewType.PERSONALIZED_SIGNIN_PROMO,
ViewType.PERSONALIZED_SYNC_PROMO, ViewType.SYNC_PROMO, ViewType.FOLDER,
ViewType.BOOKMARK})
private @interface ViewType {
int INVALID_PROMO = -1;
int PERSONALIZED_SIGNIN_PROMO = 0;
int PERSONALIZED_SYNC_PROMO = 1;
int SYNC_PROMO = 2;
int FOLDER = 3;
int BOOKMARK = 4;
}
private static final int MAXIMUM_NUMBER_OF_SEARCH_RESULTS = 500;
private static final String EMPTY_QUERY = null;
private final List<BookmarkId> mTopLevelFolders = new ArrayList<>();
// There can only be one promo header at a time. This takes on one of the values:
// ViewType.PERSONALIZED_SIGNIN_PROMO, ViewType.SYNC_PROMO, or ViewType.INVALID_PROMO
// ViewType.PERSONALIZED_SIGNIN_PROMO, ViewType.SYNC_PROMO, or ViewType.INVALID.
@ViewType
private int mPromoHeaderType = ViewType.INVALID_PROMO;
private int mPromoHeaderType = ViewType.INVALID;
private BookmarkDelegate mDelegate;
private BookmarkPromoHeader mPromoHeaderManager;
private String mSearchText;
......@@ -140,10 +122,14 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
clearHighlight();
mElements.clear();
// Restore the header, if it exists, then update it.
if (hasPromoHeader()) mElements.add(null);
if (hasPromoHeader()) {
mElements.add(BookmarkListEntry.createSyncPromoHeader(mPromoHeaderType));
}
updateHeader(false);
for (BookmarkId bId : bookmarks) {
mElements.add(mDelegate.getModel().getBookmarkById(bId));
BookmarkItem item = mDelegate.getModel().getBookmarkById(bId);
mElements.add(BookmarkListEntry.createBookmarkEntry(item));
}
notifyDataSetChanged();
}
......@@ -156,16 +142,8 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
// DragReorderableListAdapter implementation.
@Override
public @ViewType int getItemViewType(int position) {
if (position == 0 && hasPromoHeader()) {
return mPromoHeaderType;
} else {
BookmarkItem item = getItemByPosition(position);
if (item.isFolder()) {
return ViewType.FOLDER;
} else {
return ViewType.BOOKMARK;
}
}
BookmarkListEntry entry = getItemByPosition(position);
return entry.getViewType();
}
private ViewHolder createViewHolderHelper(ViewGroup parent, @LayoutRes int layoutId) {
......@@ -342,7 +320,9 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
void moveUpOne(BookmarkId bookmarkId) {
int pos = getPositionForBookmark(bookmarkId);
mElements.remove(pos);
mElements.add(pos - 1, mDelegate.getModel().getBookmarkById(bookmarkId));
mElements.add(pos - 1,
BookmarkListEntry.createBookmarkEntry(
mDelegate.getModel().getBookmarkById(bookmarkId)));
setOrder(mElements);
}
......@@ -352,7 +332,9 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
void moveDownOne(BookmarkId bookmarkId) {
int pos = getPositionForBookmark(bookmarkId);
mElements.remove(pos);
mElements.add(pos + 1, mDelegate.getModel().getBookmarkById(bookmarkId));
mElements.add(pos + 1,
BookmarkListEntry.createBookmarkEntry(
mDelegate.getModel().getBookmarkById(bookmarkId)));
setOrder(mElements);
}
......@@ -386,11 +368,11 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
if (currentUIState == BookmarkUIState.STATE_LOADING) {
return;
} else if (currentUIState == BookmarkUIState.STATE_SEARCHING) {
mPromoHeaderType = ViewType.INVALID_PROMO;
mPromoHeaderType = ViewType.INVALID;
} else {
switch (mPromoHeaderManager.getPromoState()) {
case BookmarkPromoHeader.PromoState.PROMO_NONE:
mPromoHeaderType = ViewType.INVALID_PROMO;
mPromoHeaderType = ViewType.INVALID;
break;
case BookmarkPromoHeader.PromoState.PROMO_SIGNIN_PERSONALIZED:
mPromoHeaderType = ViewType.PERSONALIZED_SIGNIN_PROMO;
......@@ -410,7 +392,7 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
if (!wasShowingPromo && willShowPromo) {
// A null element at the 0th index represents a promo header.
mElements.add(0, null);
mElements.add(0, BookmarkListEntry.createSyncPromoHeader(mPromoHeaderType));
if (shouldNotify) notifyItemInserted(0);
} else if (wasShowingPromo && willShowPromo) {
if (shouldNotify) notifyItemChanged(0);
......@@ -464,7 +446,7 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
}
@Override
protected void setOrder(List<BookmarkItem> bookmarkItems) {
protected void setOrder(List<BookmarkListEntry> listEntries) {
assert !topLevelFoldersShowing() : "Cannot reorder top-level folders!";
assert mCurrentFolder.getType()
!= BookmarkType.PARTNER : "Cannot reorder partner bookmarks!";
......@@ -477,7 +459,9 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
// Get the new order for the IDs.
long[] newOrder = new long[endIndex - startIndex + 1];
for (int i = startIndex; i <= endIndex; i++) {
newOrder[i - startIndex] = bookmarkItems.get(i).getId().getId();
BookmarkItem bookmarkItem = listEntries.get(i).getBookmarkItem();
assert bookmarkItem != null;
newOrder[i - startIndex] = bookmarkItem.getId().getId();
}
mDelegate.getModel().reorderBookmarks(mCurrentFolder, newOrder);
if (mDragStateDelegate.getDragActive()) {
......@@ -491,14 +475,17 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
private int getBookmarkItemEndIndex() {
int endIndex = mElements.size() - 1;
if (!mElements.get(endIndex).isMovable()) {
BookmarkItem bookmarkItem = mElements.get(endIndex).getBookmarkItem();
assert bookmarkItem != null;
if (!bookmarkItem.isMovable()) {
endIndex--;
}
return endIndex;
}
private boolean isOrderable(BookmarkItem bItem) {
return bItem != null && bItem.isMovable();
private boolean isOrderable(BookmarkListEntry entry) {
return entry != null && entry.getBookmarkItem() != null
&& entry.getBookmarkItem().isMovable();
}
@Override
......@@ -511,19 +498,18 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem>
@Override
@VisibleForTesting
public boolean isPassivelyDraggable(ViewHolder viewHolder) {
BookmarkItem bItem = getItemByHolder(viewHolder);
return isOrderable(bItem);
return isOrderable(getItemByHolder(viewHolder));
}
@VisibleForTesting
BookmarkId getIdByPosition(int position) {
BookmarkItem bItem = getItemByPosition(position);
if (bItem == null) return null;
return bItem.getId();
BookmarkListEntry entry = getItemByPosition(position);
if (entry == null || entry.getBookmarkItem() == null) return null;
return entry.getBookmarkItem().getId();
}
private boolean hasPromoHeader() {
return mPromoHeaderType != ViewType.INVALID_PROMO;
return mPromoHeaderType != ViewType.INVALID;
}
private @Location int getLocationFromPosition(int position) {
......
// Copyright 2020 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.bookmarks;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.annotation.Nonnull;
/**
* Represents different type of views in the bookmark UI.
*/
final class BookmarkListEntry {
/**
* Specifies the view types that the bookmark delegate screen can contain.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({ViewType.INVALID, ViewType.PERSONALIZED_SIGNIN_PROMO, ViewType.PERSONALIZED_SYNC_PROMO,
ViewType.SYNC_PROMO, ViewType.FOLDER, ViewType.BOOKMARK})
@interface ViewType {
int INVALID = -1;
int PERSONALIZED_SIGNIN_PROMO = 0;
int PERSONALIZED_SYNC_PROMO = 1;
int SYNC_PROMO = 2;
int FOLDER = 3;
int BOOKMARK = 4;
}
private final @ViewType int mViewType;
@Nullable
private final BookmarkItem mBookmarkItem;
private BookmarkListEntry(int viewType, @Nullable BookmarkItem bookmarkItem) {
this.mViewType = viewType;
this.mBookmarkItem = bookmarkItem;
}
/**
* Create an entry presenting a bookmark folder or bookmark.
* @param bookmarkItem The data object created from the bookmark backend.
*/
static BookmarkListEntry createBookmarkEntry(@Nonnull BookmarkItem bookmarkItem) {
return new BookmarkListEntry(
bookmarkItem.isFolder() ? ViewType.FOLDER : ViewType.BOOKMARK, bookmarkItem);
}
/**
* Create an entry presenting a sync promo header.
* @param viewType The view type of the sync promo header.
*/
static BookmarkListEntry createSyncPromoHeader(@ViewType int viewType) {
assert viewType == ViewType.PERSONALIZED_SIGNIN_PROMO
|| viewType == ViewType.PERSONALIZED_SYNC_PROMO || viewType == ViewType.SYNC_PROMO;
return new BookmarkListEntry(viewType, /*bookmarkItem=*/null);
}
/**
* Returns the view type used in the bookmark list UI.
*/
@ViewType
int getViewType() {
return mViewType;
}
/**
* Returns the view type used in the bookmark list UI. Can be null for non bookmark view types.
*/
@Nullable
BookmarkItem getBookmarkItem() {
return mBookmarkItem;
}
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment