chromium/chrome/browser/password_manager/chrome_password_manager_client.cc

// Copyright 2014 The Chromium Authors
// 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/chrome_password_manager_client.h"

#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/time/time.h"
#include "base/types/optional_util.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "build/buildflag.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/affiliations/affiliation_service_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/device_reauth/chrome_device_authenticator_factory.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/history/history_tab_helper.h"
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/browser/password_manager/account_password_store_factory.h"
#include "chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h"
#include "chrome/browser/password_manager/chrome_webauthn_credentials_delegate_factory.h"
#include "chrome/browser/password_manager/field_info_manager_factory.h"
#include "chrome/browser/password_manager/password_manager_settings_service_factory.h"
#include "chrome/browser/password_manager/password_reuse_manager_factory.h"
#include "chrome/browser/password_manager/profile_password_store_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
#include "chrome/browser/safe_browsing/user_interaction_observer.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/translate/chrome_translate_client.h"
#include "chrome/browser/ui/passwords/password_cross_domain_confirmation_popup_controller_impl.h"
#include "chrome/browser/ui/passwords/password_generation_popup_controller_impl.h"
#include "chrome/browser/ui/passwords/passwords_client_ui_delegate.h"
#include "chrome/browser/ui/passwords/passwords_model_delegate.h"
#include "chrome/browser/ui/passwords/ui_utils.h"
#include "chrome/browser/ui/webauthn/authenticator_request_window.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/webui_url_constants.h"
#include "components/autofill/content/browser/content_autofill_client.h"
#include "components/autofill/content/browser/renderer_forms_with_server_predictions.h"
#include "components/autofill/content/browser/scoped_autofill_managers_observation.h"
#include "components/autofill/core/browser/logging/log_manager.h"
#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
#include "components/autofill/core/common/password_generation_util.h"
#include "components/back_forward_cache/back_forward_cache_disable.h"
#include "components/browsing_data/content/browsing_data_helper.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_contents.h"
#include "components/password_manager/content/browser/bad_message.h"
#include "components/password_manager/content/browser/content_password_manager_driver.h"
#include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
#include "components/password_manager/content/browser/form_meta_data.h"
#include "components/password_manager/content/browser/password_manager_log_router_factory.h"
#include "components/password_manager/content/browser/password_requirements_service_factory.h"
#include "components/password_manager/core/browser/browser_save_password_progress_logger.h"
#include "components/password_manager/core/browser/features/password_features.h"
#include "components/password_manager/core/browser/hsts_query.h"
#include "components/password_manager/core/browser/http_auth_manager.h"
#include "components/password_manager/core/browser/http_auth_manager_impl.h"
#include "components/password_manager/core/browser/leak_detection_dialog_utils.h"
#include "components/password_manager/core/browser/passkey_credential.h"
#include "components/password_manager/core/browser/password_bubble_experiment.h"
#include "components/password_manager/core/browser/password_form.h"
#include "components/password_manager/core/browser/password_form_manager_for_ui.h"
#include "components/password_manager/core/browser/password_manager_constants.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/browser/password_manager_setting.h"
#include "components/password_manager/core/browser/password_manager_settings_service.h"
#include "components/password_manager/core/browser/password_requirements_service.h"
#include "components/password_manager/core/browser/password_store/password_store_interface.h"
#include "components/password_manager/core/browser/password_sync_util.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "components/prefs/pref_service.h"
#include "components/profile_metrics/browser_profile_type.h"
#include "components/safe_browsing/buildflags.h"
#include "components/sessions/content/content_record_password_state.h"
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/site_isolation/site_isolation_policy.h"
#include "components/sync/service/sync_service.h"
#include "components/sync/service/sync_user_settings.h"
#include "components/translate/core/browser/translate_manager.h"
#include "content/public/browser/back_forward_cache.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/page.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "extensions/buildflags/buildflags.h"
#include "net/base/url_util.h"
#include "net/cert/cert_status_flags.h"
#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"

#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
#include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
#include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
#endif

