blob: 6825bcf6749541bf27b5a608e5fdd2bf050b9371 [file] [log] [blame]
// Copyright 2014 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 "components/autofill/content/browser/content_autofill_driver_factory.h"
#include <memory>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "components/autofill/content/browser/content_autofill_driver.h"
#include "components/autofill/core/browser/autofill_manager.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
namespace autofill {
namespace {
std::unique_ptr<AutofillDriver> CreateDriver(
content::RenderFrameHost* render_frame_host,
AutofillClient* client,
const std::string& app_locale,
AutofillManager::AutofillDownloadManagerState enable_download_manager,
AutofillProvider* provider) {
return std::make_unique<ContentAutofillDriver>(
render_frame_host, client, app_locale, enable_download_manager, provider);
}
} // namespace
const char ContentAutofillDriverFactory::
kContentAutofillDriverFactoryWebContentsUserDataKey[] =
"web_contents_autofill_driver_factory";
ContentAutofillDriverFactory::~ContentAutofillDriverFactory() {}
// static
void ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
content::WebContents* contents,
AutofillClient* client,
const std::string& app_locale,
AutofillManager::AutofillDownloadManagerState enable_download_manager) {
CreateForWebContentsAndDelegate(contents, client, app_locale,
enable_download_manager, nullptr);
}
void ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
content::WebContents* contents,
AutofillClient* client,
const std::string& app_locale,
AutofillManager::AutofillDownloadManagerState enable_download_manager,
AutofillProvider* provider) {
if (FromWebContents(contents))
return;
auto new_factory = base::WrapUnique(new ContentAutofillDriverFactory(
contents, client, app_locale, enable_download_manager, provider));
const std::vector<content::RenderFrameHost*> frames =
contents->GetAllFrames();
for (content::RenderFrameHost* frame : frames) {
if (frame->IsRenderFrameLive())
new_factory->RenderFrameCreated(frame);
}
contents->SetUserData(kContentAutofillDriverFactoryWebContentsUserDataKey,
std::move(new_factory));
}
// static
ContentAutofillDriverFactory* ContentAutofillDriverFactory::FromWebContents(
content::WebContents* contents) {
return static_cast<ContentAutofillDriverFactory*>(contents->GetUserData(
kContentAutofillDriverFactoryWebContentsUserDataKey));
}
// static
void ContentAutofillDriverFactory::BindAutofillDriver(
mojom::AutofillDriverAssociatedRequest request,
content::RenderFrameHost* render_frame_host) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
// We try to bind to the driver of this render frame host,
// but if driver is not ready for this render frame host for now,
// the request will be just dropped, this would cause closing the message pipe
// which would raise connection error to peer side.
// Peer side could reconnect later when needed.
if (!web_contents)
return;
ContentAutofillDriverFactory* factory =
ContentAutofillDriverFactory::FromWebContents(web_contents);
if (!factory)
return;
ContentAutofillDriver* driver = factory->DriverForFrame(render_frame_host);
if (driver)
driver->BindRequest(std::move(request));
}
ContentAutofillDriverFactory::ContentAutofillDriverFactory(
content::WebContents* web_contents,
AutofillClient* client,
const std::string& app_locale,
AutofillManager::AutofillDownloadManagerState enable_download_manager,
AutofillProvider* provider)
: AutofillDriverFactory(client),
content::WebContentsObserver(web_contents),
app_locale_(app_locale),
enable_download_manager_(enable_download_manager),
provider_(provider) {}
ContentAutofillDriver* ContentAutofillDriverFactory::DriverForFrame(
content::RenderFrameHost* render_frame_host) {
// This cast is safe because AutofillDriverFactory::AddForKey is protected
// and always called with ContentAutofillDriver instances within
// ContentAutofillDriverFactory.
return static_cast<ContentAutofillDriver*>(DriverForKey(render_frame_host));
}
void ContentAutofillDriverFactory::RenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
AddForKey(render_frame_host,
base::Bind(CreateDriver, render_frame_host, client(), app_locale_,
enable_download_manager_, provider_));
}
void ContentAutofillDriverFactory::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
DeleteForKey(render_frame_host);
}
void ContentAutofillDriverFactory::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
// For the purposes of this code, a navigation is not important if it has not
// committed yet or if it's in a subframe.
if (!navigation_handle->HasCommitted() ||
!navigation_handle->IsInMainFrame()) {
return;
}
// A main frame navigation has occured. We suppress the autofill popup and
// tell the autofill driver.
NavigationFinished();
DriverForFrame(navigation_handle->GetRenderFrameHost())
->DidNavigateMainFrame(navigation_handle);
}
void ContentAutofillDriverFactory::OnVisibilityChanged(
content::Visibility visibility) {
if (visibility == content::Visibility::HIDDEN)
TabHidden();
}
} // namespace autofill