blob: 32465df8fa498a67799d01335e68350f1d6cad54 [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 <vector>
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "components/autofill/content/browser/content_autofill_driver.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_manager.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/common/autofill_switches.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 {
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) {
if (FromWebContents(contents))
return;
auto new_factory = base::WrapUnique(new ContentAutofillDriverFactory(
contents, client, app_locale, enable_download_manager));
const std::vector<content::RenderFrameHost*> frames =
contents->GetAllFrames();
for (content::RenderFrameHost* frame : frames) {
if (frame->IsRenderFrameLive())
new_factory->RenderFrameCreated(frame);
}
contents->SetUserData(kContentAutofillDriverFactoryWebContentsUserDataKey,
new_factory.release());
}
// static
ContentAutofillDriverFactory* ContentAutofillDriverFactory::FromWebContents(
content::WebContents* contents) {
return static_cast<ContentAutofillDriverFactory*>(contents->GetUserData(
kContentAutofillDriverFactoryWebContentsUserDataKey));
}
// static
void ContentAutofillDriverFactory::BindAutofillDriver(
content::RenderFrameHost* render_frame_host,
mojom::AutofillDriverRequest request) {
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)
: content::WebContentsObserver(web_contents),
client_(client),
app_locale_(app_locale),
enable_download_manager_(enable_download_manager) {}
ContentAutofillDriver* ContentAutofillDriverFactory::DriverForFrame(
content::RenderFrameHost* render_frame_host) {
auto mapping = frame_driver_map_.find(render_frame_host);
return mapping == frame_driver_map_.end() ? nullptr : mapping->second.get();
}
void ContentAutofillDriverFactory::RenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
auto insertion_result =
frame_driver_map_.insert(std::make_pair(render_frame_host, nullptr));
// This is called twice for the main frame.
if (insertion_result.second) { // This was the first time.
insertion_result.first->second = base::MakeUnique<ContentAutofillDriver>(
render_frame_host, client_, app_locale_, enable_download_manager_);
}
}
void ContentAutofillDriverFactory::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
frame_driver_map_.erase(render_frame_host);
}
void ContentAutofillDriverFactory::DidNavigateAnyFrame(
content::RenderFrameHost* render_frame_host,
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
frame_driver_map_[render_frame_host]->DidNavigateFrame(details, params);
}
void ContentAutofillDriverFactory::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
if (navigation_handle->HasCommitted())
client_->HideAutofillPopup();
}
void ContentAutofillDriverFactory::WasHidden() {
client_->HideAutofillPopup();
}
} // namespace autofill