#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/keyboard_accessory/android/manual_filling_controller.h"
#include "chrome/browser/keyboard_accessory/android/password_accessory_controller.h"
#include "chrome/browser/keyboard_accessory/android/password_accessory_controller_impl.h"
#include "chrome/browser/password_manager/android/access_loss/password_access_loss_warning_bridge_impl.h"
#include "chrome/browser/password_manager/android/account_chooser_dialog_android.h"
#include "chrome/browser/password_manager/android/auto_signin_first_run_dialog_android.h"
#include "chrome/browser/password_manager/android/auto_signin_prompt_controller.h"
#include "chrome/browser/password_manager/android/cred_man_controller.h"
#include "chrome/browser/password_manager/android/credential_leak_controller_android.h"
#include "chrome/browser/password_manager/android/local_passwords_migration_warning_util.h"
#include "chrome/browser/password_manager/android/password_checkup_launcher_helper_impl.h"
#include "chrome/browser/password_manager/android/password_generation_controller.h"
#include "chrome/browser/password_manager/android/password_manager_error_message_helper_bridge_impl.h"
#include "chrome/browser/password_manager/android/password_manager_launcher_android.h"
#include "chrome/browser/password_manager/android/password_manager_ui_util_android.h"
#include "chrome/browser/password_manager/android/password_manager_util_bridge.h"
#include "chrome/browser/password_manager/android/password_migration_warning_startup_launcher.h"
#include "chrome/browser/touch_to_fill/password_manager/password_generation/android/touch_to_fill_password_generation_controller.h"
#include "chrome/browser/touch_to_fill/password_manager/touch_to_fill_controller.h"
#include "chrome/browser/touch_to_fill/password_manager/touch_to_fill_controller_autofill_delegate.h"
#include "components/password_manager/content/browser/keyboard_replacing_surface_visibility_controller_impl.h"
#include "components/password_manager/core/browser/credential_cache.h"
#include "components/password_manager/core/browser/password_credential_filler_impl.h"
#include "components/webauthn/android/webauthn_cred_man_delegate.h"
#include "components/webauthn/android/webauthn_cred_man_delegate_factory.h"
#else
#include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h"
#include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/hats/hats_service.h"
#include "chrome/browser/ui/hats/hats_service_factory.h"
#include "chrome/browser/ui/hats/survey_config.h"
#include "components/policy/core/common/features.h"
#endif

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/constants.h"
#endif

#if BUILDFLAG(ENABLE_DICE_SUPPORT)
#include "chrome/browser/signin/dice_web_signin_interceptor_factory.h"
#endif

#if BUILDFLAG(ENABLE_DICE_SUPPORT) || BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/ui/browser.h"
#endif

#if BUILDFLAG(IS_ANDROID)
using base::android::BuildInfo;
using password_manager::CredentialCache;
#endif

FocusedFieldType;
PasswordGenerationType;
BadMessageReason;
ContentPasswordManagerDriverFactory;
FieldInfoManager;
PasswordForm;
PasswordManagerClientHelper;
PasswordManagerDriver;
PasswordManagerMetricsRecorder;
PasswordManagerSetting;
PasswordType;
SerializedNavigationEntry;

// Shorten the name to spare line breaks. The code provides enough context
// already.
Logger;

namespace {

#if !BUILDFLAG(IS_ANDROID)
static const char kPasswordBreachEntryTrigger[] =;
#endif

#if BUILDFLAG(IS_ANDROID)
// TODO(crbug.com/41485955): Get rid of DeprecatedGetOriginAsURL().
url::Origin URLToOrigin(GURL url) {
  return url::Origin::Create(url.DeprecatedGetOriginAsURL());
}

void MaybeShowAccessLossWarning(PrefService* prefs,
                                const gfx::NativeWindow window,
                                Profile* profile) {
  PasswordAccessLossWarningBridgeImpl bridge;
  if (bridge.ShouldShowAccessLossNoticeSheet(prefs)) {
    bridge.MaybeShowAccessLossNoticeSheet(prefs, window, profile);
  }
}
#endif

}  // namespace

// static
void ChromePasswordManagerClient::CreateForWebContents(
    content::WebContents* contents) {}

// static
void ChromePasswordManagerClient::BindPasswordGenerationDriver(
    mojo::PendingAssociatedReceiver<autofill::mojom::PasswordGenerationDriver>
        receiver,
    content::RenderFrameHost* rfh) {}

