Skip to content

Commit

Permalink
Create bookmarks search box row.
Browse files Browse the repository at this point in the history
Bug: 1439583
Change-Id: Ic2656541e4bc2f3cf05462bffd534b460c256c2d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4521629
Reviewed-by: Brandon Wylie <wylieb@chromium.org>
Commit-Queue: Sky Malice <skym@chromium.org>
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#1147556}
  • Loading branch information
Sky Malice authored and Chromium LUCI CQ committed May 23, 2023
1 parent 5618193 commit af41a98
Show file tree
Hide file tree
Showing 16 changed files with 337 additions and 20 deletions.
1 change: 1 addition & 0 deletions chrome/android/chrome_java_resources.gni
Expand Up @@ -479,6 +479,7 @@ chrome_java_resources = [
"java/res/layout/bookmark_row_layout.xml",
"java/res/layout/bookmark_row_layout_visual.xml",
"java/res/layout/bookmark_save_flow.xml",
"java/res/layout/bookmark_search_box_row.xml",
"java/res/layout/bookmark_section_header.xml",
"java/res/layout/bookmark_toolbar.xml",
"java/res/layout/bookmark_widget.xml",
Expand Down
1 change: 1 addition & 0 deletions chrome/android/chrome_java_sources.gni
Expand Up @@ -188,6 +188,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowProperties.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowViewBinder.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkSearchBoxRow.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkTextInputLayout.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbar.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarCoordinator.java",
Expand Down
2 changes: 2 additions & 0 deletions chrome/android/chrome_test_java_sources.gni
Expand Up @@ -83,6 +83,8 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSearchBoxRowRenderTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSearchBoxRowTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewRenderTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowRenderTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowRenderTest.java",
Expand Down
31 changes: 31 additions & 0 deletions chrome/android/java/res/layout/bookmark_search_box_row.xml
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2023 The Chromium Authors
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<org.chromium.chrome.browser.bookmarks.BookmarkSearchBoxRow
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="@drawable/search_row_modern_bg"
android:id="@+id/bookmark_toolbar"
android:layout_height="40dp"
android:layout_width="match_parent"
android:layout_marginBottom="18dp">

<EditText
tools:ignore="Autofill,LabelFor"
android:background="@null"
android:hint="@string/bookmark_toolbar_search"
android:id="@+id/search_text"
android:imeOptions="flagNoExtractUi|actionSearch"
android:inputType="text"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:paddingHorizontal="@dimen/bookmark_search_hint_horizontal_padding"
android:singleLine="true"
android:textColorHint="@macro/search_box_hint"
android:textAppearance="@style/TextAppearance.TextLarge.Primary" />

</org.chromium.chrome.browser.bookmarks.BookmarkSearchBoxRow>
2 changes: 1 addition & 1 deletion chrome/android/java/res/values/dimens.xml
Expand Up @@ -239,7 +239,7 @@ found in the LICENSE file.
<!-- The size of displayed favicons for each row. -->
<dimen name="improved_bookmark_favicon_display_size">24dp</dimen>
<dimen name="improved_bookmark_icon_radius">24dp</dimen>

<dimen name="bookmark_search_hint_horizontal_padding">30dp</dimen>

<!-- Bookmark visual refresh dimensions. -->
<dimen name="bookmark_refresh_preferred_start_icon_size">32dp</dimen>
Expand Down
Expand Up @@ -30,7 +30,7 @@ public final class BookmarkListEntry {
ViewType.SYNC_PROMO, ViewType.FOLDER, ViewType.BOOKMARK, ViewType.DIVIDER,
ViewType.SECTION_HEADER, ViewType.SHOPPING_POWER_BOOKMARK, ViewType.TAG_CHIP_LIST,
ViewType.SHOPPING_FILTER, ViewType.IMPROVED_BOOKMARK_VISUAL,
ViewType.IMPROVED_BOOKMARK_COMPACT})
ViewType.IMPROVED_BOOKMARK_COMPACT, ViewType.SEARCH_BOX})
public @interface ViewType {
int INVALID = -1;
int PERSONALIZED_SIGNIN_PROMO = 0;
Expand All @@ -45,6 +45,7 @@ public final class BookmarkListEntry {
int SHOPPING_FILTER = 9;
int IMPROVED_BOOKMARK_VISUAL = 10;
int IMPROVED_BOOKMARK_COMPACT = 11;
int SEARCH_BOX = 12;
}

/** Contains data used by section header in bookmark UI. */
Expand Down
Expand Up @@ -205,6 +205,8 @@ public BookmarkManagerCoordinator(Context context, ComponentName openBookmarkCom
this::buildAndInitVisualImprovedBookmarkRow, ImprovedBookmarkRowViewBinder::bind);
dragReorderableRecyclerViewAdapter.registerType(ViewType.IMPROVED_BOOKMARK_COMPACT,
this::buildAndInitCompactImprovedBookmarkRow, ImprovedBookmarkRowViewBinder::bind);
dragReorderableRecyclerViewAdapter.registerType(
ViewType.SEARCH_BOX, this::buildSearchBoxRow, ImprovedBookmarkRowViewBinder::bind);

RecordUserAction.record("MobileBookmarkManagerOpen");
if (!isDialogUi) {
Expand Down Expand Up @@ -360,6 +362,10 @@ ImprovedBookmarkRow buildAndInitVisualImprovedBookmarkRow(ViewGroup parent) {
return row;
}

View buildSearchBoxRow(ViewGroup parent) {
return inflate(parent, org.chromium.chrome.R.layout.bookmark_search_box_row);
}

private static View inflate(ViewGroup parent, @LayoutRes int layoutId) {
Context context = parent.getContext();
return LayoutInflater.from(context).inflate(layoutId, parent, false);
Expand Down
Expand Up @@ -812,6 +812,12 @@ private int getPositionForBookmark(BookmarkId bookmark) {
private void setBookmarks(List<BookmarkListEntry> bookmarkListEntryList) {
clearHighlight();

if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
// TODO(https://crbug.com/1439583): Do this in a way that doesn't get overridden by
// the promo header.
updateOrAdd(0, buildSearchBoxRow());
}

// Restore the header, if it exists, then update it.
if (hasPromoHeader()) {
updateOrAdd(0, buildPersonalizedPromoListItem());
Expand All @@ -823,7 +829,9 @@ private void setBookmarks(List<BookmarkListEntry> bookmarkListEntryList) {
// items in place so that the recycler view doesn't see everything being removed and added
// back, but instead it sees items being changed.
// TODO(https://crbug.com/1413463): Rework promo/header methods to simplify initial index.
int index = hasPromoHeader() ? 1 : 0;
int index =
hasPromoHeader() || BookmarkFeatures.isAndroidImprovedBookmarksEnabled() ? 1 : 0;

for (BookmarkListEntry bookmarkListEntry : bookmarkListEntryList) {
updateOrAdd(index++, buildBookmarkListItem(bookmarkListEntry));
}
Expand Down Expand Up @@ -942,7 +950,7 @@ private void removeSectionHeaders() {
}

private int getBookmarkItemStartIndex() {
return hasPromoHeader() ? 1 : 0;
return Math.max(0, firstIndexWithLocation(0, mModelList.size(), 1));
}

private int getBookmarkItemEndIndex() {
Expand Down Expand Up @@ -990,6 +998,11 @@ private ListItem buildPersonalizedPromoListItem() {
return new ListItem(bookmarkListEntry.getViewType(), propertyModel);
}

private ListItem buildSearchBoxRow() {
PropertyModel propertyModel = new PropertyModel(BookmarkManagerProperties.ALL_KEYS);
return new ListItem(ViewType.SEARCH_BOX, propertyModel);
}

private ListItem buildBookmarkListItem(BookmarkListEntry bookmarkListEntry) {
if (bookmarkListEntry.getViewType() == ViewType.IMPROVED_BOOKMARK_COMPACT
|| bookmarkListEntry.getViewType() == ViewType.IMPROVED_BOOKMARK_VISUAL) {
Expand Down
@@ -0,0 +1,54 @@
// Copyright 2023 The Chromium Authors
// 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 android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;

import org.chromium.chrome.R;
import org.chromium.ui.KeyboardVisibilityDelegate;
import org.chromium.ui.text.EmptyTextWatcher;

/**
* Row in a {@link androidx.recyclerview.widget.RecyclerView} for querying and filtering shown
* bookmarks.
*/
public class BookmarkSearchBoxRow extends LinearLayout {
public BookmarkSearchBoxRow(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}

@Override
protected void onFinishInflate() {
super.onFinishInflate();

EditText searchText = findViewById(R.id.search_text);
searchText.addTextChangedListener(new EmptyTextWatcher() {
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
// TODO(https://crbug.com/1439583): Propagate query string upward.
}
});
searchText.setOnEditorActionListener(this::onEditorAction);
}

private boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if (actionId == EditorInfo.IME_ACTION_SEARCH
|| keyEvent != null && keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
KeyboardVisibilityDelegate.getInstance().hideKeyboard(textView);
clearFocus();
return true;
} else {
return false;
}
}
}
@@ -0,0 +1,93 @@
// Copyright 2023 The Chromium Authors
// 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 android.graphics.Color;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import androidx.test.filters.MediumTest;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;

import org.chromium.base.test.BaseActivityTestRule;
import org.chromium.base.test.params.ParameterAnnotations;
import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
import org.chromium.base.test.params.ParameterSet;
import org.chromium.base.test.params.ParameterizedRunner;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.Feature;
import org.chromium.chrome.R;
import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
import org.chromium.chrome.test.util.ChromeRenderTestRule;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.ui.test.util.BlankUiTestActivity;
import org.chromium.ui.test.util.DisableAnimationsTestRule;
import org.chromium.ui.test.util.NightModeTestUtils;
import org.chromium.ui.test.util.NightModeTestUtils.NightModeParams;

import java.io.IOException;
import java.util.List;

/** Render tests for {@link BookmarkSearchBoxRow}. */
@RunWith(ParameterizedRunner.class)
@ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
@Batch(Batch.PER_CLASS)
public class BookmarkSearchBoxRowRenderTest {
@ClassParameter
private static List<ParameterSet> sClassParams = new NightModeParams().getParameters();

@Rule
public final DisableAnimationsTestRule mDisableAnimationsRule = new DisableAnimationsTestRule();
@Rule
public BaseActivityTestRule<BlankUiTestActivity> mActivityTestRule =
new BaseActivityTestRule<>(BlankUiTestActivity.class);
@Rule
public ChromeRenderTestRule mRenderTestRule =
ChromeRenderTestRule.Builder.withPublicCorpus()
.setBugComponent(ChromeRenderTestRule.Component.UI_BROWSER_BOOKMARKS)
.build();
@Rule
public TestRule mProcessor = new Features.JUnitProcessor();

private LinearLayout mContentView;

public BookmarkSearchBoxRowRenderTest(boolean nightModeEnabled) {
NightModeTestUtils.setUpNightModeForBlankUiTestActivity(nightModeEnabled);
mRenderTestRule.setNightModeEnabled(nightModeEnabled);
}

@Before
public void setUp() throws Exception {
mActivityTestRule.launchActivity(null);
mActivityTestRule.getActivity().setTheme(R.style.Theme_BrowserUI_DayNight);

TestThreadUtils.runOnUiThreadBlocking(() -> {
mContentView = new LinearLayout(mActivityTestRule.getActivity());
mContentView.setBackgroundColor(Color.WHITE);

FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mActivityTestRule.getActivity().setContentView(mContentView, params);

LayoutInflater.from(mActivityTestRule.getActivity())
.inflate(org.chromium.chrome.R.layout.bookmark_search_box_row, mContentView);
});
}

@Test
@MediumTest
@Feature({"RenderTest"})
public void testNormal() throws IOException {
mRenderTestRule.render(mContentView, "normal");
}
}
@@ -0,0 +1,91 @@
// Copyright 2023 The Chromium Authors
// 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 android.app.Activity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;

import org.chromium.base.test.BaseActivityTestRule;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.Criteria;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.base.test.util.Matchers;
import org.chromium.chrome.R;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.content_public.browser.test.util.KeyUtils;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.content_public.browser.test.util.TouchCommon;
import org.chromium.ui.test.util.BlankUiTestActivity;
import org.chromium.ui.test.util.DisableAnimationsTestRule;

/** Non-render tests for {@link BookmarkSearchBoxRow}. */
@RunWith(ChromeJUnit4ClassRunner.class)
@Batch(Batch.PER_CLASS)
public class BookmarkSearchBoxRowTest {
@Rule
public final DisableAnimationsTestRule mDisableAnimationsRule = new DisableAnimationsTestRule();
@Rule
public BaseActivityTestRule<BlankUiTestActivity> mActivityTestRule =
new BaseActivityTestRule<>(BlankUiTestActivity.class);
@Rule
public TestRule mProcessor = new Features.JUnitProcessor();

private BookmarkSearchBoxRow mBookmarkSearchBoxRow;

@Before
public void setUp() throws Exception {
mActivityTestRule.launchActivity(null);

TestThreadUtils.runOnUiThreadBlocking(() -> {
Activity activity = mActivityTestRule.getActivity();
LinearLayout contentView = new LinearLayout(activity);

// Older Android versions need this otherwise {@link View#clearFocus()} will be ignored.
// This also mirrors what {@link SelectableListLayout} does.
contentView.setFocusableInTouchMode(true);

FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
activity.setContentView(contentView, params);

LayoutInflater layoutInflater = LayoutInflater.from(activity);
mBookmarkSearchBoxRow =
layoutInflater.inflate(R.layout.bookmark_search_box_row, contentView)
.findViewById(R.id.bookmark_toolbar);
});
}

@Test
@MediumTest
public void testFocusAndEnter() {
EditText editText = mBookmarkSearchBoxRow.findViewById(R.id.search_text);

TestThreadUtils.runOnUiThreadBlocking(() -> TouchCommon.singleClickView(editText));
CriteriaHelper.pollUiThread(
() -> Criteria.checkThat(editText.hasFocus(), Matchers.is(true)));

TestThreadUtils.runOnUiThreadBlocking(
()
-> KeyUtils.singleKeyEventView(InstrumentationRegistry.getInstrumentation(),
editText, KeyEvent.KEYCODE_ENTER));
CriteriaHelper.pollUiThread(
() -> Criteria.checkThat(editText.hasFocus(), Matchers.is(false)));
}
}
Expand Up @@ -129,5 +129,6 @@ public void testCreateView() {
assertNotNull(BookmarkManagerCoordinator.buildShoppingFilterView(parent));
assertNotNull(mCoordinator.buildAndInitCompactImprovedBookmarkRow(parent));
assertNotNull(mCoordinator.buildAndInitVisualImprovedBookmarkRow(parent));
assertNotNull(mCoordinator.buildSearchBoxRow(parent));
}
}

0 comments on commit af41a98

Please sign in to comment.