| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef FUCHSIA_WEB_WEBENGINE_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_ |
| #define FUCHSIA_WEB_WEBENGINE_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_ |
| |
| #include <fuchsia/web/cpp/fidl.h> |
| #include <lib/fidl/cpp/binding_set.h> |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "components/favicon/core/favicon_driver_observer.h" |
| #include "content/public/browser/web_contents_observer.h" |
| #include "fuchsia_web/webengine/web_engine_export.h" |
| #include "net/base/net_errors.h" |
| |
| namespace content { |
| class NavigationEntry; |
| class NavigationHandle; |
| class WebContents; |
| } // namespace content |
| |
| // Implementation of fuchsia.web.NavigationController for content::WebContents. |
| class NavigationControllerImpl final |
| : public fuchsia::web::NavigationController, |
| public content::WebContentsObserver, |
| public favicon::FaviconDriverObserver { |
| public: |
| static const void* const kAbortedRequestKey; |
| |
| NavigationControllerImpl(content::WebContents* web_contents, |
| void* parent_for_trace_flow); |
| |
| NavigationControllerImpl(const NavigationControllerImpl&) = delete; |
| NavigationControllerImpl& operator=(const NavigationControllerImpl&) = delete; |
| |
| ~NavigationControllerImpl() override; |
| |
| void AddBinding( |
| fidl::InterfaceRequest<fuchsia::web::NavigationController> controller); |
| |
| void SetEventListener( |
| fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener, |
| fuchsia::web::NavigationEventListenerFlags flags); |
| |
| private: |
| // Returns a NavigationState reflecting the current state of |web_contents_|'s |
| // visible navigation entry, taking into account |is_main_document_loaded_| |
| // and |uncommitted_load_error_| states. |
| fuchsia::web::NavigationState GetVisibleNavigationState() const; |
| |
| // Processes the most recent changes to the browser's navigation state and |
| // triggers the publishing of change events. |
| void OnNavigationEntryChanged(); |
| |
| // Sends |pending_navigation_event_| to the observer if there are any changes |
| // to be reported. |
| void MaybeSendNavigationEvent(); |
| |
| // fuchsia::web::NavigationController implementation. |
| void LoadUrl(std::string url, |
| fuchsia::web::LoadUrlParams params, |
| LoadUrlCallback callback) override; |
| void GoBack() override; |
| void GoForward() override; |
| void Stop() override; |
| void Reload(fuchsia::web::ReloadType type) override; |
| |
| // content::WebContentsObserver implementation. |
| void TitleWasSet(content::NavigationEntry*) override; |
| void PrimaryMainDocumentElementAvailable() override; |
| void DidFinishLoad(content::RenderFrameHost* render_frame_host, |
| const GURL& validated_url) override; |
| void PrimaryMainFrameRenderProcessGone( |
| base::TerminationStatus status) override; |
| void DidStartNavigation( |
| content::NavigationHandle* navigation_handle) override; |
| void DidFinishNavigation( |
| content::NavigationHandle* navigation_handle) override; |
| |
| // favicon::FaviconDriverObserver implementation. |
| void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, |
| NotificationIconType notification_icon_type, |
| const GURL& icon_url, |
| bool icon_url_changed, |
| const gfx::Image& image) override; |
| |
| const raw_ptr<void> parent_for_trace_flow_; |
| const raw_ptr<content::WebContents> web_contents_; |
| |
| // NavigationController client bindings. |
| fidl::BindingSet<fuchsia::web::NavigationController> controller_bindings_; |
| |
| // Fields used to dispatch events to the NavigationEventListener. |
| fuchsia::web::NavigationEventListenerPtr navigation_listener_; |
| fuchsia::web::NavigationState previous_navigation_state_; |
| fuchsia::web::NavigationState pending_navigation_event_; |
| bool waiting_for_navigation_event_ack_ = false; |
| |
| // True once the main document finishes loading and there are no outstanding |
| // navigations. |
| bool is_main_document_loaded_ = false; |
| raw_ptr<content::NavigationHandle> active_navigation_ = nullptr; |
| |
| // True if navigation failed due to an error during page load. |
| bool uncommitted_load_error_ = false; |
| |
| // Network error code from the last navigation attempt. |
| net::Error last_error_code_ = net::OK; |
| |
| // Set to true when NavigationEventListenerFlags::FAVICON flag |
| // was passed to the last SetEventListener() call, i.e. favicon reporting is |
| // enabled. |
| bool send_favicon_ = false; |
| |
| base::WeakPtrFactory<NavigationControllerImpl> weak_factory_; |
| }; |
| |
| // Exposed to allow unit-testing of NavigationState differencing. |
| WEB_ENGINE_EXPORT void DiffNavigationEntriesForTest( |
| const fuchsia::web::NavigationState& old_entry, |
| const fuchsia::web::NavigationState& new_entry, |
| fuchsia::web::NavigationState* difference); |
| |
| #endif // FUCHSIA_WEB_WEBENGINE_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_ |