ChromePasswordManagerClient::~ChromePasswordManagerClient() = default;

bool ChromePasswordManagerClient::IsSavingAndFillingEnabled(
    const GURL& url) const {}

bool ChromePasswordManagerClient::IsFillingEnabled(const GURL& url) const {}

bool ChromePasswordManagerClient::IsAutoSignInEnabled() const {}

void ChromePasswordManagerClient::TriggerUserPerceptionOfPasswordManagerSurvey(
    const std::string& filling_assistance) {}

bool ChromePasswordManagerClient::PromptUserToSaveOrUpdatePassword(
    std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_save,
    bool update_password) {}

void ChromePasswordManagerClient::PromptUserToMovePasswordToAccount(
    std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_move) {}

void ChromePasswordManagerClient::ShowManualFallbackForSaving(
    std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_save,
    bool has_generated_password,
    bool is_update) {}

void ChromePasswordManagerClient::HideManualFallbackForSaving() {}

void ChromePasswordManagerClient::FocusedInputChanged(
    PasswordManagerDriver* driver,
    autofill::FieldRendererId focused_field_id,
    autofill::mojom::FocusedFieldType focused_field_type) {}

bool ChromePasswordManagerClient::PromptUserToChooseCredentials(
    std::vector<std::unique_ptr<PasswordForm>> local_forms,
    const url::Origin& origin,
    CredentialsCallback callback) {}

#if BUILDFLAG(IS_ANDROID)
void ChromePasswordManagerClient::ShowPasswordManagerErrorMessage(
    password_manager::ErrorMessageFlowType flow_type,
    password_manager::PasswordStoreBackendErrorType error_type) {
  bool oldGMSSavingDisabled = error_type ==
                              password_manager::PasswordStoreBackendErrorType::
                                  kGMSCoreOutdatedSavingDisabled;
  bool oldGMSSavingPossible = error_type ==
                              password_manager::PasswordStoreBackendErrorType::
                                  kGMSCoreOutdatedSavingPossible;
  bool noPlayStore = !password_manager_android_util::IsPlayStoreAppPresent();
  if ((oldGMSSavingDisabled || oldGMSSavingPossible) && noPlayStore) {
    return;
  }
  if (!password_manager_error_message_delegate_) {
    password_manager_error_message_delegate_ =
        std::make_unique<PasswordManagerErrorMessageDelegate>(
            std::make_unique<PasswordManagerErrorMessageHelperBridgeImpl>());
    password_manager_error_message_delegate_->MaybeDisplayErrorMessage(
        web_contents(), GetPrefs(), flow_type, error_type,
        base::BindOnce(&ChromePasswordManagerClient::ResetErrorMessageDelegate,
                       base::Unretained(this)));
  }
}

void ChromePasswordManagerClient::ShowKeyboardReplacingSurface(
    password_manager::PasswordManagerDriver* driver,
    const password_manager::PasswordFillingParams& password_filling_params,
    bool is_webauthn_form,
    base::OnceCallback<void(bool)> shown_cb) {
  if (base::FeatureList::IsEnabled(
          password_manager::features::kPasswordSuggestionBottomSheetV2) &&
      keyboard_replacing_surface_visibility_controller_ &&
      !keyboard_replacing_surface_visibility_controller_->CanBeShown()) {
    std::move(shown_cb).Run(
        keyboard_replacing_surface_visibility_controller_->IsVisible());
    return;
  }

  password_manager::ContentPasswordManagerDriver* content_driver =
      static_cast<password_manager::ContentPasswordManagerDriver*>(driver);

  if (GetOrCreateCredManController()->Show(
          GetWebAuthnCredManDelegateForDriver(driver),
          std::make_unique<password_manager::PasswordCredentialFillerImpl>(
              driver->AsWeakPtr(), password_filling_params),
          content_driver->AsWeakPtrImpl(), is_webauthn_form)) {
    std::move(shown_cb).Run(true);
    return;
  }

  // base::Unretained() is safe: if the callback is called, AccountStorageNotice
  // is alive, then so is its parent ChromePasswordManagerClient.
  MaybeShowAccountStorageNotice(
      base::BindOnce(&ChromePasswordManagerClient::
                         ShowKeyboardReplacingSurfaceOnAccountStorageNoticeDone,
                     base::Unretained(this), content_driver->AsWeakPtrImpl(),
                     password_filling_params, std::move(shown_cb)));
}

