1 // Copyright 2020 The Chromium Embedded Framework Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CEF_LIBCEF_BROWSER_BROWSER_CONTENTS_DELEGATE_H_ 6 #define CEF_LIBCEF_BROWSER_BROWSER_CONTENTS_DELEGATE_H_ 7 #pragma once 8 9 #include <memory> 10 11 #include "libcef/browser/frame_host_impl.h" 12 13 #include "base/observer_list.h" 14 #include "content/public/browser/notification_observer.h" 15 #include "content/public/browser/notification_registrar.h" 16 #include "content/public/browser/web_contents_delegate.h" 17 #include "content/public/browser/web_contents_observer.h" 18 19 class CefBrowser; 20 class CefBrowserInfo; 21 class CefBrowserPlatformDelegate; 22 class CefClient; 23 24 // Flags that represent which states have changed. 25 enum class CefBrowserContentsState : uint8_t { 26 kNone = 0, 27 kNavigation = (1 << 0), 28 kDocument = (1 << 1), 29 kFullscreen = (1 << 2), 30 kFocusedFrame = (1 << 3), 31 }; 32 33 constexpr inline CefBrowserContentsState operator&( 34 CefBrowserContentsState lhs, 35 CefBrowserContentsState rhs) { 36 return static_cast<CefBrowserContentsState>(static_cast<int>(lhs) & 37 static_cast<int>(rhs)); 38 } 39 40 constexpr inline CefBrowserContentsState operator|( 41 CefBrowserContentsState lhs, 42 CefBrowserContentsState rhs) { 43 return static_cast<CefBrowserContentsState>(static_cast<int>(lhs) | 44 static_cast<int>(rhs)); 45 } 46 47 // Tracks state and executes client callbacks based on WebContents callbacks. 48 // Includes functionality that is shared by the alloy and chrome runtimes. 49 // Only accessed on the UI thread. 50 class CefBrowserContentsDelegate : public content::WebContentsDelegate, 51 public content::WebContentsObserver, 52 public content::NotificationObserver { 53 public: 54 using State = CefBrowserContentsState; 55 56 // Interface to implement for observers that wish to be informed of changes 57 // to the delegate. All methods will be called on the UI thread. 58 class Observer : public base::CheckedObserver { 59 public: 60 // Called after state has changed and before the associated CefClient 61 // callback is executed. 62 virtual void OnStateChanged(State state_changed) = 0; 63 64 // Called when the associated WebContents is destroyed. 65 virtual void OnWebContentsDestroyed(content::WebContents* web_contents) = 0; 66 67 protected: ~Observer()68 ~Observer() override {} 69 }; 70 71 explicit CefBrowserContentsDelegate( 72 scoped_refptr<CefBrowserInfo> browser_info); 73 74 void ObserveWebContents(content::WebContents* new_contents); 75 76 // Manage observer objects. The observer must either outlive this object or 77 // be removed before destruction. 78 void AddObserver(Observer* observer); 79 void RemoveObserver(Observer* observer); 80 81 // WebContentsDelegate methods: 82 content::WebContents* OpenURLFromTab( 83 content::WebContents* source, 84 const content::OpenURLParams& params) override; 85 void LoadingStateChanged(content::WebContents* source, 86 bool to_different_document) override; 87 void UpdateTargetURL(content::WebContents* source, const GURL& url) override; 88 bool DidAddMessageToConsole(content::WebContents* source, 89 blink::mojom::ConsoleMessageLevel log_level, 90 const std::u16string& message, 91 int32_t line_no, 92 const std::u16string& source_id) override; 93 void DidNavigateMainFramePostCommit( 94 content::WebContents* web_contents) override; 95 void EnterFullscreenModeForTab( 96 content::RenderFrameHost* requesting_frame, 97 const blink::mojom::FullscreenOptions& options) override; 98 void ExitFullscreenModeForTab(content::WebContents* web_contents) override; 99 content::KeyboardEventProcessingResult PreHandleKeyboardEvent( 100 content::WebContents* source, 101 const content::NativeWebKeyboardEvent& event) override; 102 bool HandleKeyboardEvent( 103 content::WebContents* source, 104 const content::NativeWebKeyboardEvent& event) override; 105 106 // WebContentsObserver methods: 107 void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; 108 void RenderFrameHostChanged(content::RenderFrameHost* old_host, 109 content::RenderFrameHost* new_host) override; 110 void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; 111 void RenderViewDeleted(content::RenderViewHost* render_view_host) override; 112 void RenderViewReady() override; 113 void RenderProcessGone(base::TerminationStatus status) override; 114 void OnFrameFocused(content::RenderFrameHost* render_frame_host) override; 115 void DocumentAvailableInMainFrame( 116 content::RenderFrameHost* render_frame_host) override; 117 void LoadProgressChanged(double progress) override; 118 void DidStopLoading() override; 119 void DidFinishNavigation( 120 content::NavigationHandle* navigation_handle) override; 121 void DidFailLoad(content::RenderFrameHost* render_frame_host, 122 const GURL& validated_url, 123 int error_code) override; 124 bool OnMessageReceived(const IPC::Message& message, 125 content::RenderFrameHost* render_frame_host) override; 126 void TitleWasSet(content::NavigationEntry* entry) override; 127 void PluginCrashed(const base::FilePath& plugin_path, 128 base::ProcessId plugin_pid) override; 129 void DidUpdateFaviconURL( 130 content::RenderFrameHost* render_frame_host, 131 const std::vector<blink::mojom::FaviconURLPtr>& candidates) override; 132 void OnWebContentsFocused( 133 content::RenderWidgetHost* render_widget_host) override; 134 void WebContentsDestroyed() override; 135 136 // NotificationObserver methods. 137 void Observe(int type, 138 const content::NotificationSource& source, 139 const content::NotificationDetails& details) override; 140 141 // Accessors for state information. Changes will be signaled to 142 // Observer::OnStateChanged. is_loading()143 bool is_loading() const { return is_loading_; } can_go_back()144 bool can_go_back() const { return can_go_back_; } can_go_forward()145 bool can_go_forward() const { return can_go_forward_; } has_document()146 bool has_document() const { return has_document_; } is_fullscreen()147 bool is_fullscreen() const { return is_fullscreen_; } focused_frame()148 CefRefPtr<CefFrameHostImpl> focused_frame() const { return focused_frame_; } 149 150 // Helpers for executing client callbacks. 151 // TODO(cef): Make this private if/when possible. 152 void OnLoadEnd(CefRefPtr<CefFrame> frame, 153 const GURL& url, 154 int http_status_code); 155 bool OnSetFocus(cef_focus_source_t source); 156 157 private: 158 CefRefPtr<CefClient> client() const; 159 CefRefPtr<CefBrowser> browser() const; 160 CefBrowserPlatformDelegate* platform_delegate() const; 161 162 // Helpers for executing client callbacks. 163 void OnAddressChange(const GURL& url); 164 void OnLoadStart(CefRefPtr<CefFrame> frame, 165 ui::PageTransition transition_type); 166 void OnLoadError(CefRefPtr<CefFrame> frame, const GURL& url, int error_code); 167 void OnTitleChange(const std::u16string& title); 168 void OnFullscreenModeChange(bool fullscreen); 169 170 void OnStateChanged(State state_changed); 171 172 scoped_refptr<CefBrowserInfo> browser_info_; 173 174 bool is_loading_ = false; 175 bool can_go_back_ = false; 176 bool can_go_forward_ = false; 177 bool has_document_ = false; 178 bool is_fullscreen_ = false; 179 180 // The currently focused frame, or nullptr if the main frame is focused. 181 CefRefPtr<CefFrameHostImpl> focused_frame_; 182 183 // True if currently in the OnSetFocus callback. 184 bool is_in_onsetfocus_ = false; 185 186 // Observers that want to be notified of changes to this object. 187 base::ObserverList<Observer> observers_; 188 189 // Used for managing notification subscriptions. 190 std::unique_ptr<content::NotificationRegistrar> registrar_; 191 192 // True if the focus is currently on an editable field on the page. 193 bool focus_on_editable_field_ = false; 194 195 DISALLOW_COPY_AND_ASSIGN(CefBrowserContentsDelegate); 196 }; 197 198 #endif // CEF_LIBCEF_BROWSER_BROWSER_CONTENTS_DELEGATE_H_ 199