blob: c5575bd733db042b2a006ec53667e4d62f5501e5 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/autofill/manual_filling_controller_impl.h"
#include <utility>
#include "base/callback.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/password_manager/password_accessory_controller.h"
#include "chrome/browser/password_manager/password_accessory_metrics_util.h"
#include "chrome/browser/password_manager/password_generation_controller.h"
#include "chrome/browser/profiles/profile.h"
#include "components/autofill/core/common/autofill_features.h"
#include "content/public/browser/web_contents.h"
using autofill::AccessorySheetData;
ManualFillingControllerImpl::~ManualFillingControllerImpl() = default;
// static
base::WeakPtr<ManualFillingController> ManualFillingController::GetOrCreate(
content::WebContents* contents) {
ManualFillingControllerImpl::CreateForWebContents(contents);
return ManualFillingControllerImpl::FromWebContents(contents)->AsWeakPtr();
}
// static
void ManualFillingControllerImpl::CreateForWebContentsForTesting(
content::WebContents* web_contents,
base::WeakPtr<PasswordAccessoryController> pwd_controller,
PasswordGenerationController* pwd_generation_controller_for_testing,
std::unique_ptr<ManualFillingViewInterface> view) {
DCHECK(web_contents) << "Need valid WebContents to attach controller to!";
DCHECK(!FromWebContents(web_contents)) << "Controller already attached!";
DCHECK(pwd_controller);
DCHECK(pwd_generation_controller_for_testing);
DCHECK(view);
web_contents->SetUserData(
UserDataKey(),
base::WrapUnique(new ManualFillingControllerImpl(
web_contents, std::move(pwd_controller),
pwd_generation_controller_for_testing, std::move(view))));
}
void ManualFillingControllerImpl::OnAutomaticGenerationStatusChanged(
bool available) {
DCHECK(view_);
view_->OnAutomaticGenerationStatusChanged(available);
}
void ManualFillingControllerImpl::OnFilledIntoFocusedField(
autofill::FillingStatus status) {
if (status != autofill::FillingStatus::SUCCESS)
return; // TODO(crbug.com/853766): Record success rate.
view_->SwapSheetWithKeyboard();
}
void ManualFillingControllerImpl::RefreshSuggestionsForField(
bool is_fillable,
const AccessorySheetData& accessory_sheet_data) {
view_->OnItemsAvailable(accessory_sheet_data);
// TODO(crbug.com/905669): The decision for showing the sheet or not will need
// to take into account if Autofill suggestions are also available.
if (is_fillable) {
view_->SwapSheetWithKeyboard();
} else {
view_->CloseAccessorySheet();
}
}
void ManualFillingControllerImpl::ShowWhenKeyboardIsVisible(
FillingSource source) {
if (source == FillingSource::AUTOFILL &&
!base::FeatureList::IsEnabled(
autofill::features::kAutofillKeyboardAccessory)) {
// Ignore autofill signals if the feature is disabled.
return;
}
visible_sources_.insert(source);
view_->ShowWhenKeyboardIsVisible();
}
void ManualFillingControllerImpl::Hide(FillingSource source) {
if (source == FillingSource::AUTOFILL &&
!base::FeatureList::IsEnabled(
autofill::features::kAutofillKeyboardAccessory)) {
// Ignore autofill signals if the feature is disabled.
return;
}
visible_sources_.erase(source);
if (visible_sources_.empty())
view_->Hide();
}
void ManualFillingControllerImpl::OnFillingTriggered(
bool is_password,
const base::string16& text_to_fill) {
DCHECK(pwd_controller_);
pwd_controller_->OnFillingTriggered(is_password, text_to_fill);
}
void ManualFillingControllerImpl::OnOptionSelected(
const base::string16& selected_option) const {
DCHECK(pwd_controller_);
pwd_controller_->OnOptionSelected(selected_option);
}
void ManualFillingControllerImpl::OnGenerationRequested() {
PasswordGenerationController* pwd_generation_controller =
pwd_generation_controller_for_testing_
? pwd_generation_controller_for_testing_
: PasswordGenerationController::GetIfExisting(web_contents_);
DCHECK(pwd_generation_controller);
pwd_generation_controller->OnGenerationRequested();
}
void ManualFillingControllerImpl::GetFavicon(
int desired_size_in_pixel,
base::OnceCallback<void(const gfx::Image&)> icon_callback) {
DCHECK(pwd_controller_);
pwd_controller_->GetFavicon(desired_size_in_pixel, std::move(icon_callback));
}
gfx::NativeView ManualFillingControllerImpl::container_view() const {
return web_contents_->GetNativeView();
}
// Returns a weak pointer for this object.
base::WeakPtr<ManualFillingController>
ManualFillingControllerImpl::AsWeakPtr() {
return weak_factory_.GetWeakPtr();
}
ManualFillingControllerImpl::ManualFillingControllerImpl(
content::WebContents* web_contents)
: web_contents_(web_contents),
view_(ManualFillingViewInterface::Create(this)),
weak_factory_(this) {
if (PasswordAccessoryController::AllowedForWebContents(web_contents)) {
pwd_controller_ =
PasswordAccessoryController::GetOrCreate(web_contents)->AsWeakPtr();
DCHECK(pwd_controller_);
}
}
ManualFillingControllerImpl::ManualFillingControllerImpl(
content::WebContents* web_contents,
base::WeakPtr<PasswordAccessoryController> pwd_controller,
PasswordGenerationController* pwd_generation_controller_for_testing,
std::unique_ptr<ManualFillingViewInterface> view)
: web_contents_(web_contents),
pwd_controller_(std::move(pwd_controller)),
pwd_generation_controller_for_testing_(
pwd_generation_controller_for_testing),
view_(std::move(view)),
weak_factory_(this) {}
WEB_CONTENTS_USER_DATA_KEY_IMPL(ManualFillingControllerImpl)