void ChromePasswordManagerClient::
    ShowKeyboardReplacingSurfaceOnAccountStorageNoticeDone(
        base::WeakPtr<password_manager::ContentPasswordManagerDriver>
            weak_driver,
        const password_manager::PasswordFillingParams& password_filling_params,
        base::OnceCallback<void(bool)> shown_cb) {
  // TODO(crbug.com/346748438): Maybe don't show TTF if there was a navigation.
  if (!weak_driver) {
    return std::move(shown_cb).Run(false);
  }

  password_manager::ContentPasswordManagerDriver* driver = weak_driver.get();
  auto* webauthn_delegate = GetWebAuthnCredentialsDelegateForDriver(driver);
  std::vector<password_manager::PasskeyCredential> passkeys;
  bool should_show_hybrid_option = false;
  if (webauthn_delegate && webauthn_delegate->GetPasskeys().has_value()) {
    passkeys = *webauthn_delegate->GetPasskeys();
    should_show_hybrid_option = webauthn_delegate->IsAndroidHybridAvailable();
  }
  auto filler =
      std::make_unique<password_manager::PasswordCredentialFillerImpl>(
          driver->AsWeakPtr(), password_filling_params);
  const PasswordForm* form_to_fill = password_manager_.GetParsedObservedForm(
      driver, password_filling_params.focused_field_renderer_id_);
  auto ttf_controller_autofill_delegate =
      std::make_unique<TouchToFillControllerAutofillDelegate>(
          this, GetDeviceAuthenticator(), webauthn_delegate->AsWeakPtr(),
          std::move(filler), form_to_fill,
          password_filling_params.focused_field_renderer_id_,
          TouchToFillControllerAutofillDelegate::ShowHybridOption(
              should_show_hybrid_option));

  const bool shown = GetOrCreateTouchToFillController()->Show(
      credential_cache_
          .GetCredentialStore(URLToOrigin(driver->GetLastCommittedURL()))
          .GetCredentials(),
      passkeys, std::move(ttf_controller_autofill_delegate),
      GetWebAuthnCredManDelegateForDriver(driver), driver->AsWeakPtrImpl());
  std::move(shown_cb).Run(shown);
}
#endif

bool ChromePasswordManagerClient::IsReauthBeforeFillingRequired(
    device_reauth::DeviceAuthenticator* authenticator) {}

std::unique_ptr<device_reauth::DeviceAuthenticator>
ChromePasswordManagerClient::GetDeviceAuthenticator() {}

void ChromePasswordManagerClient::GeneratePassword(
    PasswordGenerationType type) {}

void ChromePasswordManagerClient::NotifyUserAutoSignin(
    std::vector<std::unique_ptr<PasswordForm>> local_forms,
    const url::Origin& origin) {}

void ChromePasswordManagerClient::NotifyUserCouldBeAutoSignedIn(
    std::unique_ptr<PasswordForm> form) {}

void ChromePasswordManagerClient::NotifySuccessfulLoginWithExistingPassword(
    std::unique_ptr<password_manager::PasswordFormManagerForUI>
        submitted_manager) {}

void ChromePasswordManagerClient::NotifyStorePasswordCalled() {}

#if BUILDFLAG(IS_ANDROID)
void ChromePasswordManagerClient::StartSubmissionTrackingAfterTouchToFill(
    const std::u16string& filled_username) {
  username_filled_by_touch_to_fill_ =
      std::make_pair(filled_username, base::Time::Now());
}

