Commit d87d1cda authored by Friedrich Horschig's avatar Friedrich Horschig Committed by Commit Bot

[TouchToFill][Android] Add 'Manage Passwords' footer

This CL adds a button that allows users to navigate to the password
preferences after pulling up the touch to fill sheet fully.

Screenshots in the linked bug.

Bug: 1013257
Change-Id: Ib6616f93498b4061a0e3b2b97b9f45cfc0364138
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1859982
Commit-Queue: Friedrich [CET] <fhorschig@chromium.org>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#706910}
parent f0897e67
...@@ -612,8 +612,8 @@ ChromePasswordManagerClient::GetOrCreatePasswordAccessory() { ...@@ -612,8 +612,8 @@ ChromePasswordManagerClient::GetOrCreatePasswordAccessory() {
TouchToFillController* TouchToFillController*
ChromePasswordManagerClient::GetOrCreateTouchToFillController() { ChromePasswordManagerClient::GetOrCreateTouchToFillController() {
if (!touch_to_fill_controller_) { if (!touch_to_fill_controller_) {
touch_to_fill_controller_ = std::make_unique<TouchToFillController>( touch_to_fill_controller_ =
web_contents(), GetFaviconService()); std::make_unique<TouchToFillController>(this, GetFaviconService());
} }
return touch_to_fill_controller_.get(); return touch_to_fill_controller_.get();
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <utility> #include <utility>
#include "base/logging.h" #include "base/logging.h"
#include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include "chrome/browser/touch_to_fill/touch_to_fill_view.h" #include "chrome/browser/touch_to_fill/touch_to_fill_view.h"
#include "components/favicon/core/favicon_service.h" #include "components/favicon/core/favicon_service.h"
#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h" #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
...@@ -14,7 +15,6 @@ ...@@ -14,7 +15,6 @@
#include "components/password_manager/core/browser/password_manager_driver.h" #include "components/password_manager/core/browser/password_manager_driver.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/url_formatter/elide_url.h" #include "components/url_formatter/elide_url.h"
#include "content/public/browser/web_contents.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h" #include "services/network/public/cpp/is_potentially_trustworthy.h"
using password_manager::CredentialPair; using password_manager::CredentialPair;
...@@ -33,9 +33,9 @@ void OnImageFetched(base::OnceCallback<void(const gfx::Image&)> callback, ...@@ -33,9 +33,9 @@ void OnImageFetched(base::OnceCallback<void(const gfx::Image&)> callback,
} // namespace } // namespace
TouchToFillController::TouchToFillController( TouchToFillController::TouchToFillController(
content::WebContents* web_contents, ChromePasswordManagerClient* password_client,
favicon::FaviconService* favicon_service) favicon::FaviconService* favicon_service)
: web_contents_(web_contents), favicon_service_(favicon_service) {} : password_client_(password_client), favicon_service_(favicon_service) {}
TouchToFillController::~TouchToFillController() = default; TouchToFillController::~TouchToFillController() = default;
...@@ -67,6 +67,11 @@ void TouchToFillController::OnCredentialSelected( ...@@ -67,6 +67,11 @@ void TouchToFillController::OnCredentialSelected(
->FillSuggestion(credential.username, credential.password); ->FillSuggestion(credential.username, credential.password);
} }
void TouchToFillController::OnManagePasswordsSelected() {
password_client_->NavigateToManagePasswordsPage(
password_manager::ManagePasswordsReferrer::kTouchToFill);
}
void TouchToFillController::OnDismiss() { void TouchToFillController::OnDismiss() {
if (!driver_) if (!driver_)
return; return;
...@@ -75,7 +80,7 @@ void TouchToFillController::OnDismiss() { ...@@ -75,7 +80,7 @@ void TouchToFillController::OnDismiss() {
} }
gfx::NativeView TouchToFillController::GetNativeView() { gfx::NativeView TouchToFillController::GetNativeView() {
return web_contents_->GetNativeView(); return password_client_->web_contents()->GetNativeView();
} }
void TouchToFillController::FetchFavicon( void TouchToFillController::FetchFavicon(
......
...@@ -17,10 +17,6 @@ ...@@ -17,10 +17,6 @@
#include "components/favicon_base/favicon_types.h" #include "components/favicon_base/favicon_types.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
namespace content {
class WebContents;
} // namespace content
namespace favicon { namespace favicon {
class FaviconService; class FaviconService;
} // namespace favicon } // namespace favicon
...@@ -30,9 +26,11 @@ class PasswordManagerDriver; ...@@ -30,9 +26,11 @@ class PasswordManagerDriver;
struct CredentialPair; struct CredentialPair;
} // namespace password_manager } // namespace password_manager
class ChromePasswordManagerClient;
class TouchToFillController { class TouchToFillController {
public: public:
TouchToFillController(content::WebContents* web_contents, TouchToFillController(ChromePasswordManagerClient* web_contents,
favicon::FaviconService* favicon_service); favicon::FaviconService* favicon_service);
TouchToFillController(const TouchToFillController&) = delete; TouchToFillController(const TouchToFillController&) = delete;
TouchToFillController& operator=(const TouchToFillController&) = delete; TouchToFillController& operator=(const TouchToFillController&) = delete;
...@@ -47,6 +45,10 @@ class TouchToFillController { ...@@ -47,6 +45,10 @@ class TouchToFillController {
// repeatedly. // repeatedly.
void OnCredentialSelected(const password_manager::CredentialPair& credential); void OnCredentialSelected(const password_manager::CredentialPair& credential);
// Informs the controller that the user has tapped the "Manage Passwords"
// button. This will open the password preferences.
void OnManagePasswordsSelected();
// Informs the controller that the user has dismissed the sheet. Invokes // Informs the controller that the user has dismissed the sheet. Invokes
// TouchToFillDismissed() on |driver_|. No-op if invoked repeatedly. // TouchToFillDismissed() on |driver_|. No-op if invoked repeatedly.
void OnDismiss(); void OnDismiss();
...@@ -67,10 +69,8 @@ class TouchToFillController { ...@@ -67,10 +69,8 @@ class TouchToFillController {
#endif #endif
private: private:
// Weak pointer to the current WebContents. This is safe because the lifetime // Weak pointer to the ChromePasswordManagerClient this class is tied to.
// of this class is tied to ChromePasswordManagerClient, which implements ChromePasswordManagerClient* password_client_ = nullptr;
// WebContentsUserData.
content::WebContents* web_contents_ = nullptr;
// Driver passed to the latest invocation of Show(). Gets cleared when // Driver passed to the latest invocation of Show(). Gets cleared when
// OnCredentialSelected() or OnDismissed() gets called. // OnCredentialSelected() or OnDismissed() gets called.
......
...@@ -17,18 +17,24 @@ ...@@ -17,18 +17,24 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginEnd="@dimen/touch_to_fill_sheet_margin"
android:layout_marginStart="@dimen/touch_to_fill_sheet_margin"
android:importantForAccessibility="no" android:importantForAccessibility="no"
app:srcCompat="@drawable/touch_to_fill_header_image" /> app:srcCompat="@drawable/touch_to_fill_header_image" />
<org.chromium.ui.widget.TextViewWithLeading <org.chromium.ui.widget.TextViewWithLeading
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/touch_to_fill_sheet_margin"
android:layout_marginStart="@dimen/touch_to_fill_sheet_margin"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:text="@string/touch_to_fill_sheet_title" android:text="@string/touch_to_fill_sheet_title"
android:textAppearance="@style/TextAppearance.BlackHeadline" /> android:textAppearance="@style/TextAppearance.BlackHeadline" />
<org.chromium.ui.widget.TextViewWithLeading <org.chromium.ui.widget.TextViewWithLeading
android:id="@+id/touch_to_fill_sheet_subtitle" android:id="@+id/touch_to_fill_sheet_subtitle"
android:layout_marginEnd="@dimen/touch_to_fill_sheet_margin"
android:layout_marginStart="@dimen/touch_to_fill_sheet_margin"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
......
...@@ -10,15 +10,15 @@ ...@@ -10,15 +10,15 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:minHeight="340dp" android:minHeight="340dp"
android:orientation="vertical" android:orientation="vertical">
android:paddingStart="16dp"
android:paddingEnd="16dp">
<ImageView <ImageView
android:id="@+id/drag_handlebar" android:id="@+id/drag_handlebar"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginEnd="@dimen/touch_to_fill_sheet_margin"
android:layout_marginStart="@dimen/touch_to_fill_sheet_margin"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:layout_marginBottom="6dp" android:layout_marginBottom="6dp"
android:importantForAccessibility="no" android:importantForAccessibility="no"
...@@ -27,11 +27,31 @@ ...@@ -27,11 +27,31 @@
<android.support.v7.widget.RecyclerView <android.support.v7.widget.RecyclerView
android:id="@+id/sheet_item_list" android:id="@+id/sheet_item_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:minHeight="200dp" android:layout_weight="1"
android:layout_marginTop="24dp" android:layout_marginTop="16dp"
android:layout_marginEnd="@dimen/touch_to_fill_sheet_margin"
android:layout_marginStart="@dimen/touch_to_fill_sheet_margin"
android:clipToPadding="false" android:clipToPadding="false"
android:paddingBottom="16dp" android:paddingBottom="16dp"
android:divider="@null" android:divider="@null"
tools:listitem="@layout/touch_to_fill_credential_item"/> tools:listitem="@layout/touch_to_fill_credential_item"/>
<View style="@style/HorizontalDivider"
android:layout_height="@dimen/divider_height"
android:layout_marginBottom="8dp"
android:layout_width="match_parent"/>
<TextView
android:id="@+id/touch_to_fill_sheet_manage_passwords"
android:text="@string/manage_passwords"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:paddingStart="@dimen/touch_to_fill_sheet_margin"
android:paddingEnd="@dimen/touch_to_fill_sheet_margin"
android:minHeight="48dp"
android:gravity="center_vertical|start"
android:textAppearance="@style/TextAppearance.BlackTitle1"
android:background="?android:attr/selectableItemBackground"/>
</LinearLayout> </LinearLayout>
...@@ -5,4 +5,5 @@ ...@@ -5,4 +5,5 @@
<resources> <resources>
<dimen name="touch_to_fill_favicon_size">24dp</dimen> <dimen name="touch_to_fill_favicon_size">24dp</dimen>
<dimen name="touch_to_fill_sheet_margin">16dp</dimen>
</resources> </resources>
...@@ -67,6 +67,12 @@ class TouchToFillBridge implements TouchToFillComponent.Delegate { ...@@ -67,6 +67,12 @@ class TouchToFillBridge implements TouchToFillComponent.Delegate {
if (mNativeView != 0) TouchToFillBridgeJni.get().onDismiss(mNativeView); if (mNativeView != 0) TouchToFillBridgeJni.get().onDismiss(mNativeView);
} }
@Override
public void onManagePasswordsSelected() {
assert mNativeView != 0 : "The native side is already dismissed";
TouchToFillBridgeJni.get().onManagePasswordsSelected(mNativeView);
}
@Override @Override
public void onCredentialSelected(Credential credential) { public void onCredentialSelected(Credential credential) {
assert mNativeView != 0 : "The native side is already dismissed"; assert mNativeView != 0 : "The native side is already dismissed";
...@@ -82,6 +88,7 @@ class TouchToFillBridge implements TouchToFillComponent.Delegate { ...@@ -82,6 +88,7 @@ class TouchToFillBridge implements TouchToFillComponent.Delegate {
@NativeMethods @NativeMethods
interface Natives { interface Natives {
void onCredentialSelected(long nativeTouchToFillViewImpl, Credential credential); void onCredentialSelected(long nativeTouchToFillViewImpl, Credential credential);
void onManagePasswordsSelected(long nativeTouchToFillViewImpl);
void onDismiss(long nativeTouchToFillViewImpl); void onDismiss(long nativeTouchToFillViewImpl);
void fetchFavicon(long nativeTouchToFillViewImpl, String origin, int desiredSizeInPx, void fetchFavicon(long nativeTouchToFillViewImpl, String origin, int desiredSizeInPx,
Callback<Bitmap> callback); Callback<Bitmap> callback);
......
...@@ -10,6 +10,7 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.Cr ...@@ -10,6 +10,7 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.Cr
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.ON_CLICK_LISTENER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.ON_CLICK_LISTENER;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ON_CLICK_MANAGE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.SHEET_ITEMS; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.SHEET_ITEMS;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
...@@ -53,6 +54,7 @@ class TouchToFillMediator { ...@@ -53,6 +54,7 @@ class TouchToFillMediator {
void showCredentials( void showCredentials(
String formattedUrl, boolean isOriginSecure, List<Credential> credentials) { String formattedUrl, boolean isOriginSecure, List<Credential> credentials) {
assert credentials != null; assert credentials != null;
mModel.set(ON_CLICK_MANAGE, this::onManagePasswordSelected);
mModel.set(VISIBLE, true); mModel.set(VISIBLE, true);
ListModel<ListItem> sheetItems = mModel.get(SHEET_ITEMS); ListModel<ListItem> sheetItems = mModel.get(SHEET_ITEMS);
...@@ -99,4 +101,9 @@ class TouchToFillMediator { ...@@ -99,4 +101,9 @@ class TouchToFillMediator {
UMA_TOUCH_TO_FILL_DISMISSAL_REASON, reason, StateChangeReason.MAX_VALUE + 1); UMA_TOUCH_TO_FILL_DISMISSAL_REASON, reason, StateChangeReason.MAX_VALUE + 1);
mDelegate.onDismissed(); mDelegate.onDismissed();
} }
private void onManagePasswordSelected() {
mModel.set(VISIBLE, false);
mDelegate.onManagePasswordsSelected();
}
} }
...@@ -29,9 +29,10 @@ class TouchToFillProperties { ...@@ -29,9 +29,10 @@ class TouchToFillProperties {
new PropertyModel.ReadableObjectPropertyKey<>("sheet_items"); new PropertyModel.ReadableObjectPropertyKey<>("sheet_items");
static final PropertyModel.ReadableObjectPropertyKey<Callback<Integer>> DISMISS_HANDLER = static final PropertyModel.ReadableObjectPropertyKey<Callback<Integer>> DISMISS_HANDLER =
new PropertyModel.ReadableObjectPropertyKey<>("dismiss_handler"); new PropertyModel.ReadableObjectPropertyKey<>("dismiss_handler");
static final PropertyModel.WritableObjectPropertyKey<Runnable> ON_CLICK_MANAGE =
new PropertyModel.WritableObjectPropertyKey<>("on_click_manage");
static PropertyModel createDefaultModel(Callback<Integer> handler) { static PropertyModel createDefaultModel(Callback<Integer> handler) {
return new PropertyModel.Builder(VISIBLE, SHEET_ITEMS, DISMISS_HANDLER) return new PropertyModel.Builder(VISIBLE, SHEET_ITEMS, DISMISS_HANDLER, ON_CLICK_MANAGE)
.with(VISIBLE, false) .with(VISIBLE, false)
.with(SHEET_ITEMS, new ListModel<>()) .with(SHEET_ITEMS, new ListModel<>())
.with(DISMISS_HANDLER, handler) .with(DISMISS_HANDLER, handler)
......
...@@ -81,6 +81,11 @@ class TouchToFillView implements BottomSheet.BottomSheetContent { ...@@ -81,6 +81,11 @@ class TouchToFillView implements BottomSheet.BottomSheetContent {
mSheetItemListView.setAdapter(adapter); mSheetItemListView.setAdapter(adapter);
} }
void setOnManagePasswordClick(Runnable runnable) {
mContentView.findViewById(R.id.touch_to_fill_sheet_manage_passwords)
.setOnClickListener((v) -> runnable.run());
}
Context getContext() { Context getContext() {
return mContext; return mContext;
} }
......
...@@ -11,6 +11,7 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.Cr ...@@ -11,6 +11,7 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.Cr
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.DISMISS_HANDLER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.DISMISS_HANDLER;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ON_CLICK_MANAGE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.SHEET_ITEMS; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.SHEET_ITEMS;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
import static org.chromium.chrome.browser.util.UrlUtilities.stripScheme; import static org.chromium.chrome.browser.util.UrlUtilities.stripScheme;
...@@ -46,6 +47,8 @@ class TouchToFillViewBinder { ...@@ -46,6 +47,8 @@ class TouchToFillViewBinder {
view.setDismissHandler(model.get(DISMISS_HANDLER)); view.setDismissHandler(model.get(DISMISS_HANDLER));
} else if (propertyKey == VISIBLE) { } else if (propertyKey == VISIBLE) {
view.setVisible(model.get(VISIBLE)); view.setVisible(model.get(VISIBLE));
} else if (propertyKey == ON_CLICK_MANAGE) {
view.setOnManagePasswordClick(model.get(ON_CLICK_MANAGE));
} else if (propertyKey == SHEET_ITEMS) { } else if (propertyKey == SHEET_ITEMS) {
view.setSheetItemListAdapter( view.setSheetItemListAdapter(
new RecyclerViewAdapter<>(new SimpleRecyclerViewMcp<>(model.get(SHEET_ITEMS), new RecyclerViewAdapter<>(new SimpleRecyclerViewMcp<>(model.get(SHEET_ITEMS),
......
...@@ -125,6 +125,9 @@ ...@@ -125,6 +125,9 @@
<message name="IDS_TOUCH_TO_FILL_SHEET_CLOSED" desc="Accessibility string read when the Touch To Fill bottom sheet showing a list of the user's credentials is closed."> <message name="IDS_TOUCH_TO_FILL_SHEET_CLOSED" desc="Accessibility string read when the Touch To Fill bottom sheet showing a list of the user's credentials is closed.">
List of credentials to be filled on touch is closed. List of credentials to be filled on touch is closed.
</message> </message>
<message name="IDS_MANAGE_PASSWORDS" desc="Title of the button at the end of a touch to fill sheet that will open the password preferences when tapped.">
Manage Passwords
</message>
</messages> </messages>
</release> </release>
</grit> </grit>
...@@ -36,6 +36,11 @@ public interface TouchToFillComponent { ...@@ -36,6 +36,11 @@ public interface TouchToFillComponent {
*/ */
void onDismissed(); void onDismissed();
/**
* Called when the user selects the "Manage Passwords" option.
*/
void onManagePasswordsSelected();
/** /**
* Called to fetch a favicon for one origin to display it in the UI. * Called to fetch a favicon for one origin to display it in the UI.
*/ */
......
...@@ -17,6 +17,7 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.Cr ...@@ -17,6 +17,7 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.Cr
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.ON_CLICK_LISTENER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.ON_CLICK_LISTENER;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ON_CLICK_MANAGE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.SHEET_ITEMS; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.SHEET_ITEMS;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
import static org.chromium.content_public.browser.test.util.CriteriaHelper.pollUiThread; import static org.chromium.content_public.browser.test.util.CriteriaHelper.pollUiThread;
...@@ -54,6 +55,7 @@ import org.chromium.ui.modelutil.MVCListAdapter; ...@@ -54,6 +55,7 @@ import org.chromium.ui.modelutil.MVCListAdapter;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* View tests for the Touch To Fill component ensure that model changes are reflected in the sheet. * View tests for the Touch To Fill component ensure that model changes are reflected in the sheet.
...@@ -189,6 +191,27 @@ public class TouchToFillViewTest { ...@@ -189,6 +191,27 @@ public class TouchToFillViewTest {
waitForEvent(mCredentialCallback).onResult(eq(ANA)); waitForEvent(mCredentialCallback).onResult(eq(ANA));
} }
@Test
@MediumTest
public void testManagePasswordsIsClickable() {
final AtomicBoolean manageButtonClicked = new AtomicBoolean(false);
TestThreadUtils.runOnUiThreadBlocking(() -> {
mModel.set(ON_CLICK_MANAGE, () -> manageButtonClicked.set(true));
mModel.set(VISIBLE, true);
});
pollUiThread(() -> getBottomSheetState() == SheetState.PEEK);
TestThreadUtils.runOnUiThreadBlocking(
() -> { getActivity().getBottomSheet().setSheetState(SheetState.FULL, false); });
pollUiThread(() -> getBottomSheetState() == SheetState.FULL);
TextView manageButton = mTouchToFillView.getContentView().findViewById(
R.id.touch_to_fill_sheet_manage_passwords);
TouchCommon.singleClickView(manageButton);
pollUiThread(manageButtonClicked::get);
}
@Test @Test
@MediumTest @MediumTest
public void testDismissesWhenHidden() { public void testDismissesWhenHidden() {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.chromium.chrome.browser.touch_to_fill; package org.chromium.chrome.browser.touch_to_fill;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
...@@ -21,6 +22,7 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.Cr ...@@ -21,6 +22,7 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.Cr
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.DISMISS_HANDLER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.DISMISS_HANDLER;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ON_CLICK_MANAGE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.SHEET_ITEMS; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.SHEET_ITEMS;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
...@@ -238,6 +240,15 @@ public class TouchToFillControllerTest { ...@@ -238,6 +240,15 @@ public class TouchToFillControllerTest {
is(1)); is(1));
} }
@Test
public void testHidesWhenSelectingManagePasswords() {
mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
assertThat(mModel.get(ON_CLICK_MANAGE), is(notNullValue()));
mModel.get(ON_CLICK_MANAGE).run();
verify(mMockDelegate).onManagePasswordsSelected();
assertThat(mModel.get(VISIBLE), is(false));
}
/** /**
* Helper to verify formatted URLs. The real implementation calls {@link UrlFormatter}. It's not * Helper to verify formatted URLs. The real implementation calls {@link UrlFormatter}. It's not
* useful to actually reimplement the formatter, so just modify the string in a trivial way. * useful to actually reimplement the formatter, so just modify the string in a trivial way.
......
...@@ -118,6 +118,10 @@ void TouchToFillViewImpl::OnCredentialSelected( ...@@ -118,6 +118,10 @@ void TouchToFillViewImpl::OnCredentialSelected(
OnCredentialSelected(ConvertJavaCredential(env, credential)); OnCredentialSelected(ConvertJavaCredential(env, credential));
} }
void TouchToFillViewImpl::OnManagePasswordsSelected(JNIEnv* env) {
controller_->OnManagePasswordsSelected();
}
void TouchToFillViewImpl::OnDismiss(JNIEnv* env) { void TouchToFillViewImpl::OnDismiss(JNIEnv* env) {
OnDismiss(); OnDismiss();
} }
...@@ -39,6 +39,7 @@ class TouchToFillViewImpl : public TouchToFillView { ...@@ -39,6 +39,7 @@ class TouchToFillViewImpl : public TouchToFillView {
void OnCredentialSelected( void OnCredentialSelected(
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jobject>& credential); const base::android::JavaParamRef<jobject>& credential);
void OnManagePasswordsSelected(JNIEnv* env);
void OnDismiss(JNIEnv* env); void OnDismiss(JNIEnv* env);
private: private:
......
...@@ -212,6 +212,7 @@ GURL GetGooglePasswordManagerURL(ManagePasswordsReferrer referrer) { ...@@ -212,6 +212,7 @@ GURL GetGooglePasswordManagerURL(ManagePasswordsReferrer referrer) {
case ManagePasswordsReferrer::kProfileChooser: case ManagePasswordsReferrer::kProfileChooser:
return "profile_chooser"; return "profile_chooser";
case ManagePasswordsReferrer::kPasswordsAccessorySheet: case ManagePasswordsReferrer::kPasswordsAccessorySheet:
case ManagePasswordsReferrer::kTouchToFill:
NOTREACHED(); NOTREACHED();
} }
......
...@@ -32,9 +32,12 @@ enum class ManagePasswordsReferrer { ...@@ -32,9 +32,12 @@ enum class ManagePasswordsReferrer {
kProfileChooser = 5, kProfileChooser = 5,
// Corresponds to the passwords accessory sheet on Android, triggered by // Corresponds to the passwords accessory sheet on Android, triggered by
// tapping on the key icon above in the keyboard accessory bar. // tapping on the key icon above in the keyboard accessory bar.
// Only used on Android // Only used on Android.
kPasswordsAccessorySheet = 6, kPasswordsAccessorySheet = 6,
kMaxValue = kPasswordsAccessorySheet, // Corresponds to the touch to fill bottom sheet that replaces the dropdown.
// Only used on Android.
kTouchToFill = 7,
kMaxValue = kTouchToFill,
}; };
} // namespace password_manager } // namespace password_manager
......
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