|  | // 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. | 
|  |  | 
|  | #ifndef COMPONENTS_AUTOFILL_CONTENT_BROWSER_CONTENT_AUTOFILL_DRIVER_FACTORY_H_ | 
|  | #define COMPONENTS_AUTOFILL_CONTENT_BROWSER_CONTENT_AUTOFILL_DRIVER_FACTORY_H_ | 
|  |  | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/containers/flat_map.h" | 
|  | #include "base/memory/raw_ref.h" | 
|  | #include "base/observer_list.h" | 
|  | #include "base/types/pass_key.h" | 
|  | #include "components/autofill/content/common/mojom/autofill_driver.mojom.h" | 
|  | #include "components/autofill/core/browser/foundations/autofill_driver_factory.h" | 
|  | #include "components/autofill/core/browser/foundations/autofill_driver_router.h" | 
|  | #include "content/public/browser/web_contents_observer.h" | 
|  | #include "mojo/public/cpp/bindings/pending_associated_receiver.h" | 
|  |  | 
|  | namespace content { | 
|  | class RenderFrameHost; | 
|  | } | 
|  |  | 
|  | namespace autofill { | 
|  |  | 
|  | class ContentAutofillClient; | 
|  | class ContentAutofillDriver; | 
|  |  | 
|  | // Creates one ContentAutofillDriver per content::RenderFrameHost and manages | 
|  | // its lifecycle corresponding to the content::RenderFrameHost's lifecycle. | 
|  | // | 
|  | // Owned by ContentAutofillClient, therefore there is one | 
|  | // ContentAutofillDriverFactory per content::WebContents. | 
|  | class ContentAutofillDriverFactory : public AutofillDriverFactory, | 
|  | public content::WebContentsObserver { | 
|  | public: | 
|  | // A variant of AutofillDriverFactory::Observer with AutofillDriver[Factory] | 
|  | // narrowed to ContentAutofillDriver[Factory]. | 
|  | // See AutofillDriverFactory::Observer for further documentation. | 
|  | class Observer : public AutofillDriverFactory::Observer { | 
|  | public: | 
|  | virtual void OnContentAutofillDriverFactoryDestroyed( | 
|  | ContentAutofillDriverFactory& factory) {} | 
|  | virtual void OnContentAutofillDriverCreated( | 
|  | ContentAutofillDriverFactory& factory, | 
|  | ContentAutofillDriver& driver) {} | 
|  | virtual void OnContentAutofillDriverStateChanged( | 
|  | ContentAutofillDriverFactory& factory, | 
|  | ContentAutofillDriver& driver, | 
|  | AutofillDriver::LifecycleState old_state, | 
|  | AutofillDriver::LifecycleState new_state) {} | 
|  |  | 
|  | // AutofillDriverFactory::Observer: | 
|  | void OnAutofillDriverFactoryDestroyed(AutofillDriverFactory& factory) final; | 
|  | void OnAutofillDriverCreated(AutofillDriverFactory& factory, | 
|  | AutofillDriver& driver) final; | 
|  | void OnAutofillDriverStateChanged(AutofillDriverFactory& factory, | 
|  | AutofillDriver& driver, | 
|  | LifecycleState old_state, | 
|  | LifecycleState new_state) final; | 
|  | }; | 
|  |  | 
|  | static ContentAutofillDriverFactory* FromWebContents( | 
|  | content::WebContents* contents); | 
|  |  | 
|  | static void BindAutofillDriver( | 
|  | content::RenderFrameHost* render_frame_host, | 
|  | mojo::PendingAssociatedReceiver<mojom::AutofillDriver> pending_receiver); | 
|  |  | 
|  | ContentAutofillDriverFactory(content::WebContents* web_contents, | 
|  | ContentAutofillClient* client); | 
|  | ContentAutofillDriverFactory(ContentAutofillDriverFactory&) = delete; | 
|  | ContentAutofillDriverFactory& operator=(ContentAutofillDriverFactory&) = | 
|  | delete; | 
|  | ~ContentAutofillDriverFactory() override; | 
|  |  | 
|  | // content::WebContentsObserver: | 
|  | void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; | 
|  | void RenderFrameHostStateChanged( | 
|  | content::RenderFrameHost* render_frame_host, | 
|  | content::RenderFrameHost::LifecycleState old_state, | 
|  | content::RenderFrameHost::LifecycleState new_state) override; | 
|  | void DidFinishNavigation( | 
|  | content::NavigationHandle* navigation_handle) override; | 
|  |  | 
|  | ContentAutofillClient& client() { return *client_; } | 
|  |  | 
|  | AutofillDriverRouter& router() { return router_; } | 
|  |  | 
|  | std::vector<AutofillDriver*> GetExistingDrivers() override; | 
|  |  | 
|  | ContentAutofillDriver* DriverForFrame( | 
|  | content::RenderFrameHost* render_frame_host, | 
|  | base::PassKey<ContentAutofillDriver>) { | 
|  | return DriverForFrame(render_frame_host); | 
|  | } | 
|  |  | 
|  | private: | 
|  | friend class ContentAutofillDriverFactoryTestApi; | 
|  |  | 
|  | // Gets the `ContentAutofillDriver` associated with `render_frame_host`. | 
|  | // If `render_frame_host` is currently being deleted, this may be nullptr. | 
|  | // `render_frame_host` must be owned by `web_contents()`. | 
|  | ContentAutofillDriver* DriverForFrame( | 
|  | content::RenderFrameHost* render_frame_host); | 
|  |  | 
|  | // The owning AutofillClient. | 
|  | const raw_ref<ContentAutofillClient> client_; | 
|  |  | 
|  | // Routes events between different ContentAutofillDrivers. | 
|  | // Must be destroyed after |driver_map_|'s elements. | 
|  | AutofillDriverRouter router_; | 
|  |  | 
|  | // Owns the drivers. Drivers are created lazily in DriverForFrame() and | 
|  | // destroyed in RenderFrameDeleted(). They are added to the map on | 
|  | // construction and removed from the map on deletion. | 
|  | // | 
|  | // The map should be empty at destruction time because its elements are erased | 
|  | // in RenderFrameDeleted(). In case it is not empty, is must be destroyed | 
|  | // before `router_` because ~ContentAutofillDriver() may access `router_`. | 
|  | // | 
|  | // The map type must be so that `driver_map_.emplace()` does *not* invalidate | 
|  | // references. Otherwise, recursive DriverForFrame() calls are unsafe. | 
|  | std::map<content::RenderFrameHost*, std::unique_ptr<ContentAutofillDriver>> | 
|  | driver_map_; | 
|  |  | 
|  | // The maximum number of coexisting drivers over the lifetime of this factory. | 
|  | // TODO: crbug.com/342132628 - Remove the counter and the metric. | 
|  | size_t max_drivers_ = 0; | 
|  | }; | 
|  |  | 
|  | }  // namespace autofill | 
|  |  | 
|  | #endif  // COMPONENTS_AUTOFILL_CONTENT_BROWSER_CONTENT_AUTOFILL_DRIVER_FACTORY_H_ |