void ChromePasswordManagerClient::NotifyOnSuccessfulLogin(
    const std::u16string& submitted_username) {
  if (!username_filled_by_touch_to_fill_) {
    return;
  }

  base::TimeDelta delta =
      base::Time::Now() - username_filled_by_touch_to_fill_->second;
  // Filter out unrelated logins.
  if (delta < base::Minutes(1) &&
      username_filled_by_touch_to_fill_->first == submitted_username) {
    UmaHistogramMediumTimes("PasswordManager.TouchToFill.TimeToSuccessfulLogin",
                            delta);
    ukm::builders::TouchToFill_TimeToSuccessfulLogin(GetUkmSourceId())
        .SetTimeToSuccessfulLogin(
            ukm::GetExponentialBucketMinForUserTiming(delta.InMilliseconds()))
        .Record(ukm::UkmRecorder::Get());

    base::UmaHistogramBoolean(
        "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", true);
    username_filled_by_touch_to_fill_.reset();
  } else {
    ResetSubmissionTrackingAfterTouchToFill();
  }
}

void ChromePasswordManagerClient::ResetSubmissionTrackingAfterTouchToFill() {
  if (username_filled_by_touch_to_fill_.has_value()) {
    base::UmaHistogramBoolean(
        "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", false);
    username_filled_by_touch_to_fill_.reset();
  }
}
#endif  // BUILDFLAG(IS_ANDROID)

void ChromePasswordManagerClient::UpdateCredentialCache(
    const url::Origin& origin,
    base::span<const PasswordForm> best_matches,
    bool is_blocklisted) {}

void ChromePasswordManagerClient::AutomaticPasswordSave(
    std::unique_ptr<password_manager::PasswordFormManagerForUI> saved_form,
    bool is_update_confirmation) {}

void ChromePasswordManagerClient::PasswordWasAutofilled(
    base::span<const PasswordForm> best_matches,
    const url::Origin& origin,
    base::span<const PasswordForm> federated_matches,
    bool was_autofilled_on_pageload) {}

void ChromePasswordManagerClient::AutofillHttpAuth(
    const PasswordForm& preferred_match,
    const password_manager::PasswordFormManagerForUI* form_manager) {}

void ChromePasswordManagerClient::NotifyUserCredentialsWereLeaked(
    password_manager::CredentialLeakType leak_type,
    const GURL& url,
    const std::u16string& username,
    bool in_account_store) {}

void ChromePasswordManagerClient::NotifyKeychainError() {}

void ChromePasswordManagerClient::TriggerReauthForPrimaryAccount(
    signin_metrics::ReauthAccessPoint access_point,
    base::OnceCallback<void(ReauthSucceeded)> reauth_callback) {}

void ChromePasswordManagerClient::TriggerSignIn(
    signin_metrics::AccessPoint access_point) {}

PrefService* ChromePasswordManagerClient::GetPrefs() const {}

PrefService* ChromePasswordManagerClient::GetLocalStatePrefs() const {}

const syncer::SyncService* ChromePasswordManagerClient::GetSyncService() const {}

affiliations::AffiliationService*
ChromePasswordManagerClient::GetAffiliationService() {}

password_manager::PasswordStoreInterface*
ChromePasswordManagerClient::GetProfilePasswordStore() const {}

password_manager::PasswordStoreInterface*
ChromePasswordManagerClient::GetAccountPasswordStore() const {}

password_manager::PasswordReuseManager*
ChromePasswordManagerClient::GetPasswordReuseManager() const {}

bool ChromePasswordManagerClient::WasLastNavigationHTTPError() const {}

net::CertStatus ChromePasswordManagerClient::GetMainFrameCertStatus() const {}

void ChromePasswordManagerClient::PromptUserToEnableAutosignin() {}

bool ChromePasswordManagerClient::IsOffTheRecord() const {}

profile_metrics::BrowserProfileType
ChromePasswordManagerClient::GetProfileType() const {}

const password_manager::PasswordManager*
ChromePasswordManagerClient::GetPasswordManager() const {}

const password_manager::PasswordFeatureManager*
ChromePasswordManagerClient::GetPasswordFeatureManager() const {}

password_manager::HttpAuthManager*
ChromePasswordManagerClient::GetHttpAuthManager() {}

autofill::AutofillCrowdsourcingManager*
ChromePasswordManagerClient::GetAutofillCrowdsourcingManager() {}

bool ChromePasswordManagerClient::IsCommittedMainFrameSecure() const {}

const GURL& ChromePasswordManagerClient::GetLastCommittedURL() const {}

