blob: fb33c1b91d19df5e03a95871ec6b59c743024240 [file] [log] [blame]
// Copyright 2013 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.
#import "ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h"
#include <utility>
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h"
#include "components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h"
#include "components/autofill/core/browser/form_data_importer.h"
#include "components/autofill/core/browser/payments/payments_client.h"
#include "components/autofill/core/browser/ui/card_unmask_prompt_view.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/ios/browser/autofill_util.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/infobars/core/infobar.h"
#include "components/keyed_service/core/service_access_type.h"
#include "components/translate/core/browser/translate_manager.h"
#include "ios/chrome/browser/application_context.h"
#include "ios/chrome/browser/autofill/address_normalizer_factory.h"
#include "ios/chrome/browser/autofill/legacy_strike_database_factory.h"
#include "ios/chrome/browser/autofill/personal_data_manager_factory.h"
#include "ios/chrome/browser/infobars/infobar.h"
#include "ios/chrome/browser/infobars/infobar_utils.h"
#include "ios/chrome/browser/metrics/ukm_url_recorder.h"
#include "ios/chrome/browser/signin/identity_manager_factory.h"
#import "ios/chrome/browser/ssl/insecure_input_tab_helper.h"
#include "ios/chrome/browser/ssl/ios_security_state_tab_helper.h"
#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
#include "ios/chrome/browser/translate/chrome_ios_translate_client.h"
#include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h"
#include "ios/chrome/browser/ui/autofill/save_card_infobar_controller.h"
#include "ios/chrome/browser/web_data_service_factory.h"
#include "ios/chrome/common/channel_info.h"
#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Creates and returns an infobar for saving credit cards.
std::unique_ptr<infobars::InfoBar> CreateSaveCardInfoBarMobile(
std::unique_ptr<autofill::AutofillSaveCardInfoBarDelegateMobile> delegate) {
SaveCardInfoBarController* controller = [[SaveCardInfoBarController alloc]
initWithInfoBarDelegate:delegate.get()];
return std::make_unique<InfoBarIOS>(controller, std::move(delegate));
}
} // namespace
namespace autofill {
ChromeAutofillClientIOS::ChromeAutofillClientIOS(
ios::ChromeBrowserState* browser_state,
web::WebState* web_state,
infobars::InfoBarManager* infobar_manager,
id<AutofillClientIOSBridge> bridge,
password_manager::PasswordGenerationManager* password_generation_manager)
: pref_service_(browser_state->GetPrefs()),
sync_service_(
ProfileSyncServiceFactory::GetForBrowserState(browser_state)),
personal_data_manager_(PersonalDataManagerFactory::GetForBrowserState(
browser_state->GetOriginalChromeBrowserState())),
web_state_(web_state),
bridge_(bridge),
identity_manager_(IdentityManagerFactory::GetForBrowserState(
browser_state->GetOriginalChromeBrowserState())),
payments_client_(std::make_unique<payments::PaymentsClient>(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
web_state_->GetBrowserState()->GetURLLoaderFactory()),
pref_service_,
identity_manager_,
personal_data_manager_,
web_state_->GetBrowserState()->IsOffTheRecord())),
form_data_importer_(std::make_unique<FormDataImporter>(
this,
payments_client_.get(),
personal_data_manager_,
GetApplicationContext()->GetApplicationLocale())),
legacy_strike_database_(LegacyStrikeDatabaseFactory::GetForBrowserState(
browser_state->GetOriginalChromeBrowserState())),
autofill_web_data_service_(
ios::WebDataServiceFactory::GetAutofillWebDataForBrowserState(
browser_state,
ServiceAccessType::EXPLICIT_ACCESS)),
infobar_manager_(infobar_manager),
password_generation_manager_(password_generation_manager),
unmask_controller_(browser_state->GetPrefs(),
browser_state->IsOffTheRecord()) {}
ChromeAutofillClientIOS::~ChromeAutofillClientIOS() {
HideAutofillPopup();
}
void ChromeAutofillClientIOS::SetBaseViewController(
UIViewController* base_view_controller) {
base_view_controller_ = base_view_controller;
}
version_info::Channel ChromeAutofillClientIOS::GetChannel() const {
return ::GetChannel();
}
PersonalDataManager* ChromeAutofillClientIOS::GetPersonalDataManager() {
return personal_data_manager_;
}
scoped_refptr<AutofillWebDataService> ChromeAutofillClientIOS::GetDatabase() {
return autofill_web_data_service_;
}
PrefService* ChromeAutofillClientIOS::GetPrefs() {
return pref_service_;
}
syncer::SyncService* ChromeAutofillClientIOS::GetSyncService() {
return sync_service_;
}
identity::IdentityManager* ChromeAutofillClientIOS::GetIdentityManager() {
return identity_manager_;
}
FormDataImporter* ChromeAutofillClientIOS::GetFormDataImporter() {
return form_data_importer_.get();
}
payments::PaymentsClient* ChromeAutofillClientIOS::GetPaymentsClient() {
return payments_client_.get();
}
LegacyStrikeDatabase* ChromeAutofillClientIOS::GetLegacyStrikeDatabase() {
return legacy_strike_database_;
}
ukm::UkmRecorder* ChromeAutofillClientIOS::GetUkmRecorder() {
return GetApplicationContext()->GetUkmRecorder();
}
ukm::SourceId ChromeAutofillClientIOS::GetUkmSourceId() {
return ukm::GetSourceIdForWebStateDocument(web_state_);
}
AddressNormalizer* ChromeAutofillClientIOS::GetAddressNormalizer() {
if (base::FeatureList::IsEnabled(features::kAutofillAddressNormalizer))
return AddressNormalizerFactory::GetInstance();
return nullptr;
}
security_state::SecurityLevel
ChromeAutofillClientIOS::GetSecurityLevelForUmaHistograms() {
auto* ios_security_state_tab_helper =
IOSSecurityStateTabHelper::FromWebState(web_state_);
// If there is no helper, return SECURITY_LEVEL_COUNT which won't be logged.
if (!ios_security_state_tab_helper)
return security_state::SecurityLevel::SECURITY_LEVEL_COUNT;
security_state::SecurityInfo result;
ios_security_state_tab_helper->GetSecurityInfo(&result);
return result.security_level;
}
std::string ChromeAutofillClientIOS::GetPageLanguage() const {
// TODO(crbug.com/912597): iOS vs other platforms extracts language from
// the top level frame vs whatever frame directly holds the form.
auto* translate_client = ChromeIOSTranslateClient::FromWebState(web_state_);
if (translate_client) {
auto* translate_manager = translate_client->GetTranslateManager();
if (translate_manager)
return translate_manager->GetLanguageState().original_language();
}
return std::string();
}
void ChromeAutofillClientIOS::ShowAutofillSettings(
bool show_credit_card_settings) {
NOTREACHED();
}
void ChromeAutofillClientIOS::ShowUnmaskPrompt(
const CreditCard& card,
UnmaskCardReason reason,
base::WeakPtr<CardUnmaskDelegate> delegate) {
unmask_controller_.ShowPrompt(
// autofill::CardUnmaskPromptViewBridge manages its own lifetime, so
// do not use std::unique_ptr<> here.
new autofill::CardUnmaskPromptViewBridge(&unmask_controller_,
base_view_controller_),
card, reason, delegate);
}
void ChromeAutofillClientIOS::OnUnmaskVerificationResult(
PaymentsRpcResult result) {
unmask_controller_.OnVerificationResult(result);
}
void ChromeAutofillClientIOS::ShowLocalCardMigrationDialog(
base::OnceClosure show_migration_dialog_closure) {
NOTIMPLEMENTED();
}
void ChromeAutofillClientIOS::ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
const std::vector<MigratableCreditCard>& migratable_credit_cards,
LocalCardMigrationCallback start_migrating_cards_callback) {
NOTIMPLEMENTED();
}
void ChromeAutofillClientIOS::ShowLocalCardMigrationResults(
const base::string16& tip_message,
const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) {
NOTIMPLEMENTED();
}
void ChromeAutofillClientIOS::ConfirmSaveAutofillProfile(
const AutofillProfile& profile,
base::OnceClosure callback) {
// Since there is no confirmation needed to save an Autofill Profile,
// running |callback| will proceed with saving |profile|.
std::move(callback).Run();
}
void ChromeAutofillClientIOS::ConfirmSaveCreditCardLocally(
const CreditCard& card,
bool show_prompt,
base::OnceClosure callback) {
DCHECK(show_prompt);
infobar_manager_->AddInfoBar(CreateSaveCardInfoBarMobile(
std::make_unique<AutofillSaveCardInfoBarDelegateMobile>(
/*upload=*/false, /*should_request_name_from_user=*/false, card,
std::make_unique<base::DictionaryValue>(), GetLegacyStrikeDatabase(),
/*upload_save_card_callback=*/UserAcceptedUploadCallback(),
/*local_save_card_callback=*/std::move(callback), GetPrefs())));
}
void ChromeAutofillClientIOS::ConfirmSaveCreditCardToCloud(
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
bool should_request_name_from_user,
bool should_request_expiration_date_from_user,
bool show_prompt,
UserAcceptedUploadCallback callback) {
DCHECK(show_prompt);
auto save_card_info_bar_delegate_mobile =
std::make_unique<AutofillSaveCardInfoBarDelegateMobile>(
/*upload=*/true, /*should_request_name_from_user=*/false, card,
std::move(legal_message), GetLegacyStrikeDatabase(),
/*upload_save_card_callback=*/std::move(callback),
/*local_save_card_callback=*/base::Closure(), GetPrefs());
// Allow user to save card only if legal messages are successfully parsed.
// Legal messages are provided only for the upload case, not for local save.
if (save_card_info_bar_delegate_mobile->LegalMessagesParsedSuccessfully()) {
infobar_manager_->AddInfoBar(CreateSaveCardInfoBarMobile(
std::move(save_card_info_bar_delegate_mobile)));
}
}
void ChromeAutofillClientIOS::ConfirmCreditCardFillAssist(
const CreditCard& card,
base::OnceClosure callback) {
auto infobar_delegate =
std::make_unique<AutofillCreditCardFillingInfoBarDelegateMobile>(
card, std::move(callback));
auto* raw_delegate = infobar_delegate.get();
if (infobar_manager_->AddInfoBar(
::CreateConfirmInfoBar(std::move(infobar_delegate)))) {
raw_delegate->set_was_shown();
}
}
bool ChromeAutofillClientIOS::HasCreditCardScanFeature() {
return false;
}
void ChromeAutofillClientIOS::ScanCreditCard(
const CreditCardScanCallback& callback) {
NOTREACHED();
}
void ChromeAutofillClientIOS::ShowAutofillPopup(
const gfx::RectF& element_bounds,
base::i18n::TextDirection text_direction,
const std::vector<Suggestion>& suggestions,
bool /*unused_autoselect_first_suggestion*/,
base::WeakPtr<AutofillPopupDelegate> delegate) {
[bridge_ showAutofillPopup:suggestions popupDelegate:delegate];
}
void ChromeAutofillClientIOS::UpdateAutofillPopupDataListValues(
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
NOTREACHED();
}
void ChromeAutofillClientIOS::HideAutofillPopup() {
[bridge_ hideAutofillPopup];
}
bool ChromeAutofillClientIOS::IsAutocompleteEnabled() {
return prefs::IsAutocompleteEnabled(GetPrefs());
}
void ChromeAutofillClientIOS::PropagateAutofillPredictions(
content::RenderFrameHost* rfh,
const std::vector<FormStructure*>& forms) {
if (password_generation_manager_) {
password_generation_manager_->DetectFormsEligibleForGeneration(forms);
}
}
void ChromeAutofillClientIOS::DidFillOrPreviewField(
const base::string16& autofilled_value,
const base::string16& profile_full_name) {}
void ChromeAutofillClientIOS::DidInteractWithNonsecureCreditCardInput() {
InsecureInputTabHelper::GetOrCreateForWebState(web_state_)
->DidInteractWithNonsecureCreditCardInput();
}
bool ChromeAutofillClientIOS::IsContextSecure() {
return IsContextSecureForWebState(web_state_);
}
bool ChromeAutofillClientIOS::ShouldShowSigninPromo() {
return false;
}
bool ChromeAutofillClientIOS::AreServerCardsSupported() {
return true;
}
void ChromeAutofillClientIOS::ExecuteCommand(int id) {
NOTIMPLEMENTED();
}
void ChromeAutofillClientIOS::LoadRiskData(
base::OnceCallback<void(const std::string&)> callback) {
std::move(callback).Run(ios::GetChromeBrowserProvider()->GetRiskData());
}
} // namespace autofill