Commit 0e988b8e authored by Jan Wilken Dörrie's avatar Jan Wilken Dörrie Committed by Commit Bot

[Passwords] Add string for insecure origins to Touch To Fill

This change modifies the subtitle of the Touch To Fill sheet to be more
explicit when filling into insecure origins. It does so by introducing
another string that is displayed in this case.

Bug: 1012717
Change-Id: I15991f9b09d1607c155c8764a8694df7ccc8ed82
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1849856Reviewed-by: default avatarFriedrich [CET] <fhorschig@chromium.org>
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704645}
parent 14371f98
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#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 "content/public/browser/web_contents.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
using password_manager::CredentialPair; using password_manager::CredentialPair;
using password_manager::PasswordManagerDriver; using password_manager::PasswordManagerDriver;
...@@ -31,9 +32,11 @@ void TouchToFillController::Show(base::span<const CredentialPair> credentials, ...@@ -31,9 +32,11 @@ void TouchToFillController::Show(base::span<const CredentialPair> credentials,
if (!view_) if (!view_)
view_ = TouchToFillViewFactory::Create(this); view_ = TouchToFillViewFactory::Create(this);
const GURL& url = driver_->GetLastCommittedURL();
view_->Show(url_formatter::FormatUrlForSecurityDisplay( view_->Show(url_formatter::FormatUrlForSecurityDisplay(
driver_->GetLastCommittedURL(), url, url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS),
url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC), TouchToFillView::IsOriginSecure(
network::IsUrlPotentiallyTrustworthy(url)),
credentials); credentials);
} }
......
...@@ -22,6 +22,7 @@ using ::testing::ElementsAreArray; ...@@ -22,6 +22,7 @@ using ::testing::ElementsAreArray;
using ::testing::Eq; using ::testing::Eq;
using ::testing::ReturnRefOfCopy; using ::testing::ReturnRefOfCopy;
using ::testing::WithArg; using ::testing::WithArg;
using IsOriginSecure = TouchToFillView::IsOriginSecure;
using IsPublicSuffixMatch = CredentialPair::IsPublicSuffixMatch; using IsPublicSuffixMatch = CredentialPair::IsPublicSuffixMatch;
...@@ -35,8 +36,10 @@ struct MockPasswordManagerDriver : password_manager::StubPasswordManagerDriver { ...@@ -35,8 +36,10 @@ struct MockPasswordManagerDriver : password_manager::StubPasswordManagerDriver {
}; };
struct MockTouchToFillView : TouchToFillView { struct MockTouchToFillView : TouchToFillView {
MOCK_METHOD2(Show, MOCK_METHOD3(Show,
void(base::StringPiece16, base::span<const CredentialPair>)); void(base::StringPiece16,
IsOriginSecure,
base::span<const CredentialPair>));
MOCK_METHOD1(OnCredentialSelected, void(const CredentialPair&)); MOCK_METHOD1(OnCredentialSelected, void(const CredentialPair&));
MOCK_METHOD0(OnDismiss, void()); MOCK_METHOD0(OnDismiss, void());
}; };
...@@ -73,8 +76,9 @@ TEST_F(TouchToFillControllerTest, Show_And_Fill) { ...@@ -73,8 +76,9 @@ TEST_F(TouchToFillControllerTest, Show_And_Fill) {
{base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"), {base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"),
GURL(kExampleCom), IsPublicSuffixMatch(false)}}; GURL(kExampleCom), IsPublicSuffixMatch(false)}};
EXPECT_CALL(view(), Show(Eq(base::ASCIIToUTF16("example.com")), EXPECT_CALL(view(),
ElementsAreArray(credentials))); Show(Eq(base::ASCIIToUTF16("example.com")), IsOriginSecure(true),
ElementsAreArray(credentials)));
touch_to_fill_controller().Show(credentials, driver().AsWeakPtr()); touch_to_fill_controller().Show(credentials, driver().AsWeakPtr());
// Test that we correctly log the absence of an Android credential. // Test that we correctly log the absence of an Android credential.
...@@ -87,6 +91,20 @@ TEST_F(TouchToFillControllerTest, Show_And_Fill) { ...@@ -87,6 +91,20 @@ TEST_F(TouchToFillControllerTest, Show_And_Fill) {
false, 1); false, 1);
} }
TEST_F(TouchToFillControllerTest, Show_Insecure_Origin) {
EXPECT_CALL(driver(), GetLastCommittedURL())
.WillOnce(ReturnRefOfCopy(GURL("http://example.com")));
CredentialPair credentials[] = {
{base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"),
GURL(kExampleCom), IsPublicSuffixMatch(false)}};
EXPECT_CALL(view(),
Show(Eq(base::ASCIIToUTF16("example.com")), IsOriginSecure(false),
ElementsAreArray(credentials)));
touch_to_fill_controller().Show(credentials, driver().AsWeakPtr());
}
TEST_F(TouchToFillControllerTest, Show_And_Fill_Android_Credential) { TEST_F(TouchToFillControllerTest, Show_And_Fill_Android_Credential) {
// Test multiple credentials with one of them being an Android credential. // Test multiple credentials with one of them being an Android credential.
CredentialPair credentials[] = { CredentialPair credentials[] = {
...@@ -95,8 +113,9 @@ TEST_F(TouchToFillControllerTest, Show_And_Fill_Android_Credential) { ...@@ -95,8 +113,9 @@ TEST_F(TouchToFillControllerTest, Show_And_Fill_Android_Credential) {
{base::ASCIIToUTF16("bob"), base::ASCIIToUTF16("s3cr3t"), {base::ASCIIToUTF16("bob"), base::ASCIIToUTF16("s3cr3t"),
GURL("android://hash@com.example.my"), IsPublicSuffixMatch(false)}}; GURL("android://hash@com.example.my"), IsPublicSuffixMatch(false)}};
EXPECT_CALL(view(), Show(Eq(base::ASCIIToUTF16("example.com")), EXPECT_CALL(view(),
ElementsAreArray(credentials))); Show(Eq(base::ASCIIToUTF16("example.com")), IsOriginSecure(true),
ElementsAreArray(credentials)));
touch_to_fill_controller().Show(credentials, driver().AsWeakPtr()); touch_to_fill_controller().Show(credentials, driver().AsWeakPtr());
// Test that we correctly log the presence of an Android credential. // Test that we correctly log the presence of an Android credential.
...@@ -114,8 +133,9 @@ TEST_F(TouchToFillControllerTest, Dismiss) { ...@@ -114,8 +133,9 @@ TEST_F(TouchToFillControllerTest, Dismiss) {
{base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"), {base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"),
GURL(kExampleCom), IsPublicSuffixMatch(false)}}; GURL(kExampleCom), IsPublicSuffixMatch(false)}};
EXPECT_CALL(view(), Show(Eq(base::ASCIIToUTF16("example.com")), EXPECT_CALL(view(),
ElementsAreArray(credentials))); Show(Eq(base::ASCIIToUTF16("example.com")), IsOriginSecure(true),
ElementsAreArray(credentials)));
touch_to_fill_controller().Show(credentials, driver().AsWeakPtr()); touch_to_fill_controller().Show(credentials, driver().AsWeakPtr());
EXPECT_CALL(driver(), TouchToFillDismissed); EXPECT_CALL(driver(), TouchToFillDismissed);
......
...@@ -51,8 +51,10 @@ class TouchToFillBridge implements TouchToFillComponent.Delegate { ...@@ -51,8 +51,10 @@ class TouchToFillBridge implements TouchToFillComponent.Delegate {
} }
@CalledByNative @CalledByNative
private void showCredentials(String formattedUrl, Credential[] credentials) { private void showCredentials(
mTouchToFillComponent.showCredentials(formattedUrl, Arrays.asList(credentials)); String formattedUrl, boolean isOriginSecure, Credential[] credentials) {
mTouchToFillComponent.showCredentials(
formattedUrl, isOriginSecure, Arrays.asList(credentials));
} }
@Override @Override
......
...@@ -34,8 +34,9 @@ public class TouchToFillCoordinator implements TouchToFillComponent { ...@@ -34,8 +34,9 @@ public class TouchToFillCoordinator implements TouchToFillComponent {
} }
@Override @Override
public void showCredentials(String formattedUrl, List<Credential> credentials) { public void showCredentials(
mMediator.showCredentials(formattedUrl, credentials); String formattedUrl, boolean isOriginSecure, List<Credential> credentials) {
mMediator.showCredentials(formattedUrl, isOriginSecure, credentials);
} }
/** /**
......
...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.touch_to_fill; ...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.touch_to_fill;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ORIGIN_SECURE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
import org.chromium.chrome.browser.touch_to_fill.data.Credential; import org.chromium.chrome.browser.touch_to_fill.data.Credential;
...@@ -27,9 +28,11 @@ class TouchToFillMediator implements TouchToFillProperties.ViewEventListener { ...@@ -27,9 +28,11 @@ class TouchToFillMediator implements TouchToFillProperties.ViewEventListener {
mModel = model; mModel = model;
} }
void showCredentials(String formattedUrl, List<Credential> credentials) { void showCredentials(
String formattedUrl, boolean isOriginSecure, List<Credential> credentials) {
assert credentials != null; assert credentials != null;
mModel.set(FORMATTED_URL, formattedUrl); mModel.set(FORMATTED_URL, formattedUrl);
mModel.set(ORIGIN_SECURE, isOriginSecure);
mModel.set(VISIBLE, true); mModel.set(VISIBLE, true);
mModel.get(CREDENTIAL_LIST).clear(); mModel.get(CREDENTIAL_LIST).clear();
mModel.get(CREDENTIAL_LIST).addAll(credentials); mModel.get(CREDENTIAL_LIST).addAll(credentials);
......
...@@ -16,6 +16,8 @@ class TouchToFillProperties { ...@@ -16,6 +16,8 @@ class TouchToFillProperties {
new PropertyModel.WritableBooleanPropertyKey("visible"); new PropertyModel.WritableBooleanPropertyKey("visible");
static final PropertyModel.WritableObjectPropertyKey<String> FORMATTED_URL = static final PropertyModel.WritableObjectPropertyKey<String> FORMATTED_URL =
new PropertyModel.WritableObjectPropertyKey<>("formatted_url"); new PropertyModel.WritableObjectPropertyKey<>("formatted_url");
static final PropertyModel.WritableBooleanPropertyKey ORIGIN_SECURE =
new PropertyModel.WritableBooleanPropertyKey("origin_secure");
static final PropertyModel.ReadableObjectPropertyKey<ListModel<Credential>> CREDENTIAL_LIST = static final PropertyModel.ReadableObjectPropertyKey<ListModel<Credential>> CREDENTIAL_LIST =
new PropertyModel.ReadableObjectPropertyKey<>("credential_list"); new PropertyModel.ReadableObjectPropertyKey<>("credential_list");
static final PropertyModel.ReadableObjectPropertyKey<ViewEventListener> VIEW_EVENT_LISTENER = static final PropertyModel.ReadableObjectPropertyKey<ViewEventListener> VIEW_EVENT_LISTENER =
...@@ -23,8 +25,10 @@ class TouchToFillProperties { ...@@ -23,8 +25,10 @@ class TouchToFillProperties {
static PropertyModel createDefaultModel(ViewEventListener listener) { static PropertyModel createDefaultModel(ViewEventListener listener) {
return new PropertyModel return new PropertyModel
.Builder(VISIBLE, FORMATTED_URL, CREDENTIAL_LIST, VIEW_EVENT_LISTENER) .Builder(
VISIBLE, FORMATTED_URL, ORIGIN_SECURE, CREDENTIAL_LIST, VIEW_EVENT_LISTENER)
.with(VISIBLE, false) .with(VISIBLE, false)
.with(ORIGIN_SECURE, false)
.with(CREDENTIAL_LIST, new ListModel<>()) .with(CREDENTIAL_LIST, new ListModel<>())
.with(VIEW_EVENT_LISTENER, listener) .with(VIEW_EVENT_LISTENER, listener)
.build(); .build();
......
...@@ -84,13 +84,23 @@ class TouchToFillView implements BottomSheet.BottomSheetContent { ...@@ -84,13 +84,23 @@ class TouchToFillView implements BottomSheet.BottomSheetContent {
} }
/** /**
* Renders the given url into the subtitle. * Renders the given secure url into the subtitle.
* @param formattedUrl A {@link String} containing a URL already formatted to display. * @param formattedUrl A {@link String} containing a URL already formatted to display.
*/ */
void setFormattedUrl(String formattedUrl) { void setSecureSubtitle(String formattedUrl) {
TextView sheetSubtitleText = mContentView.findViewById(R.id.touch_to_fill_sheet_subtitle); TextView sheetSubtitleText = mContentView.findViewById(R.id.touch_to_fill_sheet_subtitle);
sheetSubtitleText.setText(String.format( sheetSubtitleText.setText(formattedUrl);
mContext.getString(R.string.touch_to_fill_sheet_subtitle), formattedUrl)); }
/**
* Renders the given non-secure url into the subtitle.
* @param formattedUrl A {@link String} containing a URL already formatted to display.
*/
void setNonSecureSubtitle(String formattedUrl) {
TextView sheetSubtitleText = mContentView.findViewById(R.id.touch_to_fill_sheet_subtitle);
String subtitleText = String.format(
mContext.getString(R.string.touch_to_fill_sheet_subtitle_not_secure), formattedUrl);
sheetSubtitleText.setText(subtitleText);
} }
void setCredentialListAdapter(ListAdapter adapter) { void setCredentialListAdapter(ListAdapter adapter) {
......
...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.touch_to_fill; ...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.touch_to_fill;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ORIGIN_SECURE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VIEW_EVENT_LISTENER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VIEW_EVENT_LISTENER;
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;
...@@ -67,8 +68,12 @@ class TouchToFillViewBinder { ...@@ -67,8 +68,12 @@ class TouchToFillViewBinder {
view.setEventListener(model.get(VIEW_EVENT_LISTENER)); view.setEventListener(model.get(VIEW_EVENT_LISTENER));
} else if (propertyKey == VISIBLE) { } else if (propertyKey == VISIBLE) {
view.setVisible(model.get(VISIBLE)); view.setVisible(model.get(VISIBLE));
} else if (propertyKey == FORMATTED_URL) { } else if (propertyKey == FORMATTED_URL || propertyKey == ORIGIN_SECURE) {
view.setFormattedUrl(model.get(FORMATTED_URL)); if (model.get(ORIGIN_SECURE)) {
view.setSecureSubtitle(model.get(FORMATTED_URL));
} else {
view.setNonSecureSubtitle(model.get(FORMATTED_URL));
}
} else if (propertyKey == CREDENTIAL_LIST) { } else if (propertyKey == CREDENTIAL_LIST) {
// No binding required. Single items are bound via bindCredentialView. // No binding required. Single items are bound via bindCredentialView.
} else { } else {
......
...@@ -110,8 +110,8 @@ ...@@ -110,8 +110,8 @@
<message name="IDS_TOUCH_TO_FILL_SHEET_TITLE" desc="Header for Touch To Fill sheet where users can pick a credential to fill into a form to."> <message name="IDS_TOUCH_TO_FILL_SHEET_TITLE" desc="Header for Touch To Fill sheet where users can pick a credential to fill into a form to.">
Choose an account Choose an account
</message> </message>
<message name="IDS_TOUCH_TO_FILL_SHEET_SUBTITLE" desc="Subtitle for Touch To Fill sheet where users can pick a credential to fill into a form to."> <message name="IDS_TOUCH_TO_FILL_SHEET_SUBTITLE_NOT_SECURE" desc="Subtitle for Touch To Fill sheet when the website is not secure. Note that similarly to the omnibox 'not secure' in this case primarily refers to HTTPS connection security. So prefer translations with a connotation of 'not private' (someone can intercept your communication with the site) rather than 'not trustworthy' (which would be a judgment of site reputation).">
for <ph name="SITE_NAME">%1$s<ex>airbnb.com</ex></ph> <ph name="SITE_NAME">%1$s<ex>airbnb.com</ex> (not secure)</ph>
</message> </message>
<message name="IDS_TOUCH_TO_FILL_CONTENT_DESCRIPTION" desc="Accessibility string read when the Touch To Fill bottom sheet is opened. It describes the bottom sheet where a user can pick a credential to fill into a password form."> <message name="IDS_TOUCH_TO_FILL_CONTENT_DESCRIPTION" desc="Accessibility string read when the Touch To Fill bottom sheet is opened. It describes the bottom sheet where a user can pick a credential to fill into a password form.">
List of credentials to be filled on touch. List of credentials to be filled on touch.
......
...@@ -44,7 +44,8 @@ public interface TouchToFillComponent { ...@@ -44,7 +44,8 @@ public interface TouchToFillComponent {
/** /**
* Displays the given credentials in a new bottom sheet. * Displays the given credentials in a new bottom sheet.
* @param formattedUrl A {@link String} that contains the URL to display credentials for. * @param formattedUrl A {@link String} that contains the URL to display credentials for.
* @param isOriginSecure A {@link boolean} that indicates whether the current origin is secure.
* @param credentials A list of {@link Credential}s that will be displayed. * @param credentials A list of {@link Credential}s that will be displayed.
*/ */
void showCredentials(String formattedUrl, List<Credential> credentials); void showCredentials(String formattedUrl, boolean isOriginSecure, List<Credential> credentials);
} }
...@@ -76,8 +76,9 @@ public class TouchToFillIntegrationTest { ...@@ -76,8 +76,9 @@ public class TouchToFillIntegrationTest {
@MediumTest @MediumTest
@DisabledTest(message = "crbug.com/1012221") @DisabledTest(message = "crbug.com/1012221")
public void testClickingSuggestionsTriggersCallback() { public void testClickingSuggestionsTriggersCallback() {
runOnUiThreadBlocking( runOnUiThreadBlocking(() -> {
() -> { mTouchToFill.showCredentials(EXAMPLE_URL, Arrays.asList(ANA, BOB)); }); mTouchToFill.showCredentials(EXAMPLE_URL, true, Arrays.asList(ANA, BOB));
});
pollUiThread(() -> getBottomSheetState() == SheetState.FULL); pollUiThread(() -> getBottomSheetState() == SheetState.FULL);
pollUiThread(() -> getCredentials().getChildAt(1) != null); pollUiThread(() -> getCredentials().getChildAt(1) != null);
...@@ -90,8 +91,9 @@ public class TouchToFillIntegrationTest { ...@@ -90,8 +91,9 @@ public class TouchToFillIntegrationTest {
@Test @Test
@MediumTest @MediumTest
public void testBackDismissesAndCallsCallback() { public void testBackDismissesAndCallsCallback() {
runOnUiThreadBlocking( runOnUiThreadBlocking(() -> {
() -> { mTouchToFill.showCredentials(EXAMPLE_URL, Arrays.asList(ANA, BOB)); }); mTouchToFill.showCredentials(EXAMPLE_URL, true, Arrays.asList(ANA, BOB));
});
pollUiThread(() -> getBottomSheetState() == SheetState.FULL); pollUiThread(() -> getBottomSheetState() == SheetState.FULL);
Espresso.pressBack(); Espresso.pressBack();
......
...@@ -13,6 +13,7 @@ import static org.mockito.Mockito.verify; ...@@ -13,6 +13,7 @@ import static org.mockito.Mockito.verify;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ORIGIN_SECURE;
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;
...@@ -93,17 +94,21 @@ public class TouchToFillViewTest { ...@@ -93,17 +94,21 @@ public class TouchToFillViewTest {
public void testSubtitleUrlChangedByModel() { public void testSubtitleUrlChangedByModel() {
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
mModel.set(FORMATTED_URL, "www.example.org"); mModel.set(FORMATTED_URL, "www.example.org");
mModel.set(ORIGIN_SECURE, true);
mModel.set(VISIBLE, true); mModel.set(VISIBLE, true);
}); });
pollUiThread(() -> getBottomSheetState() == SheetState.FULL); pollUiThread(() -> getBottomSheetState() == SheetState.FULL);
TextView subtitle = TextView subtitle =
mTouchToFillView.getContentView().findViewById(R.id.touch_to_fill_sheet_subtitle); mTouchToFillView.getContentView().findViewById(R.id.touch_to_fill_sheet_subtitle);
assertThat(subtitle.getText(), is(getFormattedSubtitle("www.example.org"))); assertThat(subtitle.getText(), is("www.example.org"));
TestThreadUtils.runOnUiThreadBlocking(() -> mModel.set(FORMATTED_URL, "m.example.org")); TestThreadUtils.runOnUiThreadBlocking(() -> {
mModel.set(FORMATTED_URL, "m.example.org");
mModel.set(ORIGIN_SECURE, false);
});
assertThat(subtitle.getText(), is(getFormattedSubtitle("m.example.org"))); assertThat(subtitle.getText(), is(getFormattedNotSecureSubtitle("m.example.org")));
} }
@Test @Test
...@@ -171,8 +176,8 @@ public class TouchToFillViewTest { ...@@ -171,8 +176,8 @@ public class TouchToFillViewTest {
return mActivityTestRule.getActivity(); return mActivityTestRule.getActivity();
} }
private String getFormattedSubtitle(String url) { private String getFormattedNotSecureSubtitle(String url) {
return getActivity().getString(R.string.touch_to_fill_sheet_subtitle, url); return getActivity().getString(R.string.touch_to_fill_sheet_subtitle_not_secure, url);
} }
private @SheetState int getBottomSheetState() { private @SheetState int getBottomSheetState() {
...@@ -200,4 +205,4 @@ public class TouchToFillViewTest { ...@@ -200,4 +205,4 @@ public class TouchToFillViewTest {
return verify(mMockListener, return verify(mMockListener,
timeout(ScalableTimeout.scaleTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL))); timeout(ScalableTimeout.scaleTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL)));
} }
} }
\ No newline at end of file
...@@ -12,6 +12,7 @@ import static org.mockito.Mockito.verify; ...@@ -12,6 +12,7 @@ import static org.mockito.Mockito.verify;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ORIGIN_SECURE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VIEW_EVENT_LISTENER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VIEW_EVENT_LISTENER;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
...@@ -62,17 +63,19 @@ public class TouchToFillControllerTest { ...@@ -62,17 +63,19 @@ public class TouchToFillControllerTest {
assertNotNull(mModel.get(VIEW_EVENT_LISTENER)); assertNotNull(mModel.get(VIEW_EVENT_LISTENER));
assertThat(mModel.get(VISIBLE), is(false)); assertThat(mModel.get(VISIBLE), is(false));
assertThat(mModel.get(FORMATTED_URL), is(nullValue())); assertThat(mModel.get(FORMATTED_URL), is(nullValue()));
assertThat(mModel.get(ORIGIN_SECURE), is(false));
} }
@Test @Test
public void testShowCredentialsSetsFormattedUrl() { public void testShowCredentialsSetsFormattedUrl() {
mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL, BOB)); mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
assertThat(mModel.get(FORMATTED_URL), is(TEST_URL)); assertThat(mModel.get(FORMATTED_URL), is(TEST_URL));
assertThat(mModel.get(ORIGIN_SECURE), is(true));
} }
@Test @Test
public void testShowCredentialsSetsCredentialList() { public void testShowCredentialsSetsCredentialList() {
mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL, BOB)); mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
assertThat(mModel.get(CREDENTIAL_LIST).size(), is(3)); assertThat(mModel.get(CREDENTIAL_LIST).size(), is(3));
assertThat(mModel.get(CREDENTIAL_LIST).get(0), is(ANA)); assertThat(mModel.get(CREDENTIAL_LIST).get(0), is(ANA));
assertThat(mModel.get(CREDENTIAL_LIST).get(1), is(CARL)); assertThat(mModel.get(CREDENTIAL_LIST).get(1), is(CARL));
...@@ -81,25 +84,25 @@ public class TouchToFillControllerTest { ...@@ -81,25 +84,25 @@ public class TouchToFillControllerTest {
@Test @Test
public void testClearsCredentialListWhenShowingAgain() { public void testClearsCredentialListWhenShowingAgain() {
mMediator.showCredentials(TEST_URL, Collections.singletonList(ANA)); mMediator.showCredentials(TEST_URL, true, Collections.singletonList(ANA));
assertThat(mModel.get(CREDENTIAL_LIST).size(), is(1)); assertThat(mModel.get(CREDENTIAL_LIST).size(), is(1));
assertThat(mModel.get(CREDENTIAL_LIST).get(0), is(ANA)); assertThat(mModel.get(CREDENTIAL_LIST).get(0), is(ANA));
// Showing the sheet a second time should replace all changed credentials. // Showing the sheet a second time should replace all changed credentials.
mMediator.showCredentials(TEST_URL, Collections.singletonList(BOB)); mMediator.showCredentials(TEST_URL, true, Collections.singletonList(BOB));
assertThat(mModel.get(CREDENTIAL_LIST).size(), is(1)); assertThat(mModel.get(CREDENTIAL_LIST).size(), is(1));
assertThat(mModel.get(CREDENTIAL_LIST).get(0), is(BOB)); assertThat(mModel.get(CREDENTIAL_LIST).get(0), is(BOB));
} }
@Test @Test
public void testShowCredentialsSetsVisibile() { public void testShowCredentialsSetsVisibile() {
mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL, BOB)); mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
assertThat(mModel.get(VISIBLE), is(true)); assertThat(mModel.get(VISIBLE), is(true));
} }
@Test @Test
public void testCallsCallbackAndHidesOnSelectingItem() { public void testCallsCallbackAndHidesOnSelectingItem() {
mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL)); mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL));
mMediator.onSelectItemAt(1); mMediator.onSelectItemAt(1);
verify(mMockDelegate).onCredentialSelected(CARL); verify(mMockDelegate).onCredentialSelected(CARL);
assertThat(mModel.get(VISIBLE), is(false)); assertThat(mModel.get(VISIBLE), is(false));
...@@ -107,7 +110,7 @@ public class TouchToFillControllerTest { ...@@ -107,7 +110,7 @@ public class TouchToFillControllerTest {
@Test @Test
public void testCallsDelegateAndHidesOnDismiss() { public void testCallsDelegateAndHidesOnDismiss() {
mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL)); mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL));
mMediator.onDismissed(); mMediator.onDismissed();
verify(mMockDelegate).onDismissed(); verify(mMockDelegate).onDismissed();
assertThat(mModel.get(VISIBLE), is(false)); assertThat(mModel.get(VISIBLE), is(false));
......
...@@ -57,6 +57,7 @@ TouchToFillViewImpl::~TouchToFillViewImpl() { ...@@ -57,6 +57,7 @@ TouchToFillViewImpl::~TouchToFillViewImpl() {
void TouchToFillViewImpl::Show( void TouchToFillViewImpl::Show(
base::StringPiece16 formatted_url, base::StringPiece16 formatted_url,
IsOriginSecure is_origin_secure,
base::span<const password_manager::CredentialPair> credentials) { base::span<const password_manager::CredentialPair> credentials) {
// Serialize the |credentials| span into a Java array and instruct the bridge // Serialize the |credentials| span into a Java array and instruct the bridge
// to show it together with |formatted_url| to the user. // to show it together with |formatted_url| to the user.
...@@ -76,7 +77,7 @@ void TouchToFillViewImpl::Show( ...@@ -76,7 +77,7 @@ void TouchToFillViewImpl::Show(
Java_TouchToFillBridge_showCredentials( Java_TouchToFillBridge_showCredentials(
env, java_object_, ConvertUTF16ToJavaString(env, formatted_url), env, java_object_, ConvertUTF16ToJavaString(env, formatted_url),
credential_array); is_origin_secure.value(), credential_array);
} }
void TouchToFillViewImpl::OnCredentialSelected( void TouchToFillViewImpl::OnCredentialSelected(
......
...@@ -21,6 +21,7 @@ class TouchToFillViewImpl : public TouchToFillView { ...@@ -21,6 +21,7 @@ class TouchToFillViewImpl : public TouchToFillView {
// TouchToFillView: // TouchToFillView:
void Show( void Show(
base::StringPiece16 formatted_url, base::StringPiece16 formatted_url,
IsOriginSecure is_origin_secure,
base::span<const password_manager::CredentialPair> credentials) override; base::span<const password_manager::CredentialPair> credentials) override;
void OnCredentialSelected( void OnCredentialSelected(
const password_manager::CredentialPair& credential) override; const password_manager::CredentialPair& credential) override;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/containers/span.h" #include "base/containers/span.h"
#include "base/strings/string_piece_forward.h" #include "base/strings/string_piece_forward.h"
#include "base/util/type_safety/strong_alias.h"
namespace password_manager { namespace password_manager {
struct CredentialPair; struct CredentialPair;
...@@ -17,6 +18,8 @@ struct CredentialPair; ...@@ -17,6 +18,8 @@ struct CredentialPair;
// To Fill controller with the Android frontend. // To Fill controller with the Android frontend.
class TouchToFillView { class TouchToFillView {
public: public:
using IsOriginSecure = util::StrongAlias<class IsOriginSecureTag, bool>;
TouchToFillView() = default; TouchToFillView() = default;
TouchToFillView(const TouchToFillView&) = delete; TouchToFillView(const TouchToFillView&) = delete;
TouchToFillView& operator=(const TouchToFillView&) = delete; TouchToFillView& operator=(const TouchToFillView&) = delete;
...@@ -24,10 +27,12 @@ class TouchToFillView { ...@@ -24,10 +27,12 @@ class TouchToFillView {
// Instructs Touch To Fill to show the provided |credentials| to the user. // Instructs Touch To Fill to show the provided |credentials| to the user.
// |formatted_url| contains a human friendly version of the current origin. // |formatted_url| contains a human friendly version of the current origin.
// |is_origin_secure| indicates whether the current frame origin is secure.
// After user interaction either OnCredentialSelected() or OnDismiss() gets // After user interaction either OnCredentialSelected() or OnDismiss() gets
// invoked. // invoked.
virtual void Show( virtual void Show(
base::StringPiece16 formatted_url, base::StringPiece16 formatted_url,
IsOriginSecure is_origin_secure,
base::span<const password_manager::CredentialPair> credentials) = 0; base::span<const password_manager::CredentialPair> credentials) = 0;
// Invoked in case the user chooses an entry from the credential list // Invoked in case the user chooses an entry from the credential list
......
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