url::Origin ChromePasswordManagerClient::GetLastCommittedOrigin() const {}
const password_manager::CredentialsFilter*
ChromePasswordManagerClient::GetStoreResultFilter() const {}

autofill::LogManager* ChromePasswordManagerClient::GetLogManager() {}

void ChromePasswordManagerClient::AnnotateNavigationEntry(
    bool has_password_field) {}

autofill::LanguageCode ChromePasswordManagerClient::GetPageLanguage() const {}

safe_browsing::PasswordProtectionService*
ChromePasswordManagerClient::GetPasswordProtectionService() const {}

#if defined(ON_FOCUS_PING_ENABLED)
void ChromePasswordManagerClient::CheckSafeBrowsingReputation(
    const GURL& form_action,
    const GURL& frame_url) {}
#endif  // defined(ON_FOCUS_PING_ENABLED)

#if !BUILDFLAG(IS_ANDROID)
void ChromePasswordManagerClient::MaybeReportEnterpriseLoginEvent(
    const GURL& url,
    bool is_federated,
    const url::SchemeHostPort& federated_origin,
    const std::u16string& login_user_name) const {}

void ChromePasswordManagerClient::MaybeReportEnterprisePasswordBreachEvent(
    const std::vector<std::pair<GURL, std::u16string>>& identities) const {}
#endif

ukm::SourceId ChromePasswordManagerClient::GetUkmSourceId() {}

PasswordManagerMetricsRecorder*
ChromePasswordManagerClient::GetMetricsRecorder() {}

password_manager::PasswordRequirementsService*
ChromePasswordManagerClient::GetPasswordRequirementsService() {}

favicon::FaviconService* ChromePasswordManagerClient::GetFaviconService() {}

signin::IdentityManager* ChromePasswordManagerClient::GetIdentityManager() {}

FieldInfoManager* ChromePasswordManagerClient::GetFieldInfoManager() const {}

scoped_refptr<network::SharedURLLoaderFactory>
ChromePasswordManagerClient::GetURLLoaderFactory() {}

network::mojom::NetworkContext* ChromePasswordManagerClient::GetNetworkContext()
    const {}

void ChromePasswordManagerClient::UpdateFormManagers() {}

void ChromePasswordManagerClient::NavigateToManagePasswordsPage(
    password_manager::ManagePasswordsReferrer referrer) {}

#if BUILDFLAG(IS_ANDROID)
void ChromePasswordManagerClient::NavigateToManagePasskeysPage(
    password_manager::ManagePasswordsReferrer referrer) {
  password_manager_launcher::ShowPasswordSettings(web_contents(), referrer,
                                                  /*manage_passkeys=*/true);
}
#endif

bool ChromePasswordManagerClient::IsIsolationForPasswordSitesEnabled() const {}

bool ChromePasswordManagerClient::IsNewTabPage() const {}

password_manager::WebAuthnCredentialsDelegate*
ChromePasswordManagerClient::GetWebAuthnCredentialsDelegateForDriver(
    PasswordManagerDriver* driver) {}

#if BUILDFLAG(IS_ANDROID)
webauthn::WebAuthnCredManDelegate*
ChromePasswordManagerClient::GetWebAuthnCredManDelegateForDriver(
    PasswordManagerDriver* driver) {
  auto* frame_host =
      static_cast<password_manager::ContentPasswordManagerDriver*>(driver)
          ->render_frame_host();
  return webauthn::WebAuthnCredManDelegateFactory::GetFactory(web_contents())
      ->GetRequestDelegate(frame_host);
}

void ChromePasswordManagerClient::MarkSharedCredentialsAsNotified(
    const GURL& url) {
  for (const PasswordForm& form :
       credential_cache_.GetCredentialStore(URLToOrigin(url))
           .GetUnnotifiedSharedCredentials()) {
    // Make a non-const copy so we can modify it.
    password_manager::PasswordForm updatedForm = form;
    updatedForm.sharing_notification_displayed = true;
    if (updatedForm.IsUsingAccountStore()) {
      GetAccountPasswordStore()->UpdateLogin(std::move(updatedForm));
    } else {
      GetProfilePasswordStore()->UpdateLogin(std::move(updatedForm));
    }
  }
}

