Commit 976e7da2 authored by Milica Selakovic's avatar Milica Selakovic Committed by Commit Bot

[Password Manager] Integrate PasswordScriptFetcher to Password Check Manager

This CL adds check for scripts availability only
if kPasswordChageInSettings flag is enabled.
This CL also changes PasswordScriptsFetcherBridge so it does not use
Profile information and can be used in SafetyCheck to prewarm cache.

Bug: 1086114, 1092444
Change-Id: I87021c2e65c7886ad90ee80844b9a2e46fb4b626
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2351994
Commit-Queue: Milica Selakovic <selakovic@google.com>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarIoana Pandele <ioanap@chromium.org>
Reviewed-by: default avatarAndrey Zaytsev <andzaytsev@google.com>
Reviewed-by: default avatarBoris Sazonov <bsazonov@chromium.org>
Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799596}
parent 06919a97
...@@ -3109,7 +3109,6 @@ generate_jni("chrome_jni_headers") { ...@@ -3109,7 +3109,6 @@ generate_jni("chrome_jni_headers") {
"java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogBridge.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogBridge.java",
"java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationPopupBridge.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationPopupBridge.java",
"java/src/org/chromium/chrome/browser/password_manager/PasswordManagerLauncher.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordManagerLauncher.java",
"java/src/org/chromium/chrome/browser/password_manager/PasswordScriptsFetcherBridge.java",
"java/src/org/chromium/chrome/browser/password_manager/settings/PasswordEditingBridge.java", "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordEditingBridge.java",
"java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUIView.java", "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUIView.java",
"java/src/org/chromium/chrome/browser/permissions/PermissionSettingsBridge.java", "java/src/org/chromium/chrome/browser/permissions/PermissionSettingsBridge.java",
......
...@@ -1226,7 +1226,6 @@ chrome_java_sources = [ ...@@ -1226,7 +1226,6 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogView.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogView.java",
"java/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogViewBinder.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogViewBinder.java",
"java/src/org/chromium/chrome/browser/password_manager/PasswordManagerLauncher.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordManagerLauncher.java",
"java/src/org/chromium/chrome/browser/password_manager/PasswordScriptsFetcherBridge.java",
"java/src/org/chromium/chrome/browser/password_manager/settings/CallbackDelayer.java", "java/src/org/chromium/chrome/browser/password_manager/settings/CallbackDelayer.java",
"java/src/org/chromium/chrome/browser/password_manager/settings/DialogManager.java", "java/src/org/chromium/chrome/browser/password_manager/settings/DialogManager.java",
"java/src/org/chromium/chrome/browser/password_manager/settings/ExportErrorDialogFragment.java", "java/src/org/chromium/chrome/browser/password_manager/settings/ExportErrorDialogFragment.java",
......
...@@ -60,7 +60,7 @@ public class PasswordManagerLauncher { ...@@ -60,7 +60,7 @@ public class PasswordManagerLauncher {
if (tryShowingTheGooglePasswordManager(activity)) return; if (tryShowingTheGooglePasswordManager(activity)) return;
} }
if (ChromeFeatureList.isEnabled(ChromeFeatureList.PASSWORD_CHANGE_IN_SETTINGS)) { if (ChromeFeatureList.isEnabled(ChromeFeatureList.PASSWORD_CHANGE_IN_SETTINGS)) {
PasswordScriptsFetcherBridge.prewarmCache(Profile.getLastUsedRegularProfile()); PasswordScriptsFetcherBridge.prewarmCache();
} }
} }
......
...@@ -2855,6 +2855,7 @@ static_library("browser") { ...@@ -2855,6 +2855,7 @@ static_library("browser") {
"password_manager/android/password_manager_infobar_delegate_android.h", "password_manager/android/password_manager_infobar_delegate_android.h",
"password_manager/android/password_manager_launcher_android.cc", "password_manager/android/password_manager_launcher_android.cc",
"password_manager/android/password_manager_launcher_android.h", "password_manager/android/password_manager_launcher_android.h",
"password_manager/android/password_scripts_fetcher_android.cc",
"password_manager/android/save_password_infobar_delegate_android.cc", "password_manager/android/save_password_infobar_delegate_android.cc",
"password_manager/android/save_password_infobar_delegate_android.h", "password_manager/android/save_password_infobar_delegate_android.h",
"password_manager/android/touch_to_fill_view.h", "password_manager/android/touch_to_fill_view.h",
...@@ -2968,6 +2969,7 @@ static_library("browser") { ...@@ -2968,6 +2969,7 @@ static_library("browser") {
"//chrome/browser/offline_pages/prefetch/notifications", "//chrome/browser/offline_pages/prefetch/notifications",
"//chrome/browser/optimization_guide/android:jni_headers", "//chrome/browser/optimization_guide/android:jni_headers",
"//chrome/browser/password_check/android:jni_headers", "//chrome/browser/password_check/android:jni_headers",
"//chrome/browser/password_manager/android:jni_headers",
"//chrome/browser/payments/android:jni_headers", "//chrome/browser/payments/android:jni_headers",
"//chrome/browser/policy/android:jni_headers", "//chrome/browser/policy/android:jni_headers",
"//chrome/browser/privacy:jni_headers", "//chrome/browser/privacy:jni_headers",
......
...@@ -103,6 +103,21 @@ class PasswordCheckBridge { ...@@ -103,6 +103,21 @@ class PasswordCheckBridge {
PasswordCheckBridgeJni.get().stopCheck(mNativePasswordCheckBridge); PasswordCheckBridgeJni.get().stopCheck(mNativePasswordCheckBridge);
} }
/**
*
* @return Whether the scripts refreshment is finished.
*/
boolean areScriptsRefreshed() {
return PasswordCheckBridgeJni.get().areScriptsRefreshed(mNativePasswordCheckBridge);
}
/**
* Invokes scripts refreshment.
*/
void refreshScripts() {
PasswordCheckBridgeJni.get().refreshScripts(mNativePasswordCheckBridge);
}
/** /**
* @return The timestamp of the last completed check. * @return The timestamp of the last completed check.
*/ */
...@@ -163,6 +178,8 @@ class PasswordCheckBridge { ...@@ -163,6 +178,8 @@ class PasswordCheckBridge {
long create(PasswordCheckBridge passwordCheckBridge); long create(PasswordCheckBridge passwordCheckBridge);
void startCheck(long nativePasswordCheckBridge); void startCheck(long nativePasswordCheckBridge);
void stopCheck(long nativePasswordCheckBridge); void stopCheck(long nativePasswordCheckBridge);
boolean areScriptsRefreshed(long nativePasswordCheckBridge);
void refreshScripts(long nativePasswordCheckBridge);
long getLastCheckTimestamp(long nativePasswordCheckBridge); long getLastCheckTimestamp(long nativePasswordCheckBridge);
int getCompromisedCredentialsCount(long nativePasswordCheckBridge); int getCompromisedCredentialsCount(long nativePasswordCheckBridge);
int getSavedPasswordsCount(long nativePasswordCheckBridge); int getSavedPasswordsCount(long nativePasswordCheckBridge);
......
...@@ -37,6 +37,7 @@ class PasswordCheckImpl implements PasswordCheck, PasswordCheckObserver { ...@@ -37,6 +37,7 @@ class PasswordCheckImpl implements PasswordCheck, PasswordCheckObserver {
fragmentArgs.putInt( fragmentArgs.putInt(
PasswordCheckFragmentView.PASSWORD_CHECK_REFERRER, passwordCheckReferrer); PasswordCheckFragmentView.PASSWORD_CHECK_REFERRER, passwordCheckReferrer);
launcher.launchSettingsActivity(context, PasswordCheckFragmentView.class, fragmentArgs); launcher.launchSettingsActivity(context, PasswordCheckFragmentView.class, fragmentArgs);
mPasswordCheckBridge.refreshScripts();
} }
@Override @Override
...@@ -136,4 +137,9 @@ class PasswordCheckImpl implements PasswordCheck, PasswordCheckObserver { ...@@ -136,4 +137,9 @@ class PasswordCheckImpl implements PasswordCheck, PasswordCheckObserver {
public void stopCheck() { public void stopCheck() {
mPasswordCheckBridge.stopCheck(); mPasswordCheckBridge.stopCheck();
} }
@Override
public boolean areScriptsRefreshed() {
return mPasswordCheckBridge.areScriptsRefreshed();
}
} }
...@@ -66,6 +66,9 @@ class PasswordCheckMediator ...@@ -66,6 +66,9 @@ class PasswordCheckMediator
@Override @Override
public void onCompromisedCredentialsFetchCompleted() { public void onCompromisedCredentialsFetchCompleted() {
if (!getPasswordCheck().areScriptsRefreshed()) {
return;
}
CompromisedCredential[] credentials = getPasswordCheck().getCompromisedCredentials(); CompromisedCredential[] credentials = getPasswordCheck().getCompromisedCredentials();
assert credentials != null; assert credentials != null;
ListModel<ListItem> items = mModel.get(ITEMS); ListModel<ListItem> items = mModel.get(ITEMS);
......
...@@ -113,4 +113,9 @@ public interface PasswordCheck extends PasswordCheckComponentUi.Delegate { ...@@ -113,4 +113,9 @@ public interface PasswordCheck extends PasswordCheckComponentUi.Delegate {
* Stops the password check, if one is running. Otherwise, does nothing. * Stops the password check, if one is running. Otherwise, does nothing.
*/ */
void stopCheck(); void stopCheck();
/**
* Checks if scripts refreshment is finished.
*/
boolean areScriptsRefreshed();
} }
...@@ -193,6 +193,7 @@ public class PasswordCheckControllerTest { ...@@ -193,6 +193,7 @@ public class PasswordCheckControllerTest {
public void testCreatesEntryForExistingCredentials() { public void testCreatesEntryForExistingCredentials() {
when(mPasswordCheck.getCompromisedCredentials()) when(mPasswordCheck.getCompromisedCredentials())
.thenReturn(new CompromisedCredential[] {ANA}); .thenReturn(new CompromisedCredential[] {ANA});
when(mPasswordCheck.areScriptsRefreshed()).thenReturn(true);
when(mChangePasswordDelegate.canManuallyChangeCredential(eq(ANA))).thenReturn(true); when(mChangePasswordDelegate.canManuallyChangeCredential(eq(ANA))).thenReturn(true);
mMediator.onPasswordCheckStatusChanged(IDLE); mMediator.onPasswordCheckStatusChanged(IDLE);
...@@ -208,6 +209,7 @@ public class PasswordCheckControllerTest { ...@@ -208,6 +209,7 @@ public class PasswordCheckControllerTest {
public void testHidesChangeButtonIfManualChangeIsNotPossible() { public void testHidesChangeButtonIfManualChangeIsNotPossible() {
when(mPasswordCheck.getCompromisedCredentials()) when(mPasswordCheck.getCompromisedCredentials())
.thenReturn(new CompromisedCredential[] {BOB}); .thenReturn(new CompromisedCredential[] {BOB});
when(mPasswordCheck.areScriptsRefreshed()).thenReturn(true);
when(mChangePasswordDelegate.canManuallyChangeCredential(eq(BOB))).thenReturn(false); when(mChangePasswordDelegate.canManuallyChangeCredential(eq(BOB))).thenReturn(false);
mMediator.onPasswordCheckStatusChanged(IDLE); mMediator.onPasswordCheckStatusChanged(IDLE);
...@@ -223,6 +225,7 @@ public class PasswordCheckControllerTest { ...@@ -223,6 +225,7 @@ public class PasswordCheckControllerTest {
public void testAppendsEntryForNewlyFoundCredentials() { public void testAppendsEntryForNewlyFoundCredentials() {
when(mPasswordCheck.getCompromisedCredentials()) when(mPasswordCheck.getCompromisedCredentials())
.thenReturn(new CompromisedCredential[] {ANA}); .thenReturn(new CompromisedCredential[] {ANA});
when(mPasswordCheck.areScriptsRefreshed()).thenReturn(true);
when(mChangePasswordDelegate.canManuallyChangeCredential(eq(BOB))).thenReturn(true); when(mChangePasswordDelegate.canManuallyChangeCredential(eq(BOB))).thenReturn(true);
mMediator.onPasswordCheckStatusChanged(IDLE); mMediator.onPasswordCheckStatusChanged(IDLE);
mMediator.onCompromisedCredentialsFetchCompleted(); mMediator.onCompromisedCredentialsFetchCompleted();
...@@ -243,6 +246,7 @@ public class PasswordCheckControllerTest { ...@@ -243,6 +246,7 @@ public class PasswordCheckControllerTest {
// First call adds only ANA. // First call adds only ANA.
when(mPasswordCheck.getCompromisedCredentials()) when(mPasswordCheck.getCompromisedCredentials())
.thenReturn(new CompromisedCredential[] {ANA}); .thenReturn(new CompromisedCredential[] {ANA});
when(mPasswordCheck.areScriptsRefreshed()).thenReturn(true);
mMediator.onCompromisedCredentialsFetchCompleted(); mMediator.onCompromisedCredentialsFetchCompleted();
assertThat(mModel.get(ITEMS).size(), is(2)); // Header + existing credentials. assertThat(mModel.get(ITEMS).size(), is(2)); // Header + existing credentials.
......
...@@ -110,6 +110,14 @@ void PasswordCheckBridge::Destroy(JNIEnv* env) { ...@@ -110,6 +110,14 @@ void PasswordCheckBridge::Destroy(JNIEnv* env) {
delete this; delete this;
} }
bool PasswordCheckBridge::AreScriptsRefreshed(JNIEnv* env) const {
return check_manager_.AreScriptsRefreshed();
}
void PasswordCheckBridge::RefreshScripts(JNIEnv* env) {
check_manager_.RefreshScripts();
}
void PasswordCheckBridge::OnSavedPasswordsFetched(int count) { void PasswordCheckBridge::OnSavedPasswordsFetched(int count) {
Java_PasswordCheckBridge_onSavedPasswordsFetched( Java_PasswordCheckBridge_onSavedPasswordsFetched(
base::android::AttachCurrentThread(), java_bridge_, count); base::android::AttachCurrentThread(), java_bridge_, count);
......
...@@ -58,6 +58,12 @@ class PasswordCheckBridge : public PasswordCheckManager::Observer { ...@@ -58,6 +58,12 @@ class PasswordCheckBridge : public PasswordCheckManager::Observer {
// Called by Java when the bridge is no longer needed. Destructs itself. // Called by Java when the bridge is no longer needed. Destructs itself.
void Destroy(JNIEnv* env); void Destroy(JNIEnv* env);
// Checks if script refreshment is finished.
bool AreScriptsRefreshed(JNIEnv* env) const;
// Invokes scripts refreshment.
void RefreshScripts(JNIEnv* env);
// Called by the check manager when the saved passwords have been first loaded // Called by the check manager when the saved passwords have been first loaded
// in memory. `count` is the number of saved passwords. // in memory. `count` is the number of saved passwords.
void OnSavedPasswordsFetched(int count) override; void OnSavedPasswordsFetched(int count) override;
......
...@@ -110,7 +110,7 @@ PasswordCheckManager::PasswordCheckManager(Profile* profile, Observer* observer) ...@@ -110,7 +110,7 @@ PasswordCheckManager::PasswordCheckManager(Profile* profile, Observer* observer)
PasswordCheckManager::~PasswordCheckManager() = default; PasswordCheckManager::~PasswordCheckManager() = default;
void PasswordCheckManager::StartCheck() { void PasswordCheckManager::StartCheck() {
if (!is_initialized_) { if (!is_initialized_ || !AreScriptsRefreshed()) {
was_start_requested_ = true; was_start_requested_ = true;
return; return;
} }
...@@ -185,6 +185,9 @@ void PasswordCheckManager::OnSavedPasswordsChanged( ...@@ -185,6 +185,9 @@ void PasswordCheckManager::OnSavedPasswordsChanged(
void PasswordCheckManager::OnCompromisedCredentialsChanged( void PasswordCheckManager::OnCompromisedCredentialsChanged(
password_manager::CompromisedCredentialsManager::CredentialsView password_manager::CompromisedCredentialsManager::CredentialsView
credentials) { credentials) {
if (!AreScriptsRefreshed()) {
credentials_count_to_notify_ = credentials.size();
}
observer_->OnCompromisedCredentialsChanged(credentials.size()); observer_->OnCompromisedCredentialsChanged(credentials.size());
} }
...@@ -216,10 +219,19 @@ void PasswordCheckManager::OnCredentialDone( ...@@ -216,10 +219,19 @@ void PasswordCheckManager::OnCredentialDone(
CompromisedCredentialForUI PasswordCheckManager::MakeUICredential( CompromisedCredentialForUI PasswordCheckManager::MakeUICredential(
const CredentialWithPassword& credential) const { const CredentialWithPassword& credential) const {
CompromisedCredentialForUI ui_credential(credential); CompromisedCredentialForUI ui_credential(credential);
// UI is only be created after the list of available password check
// scripts has been refreshed.
DCHECK(AreScriptsRefreshed());
auto facet = password_manager::FacetURI::FromPotentiallyInvalidSpec( auto facet = password_manager::FacetURI::FromPotentiallyInvalidSpec(
credential.signon_realm); credential.signon_realm);
ui_credential.display_username = GetDisplayUsername(credential.username); ui_credential.display_username = GetDisplayUsername(credential.username);
ui_credential.has_script =
base::FeatureList::IsEnabled(
password_manager::features::kPasswordChangeInSettings) &&
password_script_fetcher_->IsScriptAvailable(
url::Origin::Create(credential.url.GetOrigin()));
if (facet.IsValidAndroidFacetURI()) { if (facet.IsValidAndroidFacetURI()) {
const PasswordForm& android_form = const PasswordForm& android_form =
compromised_credentials_manager_.GetSavedPasswordsFor(credential)[0]; compromised_credentials_manager_.GetSavedPasswordsFor(credential)[0];
...@@ -286,3 +298,38 @@ bool PasswordCheckManager::CanUseAccountCheck() const { ...@@ -286,3 +298,38 @@ bool PasswordCheckManager::CanUseAccountCheck() const {
return sync_state == SyncState::SYNCING_NORMAL_ENCRYPTION || return sync_state == SyncState::SYNCING_NORMAL_ENCRYPTION ||
sync_state == SyncState::ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION; sync_state == SyncState::ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION;
} }
bool PasswordCheckManager::AreScriptsRefreshed() const {
// Don't fetch scripts if password change is not enabled.
return are_scripts_refreshed_ ||
!base::FeatureList::IsEnabled(
password_manager::features::kPasswordChangeInSettings);
}
void PasswordCheckManager::RefreshScripts() {
// Don't fetch scripts if password change is not enabled.
if (!base::FeatureList::IsEnabled(
password_manager::features::kPasswordChangeInSettings)) {
return;
}
are_scripts_refreshed_ = false;
password_script_fetcher_->RefreshScriptsIfNecessary(base::BindOnce(
&PasswordCheckManager::OnScriptsFetched, base::Unretained(this)));
}
void PasswordCheckManager::OnScriptsFetched() {
are_scripts_refreshed_ = true;
if (credentials_count_to_notify_.has_value()) {
// Inform the UI about compromised credentials another time because it was
// not allowed to generate UI before the availability of password scripts is
// known.
observer_->OnCompromisedCredentialsChanged(
credentials_count_to_notify_.value());
credentials_count_to_notify_.reset();
}
if (was_start_requested_)
StartCheck();
}
...@@ -6,13 +6,16 @@ ...@@ -6,13 +6,16 @@
#define CHROME_BROWSER_PASSWORD_CHECK_ANDROID_PASSWORD_CHECK_MANAGER_H_ #define CHROME_BROWSER_PASSWORD_CHECK_ANDROID_PASSWORD_CHECK_MANAGER_H_
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "base/strings/string_piece_forward.h" #include "base/strings/string_piece_forward.h"
#include "chrome/browser/password_check/android/password_check_ui_status.h" #include "chrome/browser/password_check/android/password_check_ui_status.h"
#include "chrome/browser/password_manager/bulk_leak_check_service_factory.h" #include "chrome/browser/password_manager/bulk_leak_check_service_factory.h"
#include "chrome/browser/password_manager/password_scripts_fetcher_factory.h"
#include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "components/password_manager/core/browser/bulk_leak_check_service.h" #include "components/password_manager/core/browser/bulk_leak_check_service.h"
#include "components/password_manager/core/browser/bulk_leak_check_service_interface.h" #include "components/password_manager/core/browser/bulk_leak_check_service_interface.h"
#include "components/password_manager/core/browser/password_scripts_fetcher.h"
#include "components/password_manager/core/browser/ui/bulk_leak_check_service_adapter.h" #include "components/password_manager/core/browser/ui/bulk_leak_check_service_adapter.h"
#include "components/password_manager/core/browser/ui/compromised_credentials_manager.h" #include "components/password_manager/core/browser/ui/compromised_credentials_manager.h"
#include "components/password_manager/core/browser/ui/saved_passwords_presenter.h" #include "components/password_manager/core/browser/ui/saved_passwords_presenter.h"
...@@ -82,6 +85,12 @@ class PasswordCheckManager ...@@ -82,6 +85,12 @@ class PasswordCheckManager
// UI update on completion. // UI update on completion.
void RemoveCredential(const password_manager::CredentialView& credential); void RemoveCredential(const password_manager::CredentialView& credential);
// Invokes `PasswordScriptsFetcher`'s scripts refreshment.
void RefreshScripts();
// Returns if scripts refreshment is finished.
bool AreScriptsRefreshed() const;
// Not copyable or movable // Not copyable or movable
PasswordCheckManager(const PasswordCheckManager&) = delete; PasswordCheckManager(const PasswordCheckManager&) = delete;
PasswordCheckManager& operator=(const PasswordCheckManager&) = delete; PasswordCheckManager& operator=(const PasswordCheckManager&) = delete;
...@@ -122,6 +131,9 @@ class PasswordCheckManager ...@@ -122,6 +131,9 @@ class PasswordCheckManager
// in the account if the quota limit was reached. // in the account if the quota limit was reached.
bool CanUseAccountCheck() const; bool CanUseAccountCheck() const;
// Callback when PasswordScriptsFetcher's cache has been warmed up.
void OnScriptsFetched();
// Obsever being notified of UI-relevant events. // Obsever being notified of UI-relevant events.
// It must outlive `this`. // It must outlive `this`.
Observer* observer_ = nullptr; Observer* observer_ = nullptr;
...@@ -135,6 +147,12 @@ class PasswordCheckManager ...@@ -135,6 +147,12 @@ class PasswordCheckManager
PasswordStoreFactory::GetForProfile(profile_, PasswordStoreFactory::GetForProfile(profile_,
ServiceAccessType::EXPLICIT_ACCESS); ServiceAccessType::EXPLICIT_ACCESS);
// Used to check whether autofill assistant scripts are available for
// the specified domain.
password_manager::PasswordScriptsFetcher* password_script_fetcher_ =
PasswordScriptsFetcherFactory::GetInstance()->GetForBrowserContext(
profile_);
// Used by `compromised_credentials_manager_` to obtain the list of saved // Used by `compromised_credentials_manager_` to obtain the list of saved
// passwords. // passwords.
password_manager::SavedPasswordsPresenter saved_passwords_presenter_{ password_manager::SavedPasswordsPresenter saved_passwords_presenter_{
...@@ -161,6 +179,14 @@ class PasswordCheckManager ...@@ -161,6 +179,14 @@ class PasswordCheckManager
// Whether a check is currently running. // Whether a check is currently running.
bool is_check_running_ = false; bool is_check_running_ = false;
// Whether scripts refreshement is finished.
bool are_scripts_refreshed_ = false;
// Latest number of changed compromised credentials while script fetching
// was running. If `credentials_count_to_notify_` has value, after scripts are
// fetched `onCompromisedCredentials` should be called.
base::Optional<size_t> credentials_count_to_notify_;
// A scoped observer for `saved_passwords_presenter_`. // A scoped observer for `saved_passwords_presenter_`.
ScopedObserver<password_manager::SavedPasswordsPresenter, ScopedObserver<password_manager::SavedPasswordsPresenter,
password_manager::SavedPasswordsPresenter::Observer> password_manager::SavedPasswordsPresenter::Observer>
......
...@@ -12,14 +12,17 @@ ...@@ -12,14 +12,17 @@
#include "base/strings/strcat.h" #include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h" #include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/password_check/android/password_check_ui_status.h" #include "chrome/browser/password_check/android/password_check_ui_status.h"
#include "chrome/browser/password_manager/bulk_leak_check_service_factory.h" #include "chrome/browser/password_manager/bulk_leak_check_service_factory.h"
#include "chrome/browser/password_manager/password_scripts_fetcher_factory.h"
#include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "components/password_manager/core/browser/bulk_leak_check_service.h" #include "components/password_manager/core/browser/bulk_leak_check_service.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/test_password_store.h" #include "components/password_manager/core/browser/test_password_store.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/prefs/testing_pref_service.h" #include "components/prefs/testing_pref_service.h"
#include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/identity_manager.h"
...@@ -41,8 +44,10 @@ using password_manager::prefs::kLastTimePasswordCheckCompleted; ...@@ -41,8 +44,10 @@ using password_manager::prefs::kLastTimePasswordCheckCompleted;
using testing::_; using testing::_;
using testing::ElementsAre; using testing::ElementsAre;
using testing::Field; using testing::Field;
using testing::Invoke;
using testing::IsEmpty; using testing::IsEmpty;
using testing::NiceMock; using testing::NiceMock;
using testing::Return;
using CompromisedCredentialForUI = using CompromisedCredentialForUI =
PasswordCheckManager::CompromisedCredentialForUI; PasswordCheckManager::CompromisedCredentialForUI;
...@@ -72,6 +77,21 @@ class MockPasswordCheckManagerObserver : public PasswordCheckManager::Observer { ...@@ -72,6 +77,21 @@ class MockPasswordCheckManagerObserver : public PasswordCheckManager::Observer {
(override)); (override));
}; };
class MockPasswordScriptsFetcher
: public password_manager::PasswordScriptsFetcher {
public:
MOCK_METHOD(void, PrewarmCache, (), (override));
MOCK_METHOD(void, RefreshScriptsIfNecessary, (base::OnceClosure), (override));
MOCK_METHOD(void,
FetchScriptAvailability,
(const url::Origin&, base::OnceCallback<void(bool)>),
(override));
MOCK_METHOD(bool, IsScriptAvailable, (const url::Origin&), (const override));
};
// TODO(crbug.com/1112804): Extract this into a password manager test utils // TODO(crbug.com/1112804): Extract this into a password manager test utils
// file, since it's used across multiple tests. // file, since it's used across multiple tests.
scoped_refptr<TestPasswordStore> CreateAndUseTestPasswordStore( scoped_refptr<TestPasswordStore> CreateAndUseTestPasswordStore(
...@@ -97,6 +117,15 @@ BulkLeakCheckService* CreateAndUseBulkLeakCheckService( ...@@ -97,6 +117,15 @@ BulkLeakCheckService* CreateAndUseBulkLeakCheckService(
})); }));
} }
MockPasswordScriptsFetcher* CreateAndUseMockPasswordScriptsFetcher(
Profile* profile) {
return PasswordScriptsFetcherFactory::GetInstance()
->SetTestingSubclassFactoryAndUse(
profile, base::BindRepeating([](content::BrowserContext*) {
return std::make_unique<MockPasswordScriptsFetcher>();
}));
}
PasswordForm MakeSavedPassword(base::StringPiece signon_realm, PasswordForm MakeSavedPassword(base::StringPiece signon_realm,
base::StringPiece username, base::StringPiece username,
base::StringPiece password = kPassword1, base::StringPiece password = kPassword1,
...@@ -178,10 +207,10 @@ class PasswordCheckManagerTest : public testing::Test { ...@@ -178,10 +207,10 @@ class PasswordCheckManagerTest : public testing::Test {
BulkLeakCheckService* service() { return service_; } BulkLeakCheckService* service() { return service_; }
TestPasswordStore& store() { return *store_; } TestPasswordStore& store() { return *store_; }
MockPasswordCheckManagerObserver& mock_observer() { return mock_observer_; }
protected: MockPasswordScriptsFetcher& fetcher() { return *fetcher_; }
NiceMock<MockPasswordCheckManagerObserver> mock_observer_; PasswordCheckManager& manager() { return *manager_; }
std::unique_ptr<PasswordCheckManager> manager_; base::test::ScopedFeatureList& feature_list() { return feature_list_; }
private: private:
content::BrowserTaskEnvironment task_env_; content::BrowserTaskEnvironment task_env_;
...@@ -192,25 +221,29 @@ class PasswordCheckManagerTest : public testing::Test { ...@@ -192,25 +221,29 @@ class PasswordCheckManagerTest : public testing::Test {
&profile_); &profile_);
scoped_refptr<TestPasswordStore> store_ = scoped_refptr<TestPasswordStore> store_ =
CreateAndUseTestPasswordStore(&profile_); CreateAndUseTestPasswordStore(&profile_);
NiceMock<MockPasswordCheckManagerObserver> mock_observer_;
MockPasswordScriptsFetcher* fetcher_ =
CreateAndUseMockPasswordScriptsFetcher(&profile_);
base::test::ScopedFeatureList feature_list_;
std::unique_ptr<PasswordCheckManager> manager_;
}; };
TEST_F(PasswordCheckManagerTest, SendsNoPasswordsMessageIfNoPasswordsAreSaved) { TEST_F(PasswordCheckManagerTest, SendsNoPasswordsMessageIfNoPasswordsAreSaved) {
EXPECT_CALL(mock_observer_, OnPasswordCheckStatusChanged( EXPECT_CALL(mock_observer(), OnPasswordCheckStatusChanged(
PasswordCheckUIStatus::kErrorNoPasswords)); PasswordCheckUIStatus::kErrorNoPasswords));
InitializeManager(); InitializeManager();
RunUntilIdle(); RunUntilIdle();
} }
TEST_F(PasswordCheckManagerTest, OnSavedPasswordsFetched) { TEST_F(PasswordCheckManagerTest, OnSavedPasswordsFetched) {
store().AddLogin(MakeSavedPassword(kExampleCom, kUsername1)); store().AddLogin(MakeSavedPassword(kExampleCom, kUsername1));
EXPECT_CALL(mock_observer(), OnSavedPasswordsFetched(1));
EXPECT_CALL(mock_observer_, OnSavedPasswordsFetched(1));
InitializeManager(); InitializeManager();
RunUntilIdle(); RunUntilIdle();
// Verify that OnSavedPasswordsFetched is not called after the initial fetch // Verify that OnSavedPasswordsFetched is not called after the initial fetch
// even if the saved passwords change. // even if the saved passwords change.
EXPECT_CALL(mock_observer_, OnSavedPasswordsFetched(_)).Times(0); EXPECT_CALL(mock_observer(), OnSavedPasswordsFetched(_)).Times(0);
store().AddLogin(MakeSavedPassword(kExampleCom, kUsername2)); store().AddLogin(MakeSavedPassword(kExampleCom, kUsername2));
RunUntilIdle(); RunUntilIdle();
} }
...@@ -219,12 +252,12 @@ TEST_F(PasswordCheckManagerTest, OnCompromisedCredentialsChanged) { ...@@ -219,12 +252,12 @@ TEST_F(PasswordCheckManagerTest, OnCompromisedCredentialsChanged) {
// This is called on multiple events: once for saved passwords retrieval, // This is called on multiple events: once for saved passwords retrieval,
// once for compromised credentials retrieval and once when the saved password // once for compromised credentials retrieval and once when the saved password
// is added. // is added.
EXPECT_CALL(mock_observer_, OnCompromisedCredentialsChanged(0)).Times(3); EXPECT_CALL(mock_observer(), OnCompromisedCredentialsChanged(0)).Times(3);
InitializeManager(); InitializeManager();
store().AddLogin(MakeSavedPassword(kExampleCom, kUsername1)); store().AddLogin(MakeSavedPassword(kExampleCom, kUsername1));
RunUntilIdle(); RunUntilIdle();
EXPECT_CALL(mock_observer_, OnCompromisedCredentialsChanged(1)); EXPECT_CALL(mock_observer(), OnCompromisedCredentialsChanged(1));
store().AddCompromisedCredentials(MakeCompromised(kExampleCom, kUsername1)); store().AddCompromisedCredentials(MakeCompromised(kExampleCom, kUsername1));
RunUntilIdle(); RunUntilIdle();
} }
...@@ -235,7 +268,7 @@ TEST_F(PasswordCheckManagerTest, CorrectlyCreatesUIStructForSiteCredential) { ...@@ -235,7 +268,7 @@ TEST_F(PasswordCheckManagerTest, CorrectlyCreatesUIStructForSiteCredential) {
store().AddCompromisedCredentials(MakeCompromised(kExampleCom, kUsername1)); store().AddCompromisedCredentials(MakeCompromised(kExampleCom, kUsername1));
RunUntilIdle(); RunUntilIdle();
EXPECT_THAT( EXPECT_THAT(
manager_->GetCompromisedCredentials(), manager().GetCompromisedCredentials(),
ElementsAre(ExpectCompromisedCredentialForUI( ElementsAre(ExpectCompromisedCredentialForUI(
base::ASCIIToUTF16(kUsername1), base::ASCIIToUTF16("example.com"), base::ASCIIToUTF16(kUsername1), base::ASCIIToUTF16("example.com"),
base::nullopt, "https://example.com/", base::nullopt, "https://example.com/",
...@@ -258,7 +291,7 @@ TEST_F(PasswordCheckManagerTest, CorrectlyCreatesUIStructForAppCredentials) { ...@@ -258,7 +291,7 @@ TEST_F(PasswordCheckManagerTest, CorrectlyCreatesUIStructForAppCredentials) {
RunUntilIdle(); RunUntilIdle();
EXPECT_THAT( EXPECT_THAT(
manager_->GetCompromisedCredentials(), manager().GetCompromisedCredentials(),
UnorderedElementsAre( UnorderedElementsAre(
ExpectCompromisedCredentialForUI( ExpectCompromisedCredentialForUI(
base::ASCIIToUTF16(kUsername1), base::ASCIIToUTF16(kUsername1),
...@@ -278,11 +311,11 @@ TEST_F(PasswordCheckManagerTest, SetsTimestampOnSuccessfulCheck) { ...@@ -278,11 +311,11 @@ TEST_F(PasswordCheckManagerTest, SetsTimestampOnSuccessfulCheck) {
RunUntilIdle(); RunUntilIdle();
// Pretend to start the check so that the manager thinks a check is running. // Pretend to start the check so that the manager thinks a check is running.
manager_->StartCheck(); manager().StartCheck();
// Change the state to idle to simulate a successful check finish. // Change the state to idle to simulate a successful check finish.
service()->set_state_and_notify(State::kIdle); service()->set_state_and_notify(State::kIdle);
EXPECT_NE(0.0, manager_->GetLastCheckTimestamp().ToDoubleT()); EXPECT_NE(0.0, manager().GetLastCheckTimestamp().ToDoubleT());
} }
TEST_F(PasswordCheckManagerTest, DoesntRecordTimestampOfUnsuccessfulCheck) { TEST_F(PasswordCheckManagerTest, DoesntRecordTimestampOfUnsuccessfulCheck) {
...@@ -291,11 +324,34 @@ TEST_F(PasswordCheckManagerTest, DoesntRecordTimestampOfUnsuccessfulCheck) { ...@@ -291,11 +324,34 @@ TEST_F(PasswordCheckManagerTest, DoesntRecordTimestampOfUnsuccessfulCheck) {
RunUntilIdle(); RunUntilIdle();
// Pretend to start the check so that the manager thinks a check is running. // Pretend to start the check so that the manager thinks a check is running.
manager_->StartCheck(); manager().StartCheck();
// Change the state to an error state to simulate a unsuccessful check finish. // Change the state to an error state to simulate a unsuccessful check finish.
service()->set_state_and_notify(State::kSignedOut); service()->set_state_and_notify(State::kSignedOut);
EXPECT_EQ(0.0, manager_->GetLastCheckTimestamp().ToDoubleT()); EXPECT_EQ(0.0, manager().GetLastCheckTimestamp().ToDoubleT());
}
TEST_F(PasswordCheckManagerTest, CorrectlyCreatesUIStructWithPasswordScripts) {
InitializeManager();
feature_list().InitAndEnableFeature(
password_manager::features::kPasswordChangeInSettings);
store().AddLogin(MakeSavedPassword(kExampleCom, kUsername1));
store().AddCompromisedCredentials(MakeCompromised(kExampleCom, kUsername1));
RunUntilIdle();
EXPECT_CALL(fetcher(), RefreshScriptsIfNecessary)
.WillOnce(Invoke(
[](base::OnceClosure callback) { std::move(callback).Run(); }));
manager().RefreshScripts();
EXPECT_CALL(fetcher(), IsScriptAvailable).WillRepeatedly(Return(true));
EXPECT_THAT(
manager().GetCompromisedCredentials(),
ElementsAre(ExpectCompromisedCredentialForUI(
base::ASCIIToUTF16(kUsername1), base::ASCIIToUTF16("example.com"),
base::nullopt, "https://example.com/",
CompromiseTypeFlags::kCredentialLeaked, /*has_script=*/true)));
} }
TEST_F(PasswordCheckManagerTest, GetCompromisedCredentialsOrder) { TEST_F(PasswordCheckManagerTest, GetCompromisedCredentialsOrder) {
...@@ -321,7 +377,7 @@ TEST_F(PasswordCheckManagerTest, GetCompromisedCredentialsOrder) { ...@@ -321,7 +377,7 @@ TEST_F(PasswordCheckManagerTest, GetCompromisedCredentialsOrder) {
CompromiseType::kPhished)); CompromiseType::kPhished));
RunUntilIdle(); RunUntilIdle();
EXPECT_THAT( EXPECT_THAT(
manager_->GetCompromisedCredentials(), manager().GetCompromisedCredentials(),
ElementsAre( ElementsAre(
ExpectCompromisedCredentialForUI( ExpectCompromisedCredentialForUI(
base::ASCIIToUTF16(kUsername1), base::ASCIIToUTF16("example.org"), base::ASCIIToUTF16(kUsername1), base::ASCIIToUTF16("example.org"),
......
...@@ -7,6 +7,7 @@ import("//build/config/android/rules.gni") ...@@ -7,6 +7,7 @@ import("//build/config/android/rules.gni")
android_library("java") { android_library("java") {
deps = [ deps = [
"//base:base_java", "//base:base_java",
"//base:jni_java",
"//chrome/browser/settings:java", "//chrome/browser/settings:java",
"//components/password_manager/core/browser:password_manager_java_enums", "//components/password_manager/core/browser:password_manager_java_enums",
"//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_annotation_annotation_java",
...@@ -14,9 +15,16 @@ android_library("java") { ...@@ -14,9 +15,16 @@ android_library("java") {
] ]
sources = [ sources = [
"java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java",
"java/src/org/chromium/chrome/browser/password_manager/PasswordScriptsFetcherBridge.java",
"java/src/org/chromium/chrome/browser/password_manager/settings/PasswordReauthenticationFragment.java", "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordReauthenticationFragment.java",
"java/src/org/chromium/chrome/browser/password_manager/settings/ReauthenticationManager.java", "java/src/org/chromium/chrome/browser/password_manager/settings/ReauthenticationManager.java",
] ]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
}
generate_jni("jni_headers") {
visibility = [ "//chrome/browser" ]
sources = [ "java/src/org/chromium/chrome/browser/password_manager/PasswordScriptsFetcherBridge.java" ]
} }
junit_binary("password_manager_junit_tests") { junit_binary("password_manager_junit_tests") {
......
...@@ -6,20 +6,18 @@ package org.chromium.chrome.browser.password_manager; ...@@ -6,20 +6,18 @@ package org.chromium.chrome.browser.password_manager;
import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.components.embedder_support.browser_context.BrowserContextHandle;
/** /**
* Android bridge to |PasswordScriptsFetcher|. * Android bridge to |PasswordScriptsFetcher|.
*/ */
@JNINamespace("password_manager") @JNINamespace("password_manager")
public class PasswordScriptsFetcherBridge { public class PasswordScriptsFetcherBridge {
public static void prewarmCache(Profile profile) { public static void prewarmCache() {
PasswordScriptsFetcherBridgeJni.get().prewarmCache(profile); PasswordScriptsFetcherBridgeJni.get().prewarmCache();
} }
@NativeMethods @NativeMethods
interface Natives { interface Natives {
void prewarmCache(BrowserContextHandle browserContext); void prewarmCache();
} }
} }
...@@ -5,24 +5,17 @@ ...@@ -5,24 +5,17 @@
#include <jni.h> #include <jni.h>
#include "base/android/scoped_java_ref.h" #include "base/android/scoped_java_ref.h"
#include "chrome/android/chrome_jni_headers/PasswordScriptsFetcherBridge_jni.h" #include "chrome/browser/password_manager/android/jni_headers/PasswordScriptsFetcherBridge_jni.h"
#include "chrome/browser/password_manager/password_scripts_fetcher_factory.h" #include "chrome/browser/password_manager/password_scripts_fetcher_factory.h"
#include "components/embedder_support/android/browser_context/browser_context_handle.h" #include "chrome/browser/profiles/profile_manager.h"
#include "components/password_manager/core/browser/password_scripts_fetcher.h" #include "components/password_manager/core/browser/password_scripts_fetcher.h"
#include "content/public/browser/browser_context.h"
namespace password_manager { namespace password_manager {
// static // static
void JNI_PasswordScriptsFetcherBridge_PrewarmCache( void JNI_PasswordScriptsFetcherBridge_PrewarmCache(JNIEnv* env) {
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jbrowser_context) {
content::BrowserContext* context =
browser_context::BrowserContextFromJavaHandle(jbrowser_context);
DCHECK(context);
PasswordScriptsFetcherFactory::GetInstance() PasswordScriptsFetcherFactory::GetInstance()
->GetForBrowserContext(context) ->GetForBrowserContext(ProfileManager::GetLastUsedProfile())
->PrewarmCache(); ->PrewarmCache();
} }
......
...@@ -9,6 +9,8 @@ import androidx.lifecycle.DefaultLifecycleObserver; ...@@ -9,6 +9,8 @@ import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.password_manager.PasswordScriptsFetcherBridge;
import org.chromium.chrome.browser.settings.SettingsLauncher; import org.chromium.chrome.browser.settings.SettingsLauncher;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor; import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
...@@ -32,6 +34,10 @@ public class SafetyCheckCoordinator implements DefaultLifecycleObserver { ...@@ -32,6 +34,10 @@ public class SafetyCheckCoordinator implements DefaultLifecycleObserver {
public static void create(SafetyCheckSettingsFragment settingsFragment, public static void create(SafetyCheckSettingsFragment settingsFragment,
SafetyCheckUpdatesDelegate updatesClient, SettingsLauncher settingsLauncher) { SafetyCheckUpdatesDelegate updatesClient, SettingsLauncher settingsLauncher) {
new SafetyCheckCoordinator(settingsFragment, updatesClient, settingsLauncher); new SafetyCheckCoordinator(settingsFragment, updatesClient, settingsLauncher);
if (ChromeFeatureList.isEnabled(ChromeFeatureList.PASSWORD_CHANGE_IN_SETTINGS)) {
// Triggers pre-fetching the list of password change scripts.
PasswordScriptsFetcherBridge.prewarmCache();
}
} }
private SafetyCheckCoordinator(SafetyCheckSettingsFragment settingsFragment, private SafetyCheckCoordinator(SafetyCheckSettingsFragment settingsFragment,
......
...@@ -742,7 +742,6 @@ static_library("ui") { ...@@ -742,7 +742,6 @@ static_library("ui") {
"android/passwords/password_generation_dialog_view_android.h", "android/passwords/password_generation_dialog_view_android.h",
"android/passwords/password_generation_editing_popup_view_android.cc", "android/passwords/password_generation_editing_popup_view_android.cc",
"android/passwords/password_generation_editing_popup_view_android.h", "android/passwords/password_generation_editing_popup_view_android.h",
"android/passwords/password_scripts_fetcher_android.cc",
"android/safe_browsing/password_reuse_dialog_view_android.cc", "android/safe_browsing/password_reuse_dialog_view_android.cc",
"android/safe_browsing/password_reuse_dialog_view_android.h", "android/safe_browsing/password_reuse_dialog_view_android.h",
"android/simple_message_box_android.cc", "android/simple_message_box_android.cc",
......
...@@ -27,7 +27,8 @@ class PasswordScriptsFetcher : public KeyedService { ...@@ -27,7 +27,8 @@ class PasswordScriptsFetcher : public KeyedService {
// |PrewarmCache| was supposed to fetch the data in advance). In case of // |PrewarmCache| was supposed to fetch the data in advance). In case of
// several calls of the method, the callbacks will be called one after // several calls of the method, the callbacks will be called one after
// another. // another.
virtual void Fetch(base::OnceClosure fetch_finished_callback) = 0; virtual void RefreshScriptsIfNecessary(
base::OnceClosure fetch_finished_callback) = 0;
// Returns whether there is a password change script for |origin| via // Returns whether there is a password change script for |origin| via
// |callback|. If the cache was never set or is stale, it triggers a re-fetch. // |callback|. If the cache was never set or is stale, it triggers a re-fetch.
// In case of a network error, the verdict will default to no script being // In case of a network error, the verdict will default to no script being
......
...@@ -86,7 +86,7 @@ void PasswordScriptsFetcherImpl::PrewarmCache() { ...@@ -86,7 +86,7 @@ void PasswordScriptsFetcherImpl::PrewarmCache() {
StartFetch(); StartFetch();
} }
void PasswordScriptsFetcherImpl::Fetch( void PasswordScriptsFetcherImpl::RefreshScriptsIfNecessary(
base::OnceClosure fetch_finished_callback) { base::OnceClosure fetch_finished_callback) {
CacheState state = IsCacheStale() CacheState state = IsCacheStale()
? (url_loader_ ? CacheState::kWaiting ? (url_loader_ ? CacheState::kWaiting
......
...@@ -64,7 +64,8 @@ class PasswordScriptsFetcherImpl ...@@ -64,7 +64,8 @@ class PasswordScriptsFetcherImpl
// PasswordScriptsFetcher: // PasswordScriptsFetcher:
void PrewarmCache() override; void PrewarmCache() override;
void Fetch(base::OnceClosure fetch_finished_callback) override; void RefreshScriptsIfNecessary(
base::OnceClosure fetch_finished_callback) override;
void FetchScriptAvailability(const url::Origin& origin, void FetchScriptAvailability(const url::Origin& origin,
ResponseCallback callback) override; ResponseCallback callback) override;
bool IsScriptAvailable(const url::Origin& origin) const override; bool IsScriptAvailable(const url::Origin& origin) const override;
......
...@@ -88,7 +88,7 @@ class PasswordScriptsFetcherImplTest : public ::testing::Test { ...@@ -88,7 +88,7 @@ class PasswordScriptsFetcherImplTest : public ::testing::Test {
void StartBulkCheck() { void StartBulkCheck() {
pending_fetch_finished_callbacks_++; pending_fetch_finished_callbacks_++;
fetcher()->Fetch( fetcher()->RefreshScriptsIfNecessary(
base::BindOnce(&PasswordScriptsFetcherImplTest::RecordFetchFinished, base::BindOnce(&PasswordScriptsFetcherImplTest::RecordFetchFinished,
base::Unretained(this))); base::Unretained(this)));
RequestSingleScriptAvailability(GetOriginWithScript1()); RequestSingleScriptAvailability(GetOriginWithScript1());
......
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