Commit 0276c4cc authored by Eleonora Rocchi's avatar Eleonora Rocchi Committed by Commit Bot

Reland "[PwdCheckAndroid] Add redirect to Google Password Check on quota limit"

This reverts commit 19ec1bc6.

Reason for reland: fix broken test

Original change's description:
> Revert "[PwdCheckAndroid] Add redirect to Google Password Check on quota limit"
>
> This reverts commit b27232d7.
>
> Reason for revert: Test failures, see crbug.com/1117676
>
> Original change's description:
> > [PwdCheckAndroid] Add redirect to Google Password Check on quota limit
> >
> > This CL adds the logic to redirect the user to the Google Password
> > Check on quota limit error. The redirect is called through
> > PasswordCheckBridge to avoid dependencies on chrome_java.
> >
> > IDS_PASSWORD_CHECK_STATUS_MESSAGE_ERROR_QUOTA_LIMIT_ACCOUNT_CHECK.png
> > https://storage.cloud.google.com/chromium-translation-screenshots/c4546cf199aa6314ead807fa1fc0e1ed8b779a83
> >
> > Bug: 1092444
> > Change-Id: I374ad088c305d299fea00f412f27dd6ab3d0e9b5
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2362023
> > Reviewed-by: Ioana Pandele <ioanap@chromium.org>
> > Reviewed-by: Friedrich [CET] <fhorschig@chromium.org>
> > Commit-Queue: Eleonora Rocchi <erocchi@google.com>
> > Cr-Commit-Position: refs/heads/master@{#799117}
>
> TBR=fhorschig@chromium.org,ioanap@chromium.org,erocchi@google.com
>
> Change-Id: I38a6779f2a9a278317ab5ce2be2edb0742e34f34
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: 1092444
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2363444
> Reviewed-by: Sky Malice <skym@chromium.org>
> Commit-Queue: Sky Malice <skym@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#799397}

TBR=skym@chromium.org,fhorschig@chromium.org,ioanap@chromium.org,erocchi@google.com

# Not skipping CQ checks because this is a reland.

Bug: 1117676, 1092444
Change-Id: Ib8ffb9cd0b18b5454ffcfa48f8e890d087f5bc42
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2362823Reviewed-by: default avatarFriedrich [CET] <fhorschig@chromium.org>
Reviewed-by: default avatarIoana Pandele <ioanap@chromium.org>
Commit-Queue: Eleonora Rocchi <erocchi@google.com>
Cr-Commit-Position: refs/heads/master@{#800102}
parent 21201bbe
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
package org.chromium.chrome.browser.password_manager; package org.chromium.chrome.browser.password_manager;
import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
...@@ -19,13 +20,11 @@ import org.chromium.ui.base.WindowAndroid; ...@@ -19,13 +20,11 @@ import org.chromium.ui.base.WindowAndroid;
*/ */
public class PasswordCheckupLauncher { public class PasswordCheckupLauncher {
@CalledByNative @CalledByNative
private static void launchCheckupInAccount(String checkupUrl, WindowAndroid windowAndroid) { private static void launchCheckupInAccountWithWindowAndroid(
String checkupUrl, WindowAndroid windowAndroid) {
if (windowAndroid.getContext().get() == null) return; // Window not available yet/anymore. if (windowAndroid.getContext().get() == null) return; // Window not available yet/anymore.
ChromeActivity activity = (ChromeActivity) windowAndroid.getActivity().get(); ChromeActivity activity = (ChromeActivity) windowAndroid.getActivity().get();
if (tryLaunchingNativePasswordCheckup(activity)) return; launchCheckupInAccountWithActivity(checkupUrl, activity);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(checkupUrl));
intent.setPackage(activity.getPackageName());
activity.startActivity(intent);
} }
@CalledByNative @CalledByNative
...@@ -36,7 +35,15 @@ public class PasswordCheckupLauncher { ...@@ -36,7 +35,15 @@ public class PasswordCheckupLauncher {
windowAndroid.getContext().get(), PasswordCheckReferrer.LEAK_DIALOG); windowAndroid.getContext().get(), PasswordCheckReferrer.LEAK_DIALOG);
} }
private static boolean tryLaunchingNativePasswordCheckup(ChromeActivity activity) { @CalledByNative
private static void launchCheckupInAccountWithActivity(String checkupUrl, Activity activity) {
if (tryLaunchingNativePasswordCheckup(activity)) return;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(checkupUrl));
intent.setPackage(activity.getPackageName());
activity.startActivity(intent);
}
private static boolean tryLaunchingNativePasswordCheckup(Activity activity) {
GooglePasswordManagerUIProvider googlePasswordManagerUIProvider = GooglePasswordManagerUIProvider googlePasswordManagerUIProvider =
AppHooks.get().createGooglePasswordManagerUIProvider(); AppHooks.get().createGooglePasswordManagerUIProvider();
if (googlePasswordManagerUIProvider == null) return false; if (googlePasswordManagerUIProvider == null) return false;
......
...@@ -2854,6 +2854,8 @@ static_library("browser") { ...@@ -2854,6 +2854,8 @@ static_library("browser") {
"password_manager/android/password_accessory_controller_impl.cc", "password_manager/android/password_accessory_controller_impl.cc",
"password_manager/android/password_accessory_controller_impl.h", "password_manager/android/password_accessory_controller_impl.h",
"password_manager/android/password_accessory_metrics_util.h", "password_manager/android/password_accessory_metrics_util.h",
"password_manager/android/password_checkup_launcher_helper.cc",
"password_manager/android/password_checkup_launcher_helper.h",
"password_manager/android/password_generation_controller.h", "password_manager/android/password_generation_controller.h",
"password_manager/android/password_generation_controller_impl.cc", "password_manager/android/password_generation_controller_impl.cc",
"password_manager/android/password_generation_controller_impl.h", "password_manager/android/password_generation_controller_impl.h",
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package org.chromium.chrome.browser.password_check; package org.chromium.chrome.browser.password_check;
import android.app.Activity;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.url.GURL; import org.chromium.url.GURL;
...@@ -152,6 +154,13 @@ class PasswordCheckBridge { ...@@ -152,6 +154,13 @@ class PasswordCheckBridge {
mNativePasswordCheckBridge, credentials); mNativePasswordCheckBridge, credentials);
} }
/**
* Launch the password check in the Google Account.
*/
void launchCheckupInAccount(Activity activity) {
PasswordCheckBridgeJni.get().launchCheckupInAccount(mNativePasswordCheckBridge, activity);
}
void updateCredential(CompromisedCredential credential, String newPassword) { void updateCredential(CompromisedCredential credential, String newPassword) {
PasswordCheckBridgeJni.get().updateCredential( PasswordCheckBridgeJni.get().updateCredential(
mNativePasswordCheckBridge, credential, newPassword); mNativePasswordCheckBridge, credential, newPassword);
...@@ -186,6 +195,7 @@ class PasswordCheckBridge { ...@@ -186,6 +195,7 @@ class PasswordCheckBridge {
int getSavedPasswordsCount(long nativePasswordCheckBridge); int getSavedPasswordsCount(long nativePasswordCheckBridge);
void getCompromisedCredentials( void getCompromisedCredentials(
long nativePasswordCheckBridge, CompromisedCredential[] credentials); long nativePasswordCheckBridge, CompromisedCredential[] credentials);
void launchCheckupInAccount(long nativePasswordCheckBridge, Activity activity);
void updateCredential(long nativePasswordCheckBridge, CompromisedCredential credential, void updateCredential(long nativePasswordCheckBridge, CompromisedCredential credential,
String newPassword); String newPassword);
void removeCredential(long nativePasswordCheckBridge, CompromisedCredential credentials); void removeCredential(long nativePasswordCheckBridge, CompromisedCredential credentials);
......
...@@ -79,14 +79,18 @@ class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObs ...@@ -79,14 +79,18 @@ class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObs
mReauthenticationHelper); mReauthenticationHelper);
} }
private void launchCheckupInAccount() {
PasswordCheckFactory.getOrCreate().launchCheckupInAccount(mFragmentView.getActivity());
}
@Override @Override
public void onStartFragment() { public void onStartFragment() {
// In the rare case of a restarted activity, don't recreate the model and mediator. // In the rare case of a restarted activity, don't recreate the model and mediator.
if (mModel == null) { if (mModel == null) {
mModel = PasswordCheckProperties.createDefaultModel(); mModel = PasswordCheckProperties.createDefaultModel();
PasswordCheckCoordinator.setUpModelChangeProcessors(mModel, mFragmentView); PasswordCheckCoordinator.setUpModelChangeProcessors(mModel, mFragmentView);
mMediator.initialize( mMediator.initialize(mModel, PasswordCheckFactory.getOrCreate(),
mModel, PasswordCheckFactory.getOrCreate(), mFragmentView.getReferrer()); mFragmentView.getReferrer(), this::launchCheckupInAccount);
} }
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.password_check; package org.chromium.chrome.browser.password_check;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
...@@ -128,6 +129,11 @@ class PasswordCheckImpl implements PasswordCheck, PasswordCheckObserver { ...@@ -128,6 +129,11 @@ class PasswordCheckImpl implements PasswordCheck, PasswordCheckObserver {
return mPasswordCheckBridge.getSavedPasswordsCount(); return mPasswordCheckBridge.getSavedPasswordsCount();
} }
@Override
public void launchCheckupInAccount(Activity activity) {
mPasswordCheckBridge.launchCheckupInAccount(activity);
}
@Override @Override
public void startCheck() { public void startCheck() {
mPasswordCheckBridge.startCheck(); mPasswordCheckBridge.startCheck();
......
...@@ -13,6 +13,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties ...@@ -13,6 +13,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_TIMESTAMP; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_TIMESTAMP;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.COMPROMISED_CREDENTIALS_COUNT; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.COMPROMISED_CREDENTIALS_COUNT;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.LAUNCH_ACCOUNT_CHECKUP_ACTION;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.RESTART_BUTTON_ACTION; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.RESTART_BUTTON_ACTION;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.UNKNOWN_PROGRESS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.UNKNOWN_PROGRESS;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS;
...@@ -39,6 +40,7 @@ class PasswordCheckMediator ...@@ -39,6 +40,7 @@ class PasswordCheckMediator
private final PasswordCheckChangePasswordHelper mChangePasswordDelegate; private final PasswordCheckChangePasswordHelper mChangePasswordDelegate;
private PropertyModel mModel; private PropertyModel mModel;
private PasswordCheckComponentUi.Delegate mDelegate; private PasswordCheckComponentUi.Delegate mDelegate;
private Runnable mLaunchCheckupInAccount;
PasswordCheckMediator(PasswordCheckChangePasswordHelper changePasswordDelegate, PasswordCheckMediator(PasswordCheckChangePasswordHelper changePasswordDelegate,
PasswordCheckReauthenticationHelper reauthenticationHelper) { PasswordCheckReauthenticationHelper reauthenticationHelper) {
...@@ -47,9 +49,10 @@ class PasswordCheckMediator ...@@ -47,9 +49,10 @@ class PasswordCheckMediator
} }
void initialize(PropertyModel model, PasswordCheckComponentUi.Delegate delegate, void initialize(PropertyModel model, PasswordCheckComponentUi.Delegate delegate,
@PasswordCheckReferrer int passwordCheckReferrer) { @PasswordCheckReferrer int passwordCheckReferrer, Runnable launchCheckupInAccount) {
mModel = model; mModel = model;
mDelegate = delegate; mDelegate = delegate;
mLaunchCheckupInAccount = launchCheckupInAccount;
// If a run is scheduled to happen soon, initialize the UI as running to prevent flickering. // If a run is scheduled to happen soon, initialize the UI as running to prevent flickering.
// Otherwise, initialize the UI with last known state (defaults to IDLE before first run). // Otherwise, initialize the UI with last known state (defaults to IDLE before first run).
...@@ -76,6 +79,7 @@ class PasswordCheckMediator ...@@ -76,6 +79,7 @@ class PasswordCheckMediator
items.add(new ListItem(PasswordCheckProperties.ItemType.HEADER, items.add(new ListItem(PasswordCheckProperties.ItemType.HEADER,
new PropertyModel.Builder(PasswordCheckProperties.HeaderProperties.ALL_KEYS) new PropertyModel.Builder(PasswordCheckProperties.HeaderProperties.ALL_KEYS)
.with(CHECK_STATUS, PasswordCheckUIStatus.RUNNING) .with(CHECK_STATUS, PasswordCheckUIStatus.RUNNING)
.with(LAUNCH_ACCOUNT_CHECKUP_ACTION, mLaunchCheckupInAccount)
.with(RESTART_BUTTON_ACTION, this::runCheck) .with(RESTART_BUTTON_ACTION, this::runCheck)
.build())); .build()));
} }
...@@ -99,6 +103,7 @@ class PasswordCheckMediator ...@@ -99,6 +103,7 @@ class PasswordCheckMediator
.with(CHECK_STATUS, PasswordCheckUIStatus.RUNNING) .with(CHECK_STATUS, PasswordCheckUIStatus.RUNNING)
.with(CHECK_TIMESTAMP, null) .with(CHECK_TIMESTAMP, null)
.with(COMPROMISED_CREDENTIALS_COUNT, null) .with(COMPROMISED_CREDENTIALS_COUNT, null)
.with(LAUNCH_ACCOUNT_CHECKUP_ACTION, mLaunchCheckupInAccount)
.with(RESTART_BUTTON_ACTION, this::runCheck) .with(RESTART_BUTTON_ACTION, this::runCheck)
.build(); .build();
} else { } else {
......
...@@ -67,11 +67,15 @@ class PasswordCheckProperties { ...@@ -67,11 +67,15 @@ class PasswordCheckProperties {
static final PropertyModel static final PropertyModel
.WritableObjectPropertyKey<Integer> COMPROMISED_CREDENTIALS_COUNT = .WritableObjectPropertyKey<Integer> COMPROMISED_CREDENTIALS_COUNT =
new PropertyModel.WritableObjectPropertyKey<>("compromised_credentials_count"); new PropertyModel.WritableObjectPropertyKey<>("compromised_credentials_count");
static final PropertyModel
.ReadableObjectPropertyKey<Runnable> LAUNCH_ACCOUNT_CHECKUP_ACTION =
new PropertyModel.ReadableObjectPropertyKey<>("launch_account_checkup_action");
static final PropertyModel.ReadableObjectPropertyKey<Runnable> RESTART_BUTTON_ACTION = static final PropertyModel.ReadableObjectPropertyKey<Runnable> RESTART_BUTTON_ACTION =
new PropertyModel.WritableObjectPropertyKey<>("restart_button_action"); new PropertyModel.ReadableObjectPropertyKey<>("restart_button_action");
static final PropertyKey[] ALL_KEYS = {CHECK_PROGRESS, CHECK_STATUS, CHECK_TIMESTAMP, static final PropertyKey[] ALL_KEYS = {CHECK_PROGRESS, CHECK_STATUS, CHECK_TIMESTAMP,
COMPROMISED_CREDENTIALS_COUNT, RESTART_BUTTON_ACTION}; COMPROMISED_CREDENTIALS_COUNT, LAUNCH_ACCOUNT_CHECKUP_ACTION,
RESTART_BUTTON_ACTION};
static final Pair<Integer, Integer> UNKNOWN_PROGRESS = new Pair<>(-1, -1); static final Pair<Integer, Integer> UNKNOWN_PROGRESS = new Pair<>(-1, -1);
......
...@@ -13,6 +13,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties ...@@ -13,6 +13,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_TIMESTAMP; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_TIMESTAMP;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.COMPROMISED_CREDENTIALS_COUNT; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.COMPROMISED_CREDENTIALS_COUNT;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.LAUNCH_ACCOUNT_CHECKUP_ACTION;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.RESTART_BUTTON_ACTION; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.RESTART_BUTTON_ACTION;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.UNKNOWN_PROGRESS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.UNKNOWN_PROGRESS;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS;
...@@ -20,6 +21,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties ...@@ -20,6 +21,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.method.LinkMovementMethod;
import android.util.Pair; import android.util.Pair;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
...@@ -45,6 +47,8 @@ import org.chromium.ui.modelutil.PropertyKey; ...@@ -45,6 +47,8 @@ import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.RecyclerViewAdapter; import org.chromium.ui.modelutil.RecyclerViewAdapter;
import org.chromium.ui.modelutil.SimpleRecyclerViewMcp; import org.chromium.ui.modelutil.SimpleRecyclerViewMcp;
import org.chromium.ui.text.NoUnderlineClickableSpan;
import org.chromium.ui.text.SpanApplier;
import org.chromium.ui.widget.ButtonCompat; import org.chromium.ui.widget.ButtonCompat;
/** /**
...@@ -191,22 +195,30 @@ class PasswordCheckViewBinder { ...@@ -191,22 +195,30 @@ class PasswordCheckViewBinder {
int status = model.get(CHECK_STATUS); int status = model.get(CHECK_STATUS);
Long checkTimestamp = model.get(CHECK_TIMESTAMP); Long checkTimestamp = model.get(CHECK_TIMESTAMP);
Integer compromisedCredentialsCount = model.get(COMPROMISED_CREDENTIALS_COUNT); Integer compromisedCredentialsCount = model.get(COMPROMISED_CREDENTIALS_COUNT);
Runnable launchCheckupInAccount = model.get(LAUNCH_ACCOUNT_CHECKUP_ACTION);
if (key == CHECK_PROGRESS) { if (key == CHECK_PROGRESS) {
updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress); updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress,
launchCheckupInAccount);
} else if (key == CHECK_STATUS) { } else if (key == CHECK_STATUS) {
updateActionButton(view, status, model.get(RESTART_BUTTON_ACTION)); updateActionButton(view, status, model.get(RESTART_BUTTON_ACTION));
updateStatusIcon(view, status, compromisedCredentialsCount); updateStatusIcon(view, status, compromisedCredentialsCount);
updateStatusIllustration(view, status, compromisedCredentialsCount); updateStatusIllustration(view, status, compromisedCredentialsCount);
updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress); updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress,
launchCheckupInAccount);
updateStatusSubtitle(view, status, compromisedCredentialsCount); updateStatusSubtitle(view, status, compromisedCredentialsCount);
} else if (key == CHECK_TIMESTAMP) { } else if (key == CHECK_TIMESTAMP) {
updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress); updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress,
launchCheckupInAccount);
} else if (key == COMPROMISED_CREDENTIALS_COUNT) { } else if (key == COMPROMISED_CREDENTIALS_COUNT) {
updateStatusIcon(view, status, compromisedCredentialsCount); updateStatusIcon(view, status, compromisedCredentialsCount);
updateStatusIllustration(view, status, compromisedCredentialsCount); updateStatusIllustration(view, status, compromisedCredentialsCount);
updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress); updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress,
launchCheckupInAccount);
updateStatusSubtitle(view, status, compromisedCredentialsCount); updateStatusSubtitle(view, status, compromisedCredentialsCount);
} else if (key == LAUNCH_ACCOUNT_CHECKUP_ACTION) {
assert model.get(LAUNCH_ACCOUNT_CHECKUP_ACTION)
!= null : "Launch checkup in account is always required.";
} else if (key == RESTART_BUTTON_ACTION) { } else if (key == RESTART_BUTTON_ACTION) {
assert model.get(RESTART_BUTTON_ACTION) != null : "Restart action is always required."; assert model.get(RESTART_BUTTON_ACTION) != null : "Restart action is always required.";
} else { } else {
...@@ -273,7 +285,7 @@ class PasswordCheckViewBinder { ...@@ -273,7 +285,7 @@ class PasswordCheckViewBinder {
private static void updateStatusText(View view, @PasswordCheckUIStatus int status, private static void updateStatusText(View view, @PasswordCheckUIStatus int status,
Integer compromisedCredentialsCount, Long checkTimestamp, Integer compromisedCredentialsCount, Long checkTimestamp,
Pair<Integer, Integer> progress) { Pair<Integer, Integer> progress, Runnable launchCheckupInAccount) {
// TODO(crbug.com/1114051): Set default values for header properties. // TODO(crbug.com/1114051): Set default values for header properties.
if (status == PasswordCheckUIStatus.IDLE if (status == PasswordCheckUIStatus.IDLE
&& (compromisedCredentialsCount == null || checkTimestamp == null)) { && (compromisedCredentialsCount == null || checkTimestamp == null)) {
...@@ -282,8 +294,9 @@ class PasswordCheckViewBinder { ...@@ -282,8 +294,9 @@ class PasswordCheckViewBinder {
if (status == PasswordCheckUIStatus.RUNNING && progress == null) return; if (status == PasswordCheckUIStatus.RUNNING && progress == null) return;
TextView statusMessage = view.findViewById(R.id.check_status_message); TextView statusMessage = view.findViewById(R.id.check_status_message);
statusMessage.setText( statusMessage.setText(getStatusMessage(
getStatusMessage(view, status, compromisedCredentialsCount, progress)); view, status, compromisedCredentialsCount, progress, launchCheckupInAccount));
statusMessage.setMovementMethod(LinkMovementMethod.getInstance());
LinearLayout textLayout = view.findViewById(R.id.check_status_text_layout); LinearLayout textLayout = view.findViewById(R.id.check_status_text_layout);
int verticalMargin = getDimensionPixelOffset(view, getStatusTextMargin(status)); int verticalMargin = getDimensionPixelOffset(view, getStatusTextMargin(status));
...@@ -294,14 +307,15 @@ class PasswordCheckViewBinder { ...@@ -294,14 +307,15 @@ class PasswordCheckViewBinder {
statusDescription.setVisibility(getStatusDescriptionVisibility(status)); statusDescription.setVisibility(getStatusDescriptionVisibility(status));
} }
private static String getStatusMessage(View view, @PasswordCheckUIStatus int status, private static CharSequence getStatusMessage(View view, @PasswordCheckUIStatus int status,
Integer compromisedCredentialsCount, Pair<Integer, Integer> progress) { Integer compromisedCredentialsCount, Pair<Integer, Integer> progress,
Runnable launchCheckupInAccount) {
switch (status) { switch (status) {
case PasswordCheckUIStatus.IDLE: case PasswordCheckUIStatus.IDLE:
assert compromisedCredentialsCount != null; assert compromisedCredentialsCount != null;
return compromisedCredentialsCount == 0 return compromisedCredentialsCount == 0
? getString(view, R.string.password_check_status_message_idle_no_leaks) ? getString(view, R.string.password_check_status_message_idle_no_leaks)
: view.getContext().getResources().getQuantityString( : getResources(view).getQuantityString(
R.plurals.password_check_status_message_idle_with_leaks, R.plurals.password_check_status_message_idle_with_leaks,
compromisedCredentialsCount, compromisedCredentialsCount); compromisedCredentialsCount, compromisedCredentialsCount);
case PasswordCheckUIStatus.RUNNING: case PasswordCheckUIStatus.RUNNING:
...@@ -322,8 +336,12 @@ class PasswordCheckViewBinder { ...@@ -322,8 +336,12 @@ class PasswordCheckViewBinder {
case PasswordCheckUIStatus.ERROR_QUOTA_LIMIT: case PasswordCheckUIStatus.ERROR_QUOTA_LIMIT:
return getString(view, R.string.password_check_status_message_error_quota_limit); return getString(view, R.string.password_check_status_message_error_quota_limit);
case PasswordCheckUIStatus.ERROR_QUOTA_LIMIT_ACCOUNT_CHECK: case PasswordCheckUIStatus.ERROR_QUOTA_LIMIT_ACCOUNT_CHECK:
return getString(view, NoUnderlineClickableSpan linkSpan = new NoUnderlineClickableSpan(
R.string.password_check_status_message_error_quota_limit_account_check); getResources(view), unusedView -> launchCheckupInAccount.run());
return SpanApplier.applySpans(
getString(view,
R.string.password_check_status_message_error_quota_limit_account_check),
new SpanApplier.SpanInfo("<link>", "</link>", linkSpan));
case PasswordCheckUIStatus.ERROR_UNKNOWN: case PasswordCheckUIStatus.ERROR_UNKNOWN:
return getString(view, R.string.password_check_status_message_error_unknown); return getString(view, R.string.password_check_status_message_error_unknown);
default: default:
...@@ -353,7 +371,7 @@ class PasswordCheckViewBinder { ...@@ -353,7 +371,7 @@ class PasswordCheckViewBinder {
private static String getStatusDescription(View view, Long checkTimestamp) { private static String getStatusDescription(View view, Long checkTimestamp) {
if (checkTimestamp == null) return null; if (checkTimestamp == null) return null;
Resources res = view.getContext().getResources(); Resources res = getResources(view);
return res.getString(R.string.password_check_status_description_idle, return res.getString(R.string.password_check_status_description_idle,
getTimestamp(res, System.currentTimeMillis() - checkTimestamp)); getTimestamp(res, System.currentTimeMillis() - checkTimestamp));
} }
...@@ -478,11 +496,15 @@ class PasswordCheckViewBinder { ...@@ -478,11 +496,15 @@ class PasswordCheckViewBinder {
} }
private static String getString(View view, int resourceId) { private static String getString(View view, int resourceId) {
return view.getContext().getResources().getString(resourceId); return getResources(view).getString(resourceId);
} }
private static int getDimensionPixelOffset(View view, int resourceId) { private static int getDimensionPixelOffset(View view, int resourceId) {
return view.getContext().getResources().getDimensionPixelOffset(resourceId); return getResources(view).getDimensionPixelOffset(resourceId);
}
private static Resources getResources(View view) {
return view.getContext().getResources();
} }
private static void setTintListForCompoundDrawables( private static void setTintListForCompoundDrawables(
......
...@@ -206,7 +206,7 @@ ...@@ -206,7 +206,7 @@
Chrome couldn't check all passwords. Try again tomorrow. Chrome couldn't check all passwords. Try again tomorrow.
</message> </message>
<message name="IDS_PASSWORD_CHECK_STATUS_MESSAGE_ERROR_QUOTA_LIMIT_ACCOUNT_CHECK" desc="Error message explaining that the password check failed because the user has exceeded their quota and redirecting to check in the Google Account."> <message name="IDS_PASSWORD_CHECK_STATUS_MESSAGE_ERROR_QUOTA_LIMIT_ACCOUNT_CHECK" desc="Error message explaining that the password check failed because the user has exceeded their quota and redirecting to check in the Google Account.">
Chrome couldn't check all passwords. Try again tomorrow or check passwords in your Google Account. Chrome couldn't check all passwords. Try again tomorrow or <ph name="BEGIN_LINK">&lt;link&gt;</ph>check passwords in your Google Account<ph name="END_LINK">&lt;/link&gt;</ph>.
</message> </message>
<message name="IDS_PASSWORD_CHECK_STATUS_MESSAGE_ERROR_SIGNED_OUT" desc="Error message explaining that the password check failed because the user is signed-out."> <message name="IDS_PASSWORD_CHECK_STATUS_MESSAGE_ERROR_SIGNED_OUT" desc="Error message explaining that the password check failed because the user is signed-out.">
Chrome can check your passwords when you sign in with your Google Account. Chrome can check your passwords when you sign in with your Google Account.
......
d7b9987fb0a45cf5f829ba2750b0d9dcb8564a60 c4546cf199aa6314ead807fa1fc0e1ed8b779a83
\ No newline at end of file \ No newline at end of file
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.password_check; package org.chromium.chrome.browser.password_check;
import android.app.Activity;
import android.content.Context; import android.content.Context;
/** /**
...@@ -104,6 +105,11 @@ public interface PasswordCheck extends PasswordCheckComponentUi.Delegate { ...@@ -104,6 +105,11 @@ public interface PasswordCheck extends PasswordCheckComponentUi.Delegate {
*/ */
int getSavedPasswordsCount(); int getSavedPasswordsCount();
/**
* Launch the password check in the Google Account.
*/
void launchCheckupInAccount(Activity activity);
/** /**
* Starts the password check, if one is not running already. * Starts the password check, if one is not running already.
*/ */
......
...@@ -28,6 +28,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties ...@@ -28,6 +28,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_TIMESTAMP; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_TIMESTAMP;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.COMPROMISED_CREDENTIALS_COUNT; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.COMPROMISED_CREDENTIALS_COUNT;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.LAUNCH_ACCOUNT_CHECKUP_ACTION;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.RESTART_BUTTON_ACTION; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.RESTART_BUTTON_ACTION;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.UNKNOWN_PROGRESS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.UNKNOWN_PROGRESS;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS;
...@@ -128,6 +129,8 @@ public class PasswordCheckViewTest { ...@@ -128,6 +129,8 @@ public class PasswordCheckViewTest {
@Mock @Mock
private PasswordCheckCoordinator.CredentialEventHandler mMockHandler; private PasswordCheckCoordinator.CredentialEventHandler mMockHandler;
@Mock @Mock
private Runnable mMockLaunchCheckupInAccount;
@Mock
private Runnable mMockStartButtonCallback; private Runnable mMockStartButtonCallback;
@Rule @Rule
...@@ -258,11 +261,11 @@ public class PasswordCheckViewTest { ...@@ -258,11 +261,11 @@ public class PasswordCheckViewTest {
@Test @Test
@MediumTest @MediumTest
public void testStatusRunnningText() { public void testStatusRunningText() {
runOnUiThreadBlocking( runOnUiThreadBlocking(
() -> { mModel.get(ITEMS).add(buildHeader(RUNNING, UNKNOWN_PROGRESS)); }); () -> { mModel.get(ITEMS).add(buildHeader(RUNNING, UNKNOWN_PROGRESS)); });
waitForListViewToHaveLength(1); waitForListViewToHaveLength(1);
assertThat(getHeaderMessage().getText(), assertThat(getHeaderMessageText(),
is(getString(R.string.password_check_status_message_initial_running))); is(getString(R.string.password_check_status_message_initial_running)));
assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE)); assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE));
assertThat(getHeaderDescription().getVisibility(), is(View.GONE)); assertThat(getHeaderDescription().getVisibility(), is(View.GONE));
...@@ -275,7 +278,7 @@ public class PasswordCheckViewTest { ...@@ -275,7 +278,7 @@ public class PasswordCheckViewTest {
runOnUiThreadBlocking( runOnUiThreadBlocking(
() -> { mModel.get(ITEMS).add(buildHeader(IDLE, 0, checkTimestamp)); }); () -> { mModel.get(ITEMS).add(buildHeader(IDLE, 0, checkTimestamp)); });
waitForListViewToHaveLength(1); waitForListViewToHaveLength(1);
assertThat(getHeaderMessage().getText(), assertThat(getHeaderMessageText(),
is(getString(R.string.password_check_status_message_idle_no_leaks))); is(getString(R.string.password_check_status_message_idle_no_leaks)));
assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE)); assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE));
assertThat(getHeaderDescription().getVisibility(), is(View.VISIBLE)); assertThat(getHeaderDescription().getVisibility(), is(View.VISIBLE));
...@@ -288,7 +291,7 @@ public class PasswordCheckViewTest { ...@@ -288,7 +291,7 @@ public class PasswordCheckViewTest {
runOnUiThreadBlocking( runOnUiThreadBlocking(
() -> { mModel.get(ITEMS).add(buildHeader(IDLE, LEAKS_COUNT, checkTimestamp)); }); () -> { mModel.get(ITEMS).add(buildHeader(IDLE, LEAKS_COUNT, checkTimestamp)); });
waitForListViewToHaveLength(1); waitForListViewToHaveLength(1);
assertThat(getHeaderMessage().getText(), assertThat(getHeaderMessageText(),
is(mPasswordCheckView.getContext().getResources().getQuantityString( is(mPasswordCheckView.getContext().getResources().getQuantityString(
R.plurals.password_check_status_message_idle_with_leaks, LEAKS_COUNT, R.plurals.password_check_status_message_idle_with_leaks, LEAKS_COUNT,
LEAKS_COUNT))); LEAKS_COUNT)));
...@@ -301,7 +304,7 @@ public class PasswordCheckViewTest { ...@@ -301,7 +304,7 @@ public class PasswordCheckViewTest {
public void testStatusErrorOfflineText() { public void testStatusErrorOfflineText() {
runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_OFFLINE)); }); runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_OFFLINE)); });
waitForListViewToHaveLength(1); waitForListViewToHaveLength(1);
assertThat(getHeaderMessage().getText(), assertThat(getHeaderMessageText(),
is(getString(R.string.password_check_status_message_error_offline))); is(getString(R.string.password_check_status_message_error_offline)));
assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE)); assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE));
assertThat(getHeaderDescription().getVisibility(), is(View.GONE)); assertThat(getHeaderDescription().getVisibility(), is(View.GONE));
...@@ -312,7 +315,7 @@ public class PasswordCheckViewTest { ...@@ -312,7 +315,7 @@ public class PasswordCheckViewTest {
public void testStatusErrorNoPasswordsText() { public void testStatusErrorNoPasswordsText() {
runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_NO_PASSWORDS)); }); runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_NO_PASSWORDS)); });
waitForListViewToHaveLength(1); waitForListViewToHaveLength(1);
assertThat(getHeaderMessage().getText(), assertThat(getHeaderMessageText(),
is(getString(R.string.password_check_status_message_error_no_passwords))); is(getString(R.string.password_check_status_message_error_no_passwords)));
assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE)); assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE));
assertThat(getHeaderDescription().getVisibility(), is(View.GONE)); assertThat(getHeaderDescription().getVisibility(), is(View.GONE));
...@@ -323,7 +326,7 @@ public class PasswordCheckViewTest { ...@@ -323,7 +326,7 @@ public class PasswordCheckViewTest {
public void testStatusErrorQuotaLimitText() { public void testStatusErrorQuotaLimitText() {
runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_QUOTA_LIMIT)); }); runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_QUOTA_LIMIT)); });
waitForListViewToHaveLength(1); waitForListViewToHaveLength(1);
assertThat(getHeaderMessage().getText(), assertThat(getHeaderMessageText(),
is(getString(R.string.password_check_status_message_error_quota_limit))); is(getString(R.string.password_check_status_message_error_quota_limit)));
assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE)); assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE));
assertThat(getHeaderDescription().getVisibility(), is(View.GONE)); assertThat(getHeaderDescription().getVisibility(), is(View.GONE));
...@@ -335,9 +338,10 @@ public class PasswordCheckViewTest { ...@@ -335,9 +338,10 @@ public class PasswordCheckViewTest {
runOnUiThreadBlocking( runOnUiThreadBlocking(
() -> { mModel.get(ITEMS).add(buildHeader(ERROR_QUOTA_LIMIT_ACCOUNT_CHECK)); }); () -> { mModel.get(ITEMS).add(buildHeader(ERROR_QUOTA_LIMIT_ACCOUNT_CHECK)); });
waitForListViewToHaveLength(1); waitForListViewToHaveLength(1);
assertThat(getHeaderMessage().getText(), assertThat(getHeaderMessageText(),
is(getString( is(getString(R.string.password_check_status_message_error_quota_limit_account_check)
R.string.password_check_status_message_error_quota_limit_account_check))); .replace("<link>", "")
.replace("</link>", "")));
assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE)); assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE));
assertThat(getHeaderDescription().getVisibility(), is(View.GONE)); assertThat(getHeaderDescription().getVisibility(), is(View.GONE));
} }
...@@ -347,7 +351,7 @@ public class PasswordCheckViewTest { ...@@ -347,7 +351,7 @@ public class PasswordCheckViewTest {
public void testStatusErrorSignedOutText() { public void testStatusErrorSignedOutText() {
runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_SIGNED_OUT)); }); runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_SIGNED_OUT)); });
waitForListViewToHaveLength(1); waitForListViewToHaveLength(1);
assertThat(getHeaderMessage().getText(), assertThat(getHeaderMessageText(),
is(getString(R.string.password_check_status_message_error_signed_out))); is(getString(R.string.password_check_status_message_error_signed_out)));
assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE)); assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE));
assertThat(getHeaderDescription().getVisibility(), is(View.GONE)); assertThat(getHeaderDescription().getVisibility(), is(View.GONE));
...@@ -358,7 +362,7 @@ public class PasswordCheckViewTest { ...@@ -358,7 +362,7 @@ public class PasswordCheckViewTest {
public void testStatusErrorUnknownText() { public void testStatusErrorUnknownText() {
runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_UNKNOWN)); }); runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_UNKNOWN)); });
waitForListViewToHaveLength(1); waitForListViewToHaveLength(1);
assertThat(getHeaderMessage().getText(), assertThat(getHeaderMessageText(),
is(getString(R.string.password_check_status_message_error_unknown))); is(getString(R.string.password_check_status_message_error_unknown)));
assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE)); assertThat(getHeaderMessage().getVisibility(), is(View.VISIBLE));
assertThat(getHeaderDescription().getVisibility(), is(View.GONE)); assertThat(getHeaderDescription().getVisibility(), is(View.GONE));
...@@ -618,6 +622,7 @@ public class PasswordCheckViewTest { ...@@ -618,6 +622,7 @@ public class PasswordCheckViewTest {
.with(CHECK_STATUS, status) .with(CHECK_STATUS, status)
.with(CHECK_TIMESTAMP, checkTimestamp) .with(CHECK_TIMESTAMP, checkTimestamp)
.with(COMPROMISED_CREDENTIALS_COUNT, compromisedCredentialsCount) .with(COMPROMISED_CREDENTIALS_COUNT, compromisedCredentialsCount)
.with(LAUNCH_ACCOUNT_CHECKUP_ACTION, mMockLaunchCheckupInAccount)
.with(RESTART_BUTTON_ACTION, mMockStartButtonCallback) .with(RESTART_BUTTON_ACTION, mMockStartButtonCallback)
.build()); .build());
} }
...@@ -690,6 +695,10 @@ public class PasswordCheckViewTest { ...@@ -690,6 +695,10 @@ public class PasswordCheckViewTest {
return getStatus().findViewById(R.id.check_status_message); return getStatus().findViewById(R.id.check_status_message);
} }
private String getHeaderMessageText() {
return getHeaderMessage().getText().toString();
}
private TextView getHeaderSubtitle() { private TextView getHeaderSubtitle() {
return getStatus().findViewById(R.id.check_status_subtitle); return getStatus().findViewById(R.id.check_status_subtitle);
} }
......
...@@ -28,6 +28,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties ...@@ -28,6 +28,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_TIMESTAMP; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_TIMESTAMP;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.COMPROMISED_CREDENTIALS_COUNT; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.COMPROMISED_CREDENTIALS_COUNT;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.LAUNCH_ACCOUNT_CHECKUP_ACTION;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.RESTART_BUTTON_ACTION; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.RESTART_BUTTON_ACTION;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.UNKNOWN_PROGRESS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.UNKNOWN_PROGRESS;
import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS;
...@@ -100,7 +101,7 @@ public class PasswordCheckControllerTest { ...@@ -100,7 +101,7 @@ public class PasswordCheckControllerTest {
mModel = PasswordCheckProperties.createDefaultModel(); mModel = PasswordCheckProperties.createDefaultModel();
mMediator = new PasswordCheckMediator(mChangePasswordDelegate, mReauthenticationHelper); mMediator = new PasswordCheckMediator(mChangePasswordDelegate, mReauthenticationHelper);
PasswordCheckFactory.setPasswordCheckForTesting(mPasswordCheck); PasswordCheckFactory.setPasswordCheckForTesting(mPasswordCheck);
mMediator.initialize(mModel, mDelegate, PasswordCheckReferrer.PASSWORD_SETTINGS); mMediator.initialize(mModel, mDelegate, PasswordCheckReferrer.PASSWORD_SETTINGS, () -> {});
} }
@Test @Test
...@@ -125,7 +126,7 @@ public class PasswordCheckControllerTest { ...@@ -125,7 +126,7 @@ public class PasswordCheckControllerTest {
public void testInitializeHeaderWithLastStatusWhenComingFromSafetyCheck() { public void testInitializeHeaderWithLastStatusWhenComingFromSafetyCheck() {
clearInvocations(mPasswordCheck); // Clear invocations from setup code. clearInvocations(mPasswordCheck); // Clear invocations from setup code.
when(mPasswordCheck.getCheckStatus()).thenReturn(PasswordCheckUIStatus.IDLE); when(mPasswordCheck.getCheckStatus()).thenReturn(PasswordCheckUIStatus.IDLE);
mMediator.initialize(mModel, mDelegate, PasswordCheckReferrer.SAFETY_CHECK); mMediator.initialize(mModel, mDelegate, PasswordCheckReferrer.SAFETY_CHECK, () -> {});
assertIdleHeader(mModel.get(ITEMS).get(0)); assertIdleHeader(mModel.get(ITEMS).get(0));
verify(mPasswordCheck, never()).startCheck(); verify(mPasswordCheck, never()).startCheck();
} }
...@@ -304,7 +305,6 @@ public class PasswordCheckControllerTest { ...@@ -304,7 +305,6 @@ public class PasswordCheckControllerTest {
assertNull(header.model.get(CHECK_PROGRESS)); assertNull(header.model.get(CHECK_PROGRESS));
assertNotNull(header.model.get(CHECK_TIMESTAMP)); assertNotNull(header.model.get(CHECK_TIMESTAMP));
assertNotNull(header.model.get(COMPROMISED_CREDENTIALS_COUNT)); assertNotNull(header.model.get(COMPROMISED_CREDENTIALS_COUNT));
assertNotNull(header.model.get(RESTART_BUTTON_ACTION));
} }
private void assertRunningHeader( private void assertRunningHeader(
...@@ -313,7 +313,6 @@ public class PasswordCheckControllerTest { ...@@ -313,7 +313,6 @@ public class PasswordCheckControllerTest {
assertThat(header.model.get(CHECK_PROGRESS), is(progress)); assertThat(header.model.get(CHECK_PROGRESS), is(progress));
assertNull(header.model.get(CHECK_TIMESTAMP)); assertNull(header.model.get(CHECK_TIMESTAMP));
assertNull(header.model.get(COMPROMISED_CREDENTIALS_COUNT)); assertNull(header.model.get(COMPROMISED_CREDENTIALS_COUNT));
assertNotNull(header.model.get(RESTART_BUTTON_ACTION));
} }
private void assertHeaderTypeWithStatus( private void assertHeaderTypeWithStatus(
...@@ -321,5 +320,6 @@ public class PasswordCheckControllerTest { ...@@ -321,5 +320,6 @@ public class PasswordCheckControllerTest {
assertThat(header.type, is(ItemType.HEADER)); assertThat(header.type, is(ItemType.HEADER));
assertThat(header.model.get(CHECK_STATUS), is(status)); assertThat(header.model.get(CHECK_STATUS), is(status));
assertNotNull(header.model.get(RESTART_BUTTON_ACTION)); assertNotNull(header.model.get(RESTART_BUTTON_ACTION));
assertNotNull(header.model.get(LAUNCH_ACCOUNT_CHECKUP_ACTION));
} }
} }
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
#include "base/android/jni_string.h" #include "base/android/jni_string.h"
#include "chrome/browser/password_check/android/jni_headers/CompromisedCredential_jni.h" #include "chrome/browser/password_check/android/jni_headers/CompromisedCredential_jni.h"
#include "chrome/browser/password_check/android/jni_headers/PasswordCheckBridge_jni.h" #include "chrome/browser/password_check/android/jni_headers/PasswordCheckBridge_jni.h"
#include "chrome/browser/password_manager/android/password_checkup_launcher_helper.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "components/password_manager/core/browser/password_manager_util.h"
#include "components/password_manager/core/browser/ui/compromised_credentials_manager.h" #include "components/password_manager/core/browser/ui/compromised_credentials_manager.h"
#include "url/android/gurl_android.h" #include "url/android/gurl_android.h"
...@@ -91,6 +93,16 @@ void PasswordCheckBridge::GetCompromisedCredentials( ...@@ -91,6 +93,16 @@ void PasswordCheckBridge::GetCompromisedCredentials(
} }
} }
void PasswordCheckBridge::LaunchCheckupInAccount(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& activity) {
PasswordCheckupLauncherHelper::LaunchCheckupInAccountWithActivity(
env,
base::android::ConvertUTF8ToJavaString(
env, password_manager::GetPasswordCheckupURL().spec()),
activity);
}
void PasswordCheckBridge::UpdateCredential( void PasswordCheckBridge::UpdateCredential(
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jobject>& credential, const base::android::JavaParamRef<jobject>& credential,
......
...@@ -42,6 +42,11 @@ class PasswordCheckBridge : public PasswordCheckManager::Observer { ...@@ -42,6 +42,11 @@ class PasswordCheckBridge : public PasswordCheckManager::Observer {
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jobjectArray>& credentials); const base::android::JavaParamRef<jobjectArray>& credentials);
// Called by Java to launch a password check from the Google Account.
void LaunchCheckupInAccount(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& activity);
// Called by Java to update a single compromised credential in the password // Called by Java to update a single compromised credential in the password
// store. // store.
void UpdateCredential( void UpdateCredential(
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "base/android/jni_string.h" #include "base/android/jni_string.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "chrome/android/chrome_jni_headers/PasswordChangeLauncher_jni.h" #include "chrome/android/chrome_jni_headers/PasswordChangeLauncher_jni.h"
#include "chrome/android/chrome_jni_headers/PasswordCheckupLauncher_jni.h" #include "chrome/browser/password_manager/android/password_checkup_launcher_helper.h"
#include "chrome/browser/ui/android/passwords/credential_leak_dialog_view_android.h" #include "chrome/browser/ui/android/passwords/credential_leak_dialog_view_android.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "components/password_manager/core/browser/leak_detection_dialog_utils.h" #include "components/password_manager/core/browser/leak_detection_dialog_utils.h"
...@@ -61,10 +61,10 @@ void CredentialLeakControllerAndroid::OnAcceptDialog() { ...@@ -61,10 +61,10 @@ void CredentialLeakControllerAndroid::OnAcceptDialog() {
if (ShouldCheckPasswords()) { if (ShouldCheckPasswords()) {
if (base::FeatureList::IsEnabled( if (base::FeatureList::IsEnabled(
password_manager::features::kPasswordCheck)) { password_manager::features::kPasswordCheck)) {
Java_PasswordCheckupLauncher_launchLocalCheckup( PasswordCheckupLauncherHelper::LaunchLocalCheckup(
env, window_android_->GetJavaObject()); env, window_android_->GetJavaObject());
} else { } else {
Java_PasswordCheckupLauncher_launchCheckupInAccount( PasswordCheckupLauncherHelper::LaunchCheckupInAccountWithWindowAndroid(
env, env,
base::android::ConvertUTF8ToJavaString( base::android::ConvertUTF8ToJavaString(
env, password_manager::GetPasswordCheckupURL().spec()), env, password_manager::GetPasswordCheckupURL().spec()),
......
// 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.
#include "chrome/browser/password_manager/android/password_checkup_launcher_helper.h"
#include "chrome/android/chrome_jni_headers/PasswordCheckupLauncher_jni.h"
// static
void PasswordCheckupLauncherHelper::LaunchCheckupInAccountWithWindowAndroid(
JNIEnv* env,
const base::android::JavaRef<jstring>& checkupUrl,
const base::android::JavaRef<jobject>& windowAndroid) {
Java_PasswordCheckupLauncher_launchCheckupInAccountWithWindowAndroid(
env, checkupUrl, windowAndroid);
}
// static
void PasswordCheckupLauncherHelper::LaunchLocalCheckup(
JNIEnv* env,
const base::android::JavaRef<jobject>& windowAndroid) {
Java_PasswordCheckupLauncher_launchLocalCheckup(env, windowAndroid);
}
// static
void PasswordCheckupLauncherHelper::LaunchCheckupInAccountWithActivity(
JNIEnv* env,
const base::android::JavaRef<jstring>& checkupUrl,
const base::android::JavaRef<jobject>& activity) {
Java_PasswordCheckupLauncher_launchCheckupInAccountWithActivity(
env, checkupUrl, activity);
}
// 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.
#ifndef CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_CHECKUP_LAUNCHER_HELPER_H_
#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_CHECKUP_LAUNCHER_HELPER_H_
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
// Helper class used to access the methods of the java class
// PasswordCheckupLauncher from multiple native side locations
class PasswordCheckupLauncherHelper {
public:
// Launch the bulk password check in the Google Account
static void LaunchCheckupInAccountWithWindowAndroid(
JNIEnv* env,
const base::android::JavaRef<jstring>& checkupUrl,
const base::android::JavaRef<jobject>& windowAndroid);
// Launch the bulk password check locally
static void LaunchLocalCheckup(
JNIEnv* env,
const base::android::JavaRef<jobject>& windowAndroid);
// Launch the bulk password check in the Google Account using an activity
// rather than a WindowAndroid
static void LaunchCheckupInAccountWithActivity(
JNIEnv* env,
const base::android::JavaRef<jstring>& checkupUrl,
const base::android::JavaRef<jobject>& activity);
};
#endif // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_CHECKUP_LAUNCHER_HELPER_H_
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