#endif  // BUILDFLAG(IS_ANDROID)

version_info::Channel ChromePasswordManagerClient::GetChannel() const {}

void ChromePasswordManagerClient::RefreshPasswordManagerSettingsIfNeeded()
    const {}

#if !BUILDFLAG(IS_ANDROID)
void ChromePasswordManagerClient::OpenPasswordDetailsBubble(
    const PasswordForm& form) {}

std::unique_ptr<
    password_manager::PasswordCrossDomainConfirmationPopupController>
ChromePasswordManagerClient::ShowCrossDomainConfirmationPopup(
    const gfx::RectF& element_bounds,
    base::i18n::TextDirection text_direction,
    const GURL& domain,
    const std::u16string& password_origin,
    base::OnceClosure confirmation_callback) {}
#endif  // !BUILDFLAG(IS_ANDROID)

void ChromePasswordManagerClient::AutomaticGenerationAvailable(
    const autofill::password_generation::PasswordGenerationUIData& ui_data) {}

void ChromePasswordManagerClient::ShowPasswordEditingPopup(
    const gfx::RectF& bounds,
    const autofill::FormData& form_data,
    autofill::FieldRendererId field_renderer_id,
    const std::u16string& password_value) {}

void ChromePasswordManagerClient::PasswordGenerationRejectedByTyping() {}

void ChromePasswordManagerClient::PresaveGeneratedPassword(
    const autofill::FormData& form_data,
    const std::u16string& password_value) {}

void ChromePasswordManagerClient::PasswordNoLongerGenerated(
    const autofill::FormData& form_data) {}

void ChromePasswordManagerClient::FrameWasScrolled() {}

void ChromePasswordManagerClient::GenerationElementLostFocus() {}

void ChromePasswordManagerClient::SetTestObserver(
    PasswordGenerationPopupObserver* observer) {}

// static
void ChromePasswordManagerClient::BindCredentialManager(
    content::RenderFrameHost* render_frame_host,
    mojo::PendingReceiver<blink::mojom::CredentialManager> receiver) {}

// static
bool ChromePasswordManagerClient::CanShowBubbleOnURL(const GURL& url) {}

#if BUILDFLAG(IS_ANDROID)
PasswordAccessoryController*
ChromePasswordManagerClient::GetOrCreatePasswordAccessory() {
  return PasswordAccessoryController::GetOrCreate(web_contents(),
                                                  &credential_cache_);
}

TouchToFillController*
ChromePasswordManagerClient::GetOrCreateTouchToFillController() {
  if (!touch_to_fill_controller_) {
    touch_to_fill_controller_ = std::make_unique<TouchToFillController>(
        profile_, GetOrCreateKeyboardReplacingSurfaceVisibilityController());
  }
  return touch_to_fill_controller_.get();
}

void ChromePasswordManagerClient::MaybeShowAccountStorageNotice(
    base::OnceClosure callback) {
  // Unretained() is safe because `this` outlives `account_storage_notice_`.
  auto destroy_notice_cb = base::BindOnce(
      [](ChromePasswordManagerClient* client) {
        client->account_storage_notice_.reset();
      },
      base::Unretained(this));
  const bool had_notice = account_storage_notice_.get();
  account_storage_notice_ = AccountStorageNotice::MaybeShow(
      SyncServiceFactory::GetForProfile(profile_), profile_->GetPrefs(),
      web_contents()->GetNativeView()->GetWindowAndroid(),
      std::move(destroy_notice_cb).Then(std::move(callback)));
  // MaybeShow() will return non-null at most once, since this is a one-off
  // notice. So the possible cases are:
  // - `account_storage_notice_` was null and stayed so:  No notice shown, just
  //   invokes `callback`.
  // - `account_storage_notice_` was null and became non-null: Shows the notice.
  // - (Speculative) `account_storage_notice_` was non-null and became null:
  //   Hides the notice and executes `callback`. The alternative would be to
  //   ignore `callback` and wait for `account_storage_notice_` to go away, but
  //   that's dangerous (if there's a bug and `account_storage_notice_` is never
  //   reset, the method would always no-op, breaking the saving/filling
  //   callers).
  CHECK(!had_notice || !account_storage_notice_);
}

password_manager::CredManController*
ChromePasswordManagerClient::GetOrCreateCredManController() {
  if (!cred_man_controller_) {
    cred_man_controller_ =
        std::make_unique<password_manager::CredManController>(
            GetOrCreateKeyboardReplacingSurfaceVisibilityController(), this);
  }
  return cred_man_controller_.get();
}

base::WeakPtr<password_manager::KeyboardReplacingSurfaceVisibilityController>
ChromePasswordManagerClient::
    GetOrCreateKeyboardReplacingSurfaceVisibilityController() {
  if (!keyboard_replacing_surface_visibility_controller_) {
    keyboard_replacing_surface_visibility_controller_ = std::make_unique<
        password_manager::KeyboardReplacingSurfaceVisibilityControllerImpl>();
  }
  return keyboard_replacing_surface_visibility_controller_->AsWeakPtr();
}
#endif  // BUILDFLAG(IS_ANDROID)

ChromePasswordManagerClient::ChromePasswordManagerClient(
    content::WebContents* web_contents)
    :{}

void ChromePasswordManagerClient::PrimaryPageChanged(content::Page& page) {}

void ChromePasswordManagerClient::WebContentsDestroyed() {}

void ChromePasswordManagerClient::OnFieldTypesDetermined(
    autofill::AutofillManager& manager,
    autofill::FormGlobalId form_id,
    FieldTypeSource source) {}

password_manager::ContentPasswordManagerDriverFactory*
ChromePasswordManagerClient::GetDriverFactory() const {}

gfx::RectF ChromePasswordManagerClient::GetBoundsInScreenSpace(
    const gfx::RectF& bounds) {}

void ChromePasswordManagerClient::HideFillingUI() {}

bool ChromePasswordManagerClient::IsPasswordManagementEnabledForCurrentPage(
    const GURL& url) const {}

void ChromePasswordManagerClient::GenerationResultAvailable(
    PasswordGenerationType type,
    base::WeakPtr<password_manager::ContentPasswordManagerDriver> driver,
    const std::optional<
        autofill::password_generation::PasswordGenerationUIData>& ui_data) {}

void ChromePasswordManagerClient::ShowPasswordGenerationPopup(
    PasswordGenerationType type,
    password_manager::ContentPasswordManagerDriver* driver,
    const autofill::password_generation::PasswordGenerationUIData& ui_data) {}

gfx::RectF ChromePasswordManagerClient::TransformToRootCoordinates(
    content::RenderFrameHost* frame_host,
    const gfx::RectF& bounds_in_frame_coordinates) {}

#if BUILDFLAG(IS_ANDROID)
void ChromePasswordManagerClient::ResetErrorMessageDelegate() {
  password_manager_error_message_delegate_.reset();
}

void ChromePasswordManagerClient::TryToShowLocalPasswordMigrationWarning() {
  password_manager::PasswordStoreInterface* profile_password_store =
      GetProfilePasswordStore();
  if (profile_password_store == nullptr) {
    return;
  }
  password_migration_warning_startup_launcher_ =
      std::make_unique<PasswordMigrationWarningStartupLauncher>(
          web_contents(), profile_,
          base::BindOnce(&local_password_migration::ShowWarning));
  password_migration_warning_startup_launcher_
      ->MaybeFetchPasswordsAndShowWarning(profile_password_store);
}

void ChromePasswordManagerClient::TryToShowPostPasswordMigrationSheet() {
  // This is to let the method run after all the initialization tasks have been
  // completed.
  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE,
      base::BindOnce(&local_password_migration::MaybeShowPostMigrationSheet,
                     web_contents()->GetTopLevelNativeWindow(), profile_));
}

void ChromePasswordManagerClient::TryToShowAccessLossWarningSheet() {
  // This is to let the method run after all the initialization tasks have been
  // completed.
  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE,
      base::BindOnce(&MaybeShowAccessLossWarning, GetPrefs(),
                     web_contents()->GetTopLevelNativeWindow(), profile_));
}
#endif

WEB_CONTENTS_USER_DATA_KEY_IMPL(ChromePasswordManagerClient);