1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. 2 // Portions copyright (c) 2011 The Chromium Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 6 #ifndef CEF_LIBCEF_BROWSER_ALLOY_ALLOY_BROWSER_HOST_IMPL_H_ 7 #define CEF_LIBCEF_BROWSER_ALLOY_ALLOY_BROWSER_HOST_IMPL_H_ 8 #pragma once 9 10 #include <map> 11 #include <string> 12 #include <vector> 13 14 #include "include/cef_browser.h" 15 #include "include/cef_client.h" 16 #include "include/cef_frame.h" 17 #include "libcef/browser/browser_host_base.h" 18 #include "libcef/browser/browser_info.h" 19 #include "libcef/browser/file_dialog_manager.h" 20 #include "libcef/browser/frame_host_impl.h" 21 #include "libcef/browser/javascript_dialog_manager.h" 22 #include "libcef/browser/menu_manager.h" 23 #include "libcef/browser/request_context_impl.h" 24 25 #include "base/synchronization/lock.h" 26 #include "content/public/browser/web_contents.h" 27 #include "content/public/browser/web_contents_delegate.h" 28 #include "content/public/browser/web_contents_observer.h" 29 #include "extensions/common/mojom/view_type.mojom-forward.h" 30 31 class CefAudioCapturer; 32 class CefBrowserInfo; 33 class SiteInstance; 34 35 // CefBrowser implementation for the alloy runtime. Method calls are delegated 36 // to the CefPlatformDelegate or the WebContents as appropriate. All methods are 37 // thread-safe unless otherwise indicated. 38 // 39 // WebContentsDelegate: Interface for handling WebContents delegations. There is 40 // a one-to-one relationship between AlloyBrowserHostImpl and WebContents 41 // instances. 42 // 43 // WebContentsObserver: Interface for observing WebContents notifications and 44 // IPC messages. There is a one-to-one relationship between WebContents and 45 // RenderViewHost instances. IPC messages received by the RenderViewHost will be 46 // forwarded to this WebContentsObserver implementation via WebContents. IPC 47 // messages sent using AlloyBrowserHostImpl::Send() will be forwarded to the 48 // RenderViewHost (after posting to the UI thread if necessary). Use 49 // WebContentsObserver::routing_id() when sending IPC messages. 50 class AlloyBrowserHostImpl : public CefBrowserHostBase, 51 public content::WebContentsDelegate, 52 public content::WebContentsObserver { 53 public: 54 // Used for handling the response to command messages. 55 class CommandResponseHandler : public virtual CefBaseRefCounted { 56 public: 57 virtual void OnResponse(const std::string& response) = 0; 58 }; 59 60 ~AlloyBrowserHostImpl() override; 61 62 // Create a new AlloyBrowserHostImpl instance with owned WebContents. 63 static CefRefPtr<AlloyBrowserHostImpl> Create( 64 CefBrowserCreateParams& create_params); 65 66 // Returns the browser associated with the specified RenderViewHost. 67 static CefRefPtr<AlloyBrowserHostImpl> GetBrowserForHost( 68 const content::RenderViewHost* host); 69 // Returns the browser associated with the specified RenderFrameHost. 70 static CefRefPtr<AlloyBrowserHostImpl> GetBrowserForHost( 71 const content::RenderFrameHost* host); 72 // Returns the browser associated with the specified WebContents. 73 static CefRefPtr<AlloyBrowserHostImpl> GetBrowserForContents( 74 const content::WebContents* contents); 75 // Returns the browser associated with the specified global ID. 76 static CefRefPtr<AlloyBrowserHostImpl> GetBrowserForGlobalId( 77 const content::GlobalRenderFrameHostId& global_id); 78 79 // CefBrowserHost methods. 80 void CloseBrowser(bool force_close) override; 81 bool TryCloseBrowser() override; 82 void SetFocus(bool focus) override; 83 CefWindowHandle GetWindowHandle() override; 84 CefWindowHandle GetOpenerWindowHandle() override; 85 double GetZoomLevel() override; 86 void SetZoomLevel(double zoomLevel) override; 87 void RunFileDialog(FileDialogMode mode, 88 const CefString& title, 89 const CefString& default_file_path, 90 const std::vector<CefString>& accept_filters, 91 int selected_accept_filter, 92 CefRefPtr<CefRunFileDialogCallback> callback) override; 93 void Print() override; 94 void PrintToPDF(const CefString& path, 95 const CefPdfPrintSettings& settings, 96 CefRefPtr<CefPdfPrintCallback> callback) override; 97 void Find(const CefString& searchText, 98 bool forward, 99 bool matchCase, 100 bool findNext) override; 101 void StopFinding(bool clearSelection) override; 102 void ShowDevTools(const CefWindowInfo& windowInfo, 103 CefRefPtr<CefClient> client, 104 const CefBrowserSettings& settings, 105 const CefPoint& inspect_element_at) override; 106 void CloseDevTools() override; 107 bool HasDevTools() override; 108 bool IsWindowRenderingDisabled() override; 109 void WasResized() override; 110 void WasHidden(bool hidden) override; 111 void NotifyScreenInfoChanged() override; 112 void Invalidate(PaintElementType type) override; 113 void SendExternalBeginFrame() override; 114 void SendTouchEvent(const CefTouchEvent& event) override; 115 void SendCaptureLostEvent() override; 116 void NotifyMoveOrResizeStarted() override; 117 int GetWindowlessFrameRate() override; 118 void SetWindowlessFrameRate(int frame_rate) override; 119 void ImeSetComposition(const CefString& text, 120 const std::vector<CefCompositionUnderline>& underlines, 121 const CefRange& replacement_range, 122 const CefRange& selection_range) override; 123 void ImeCommitText(const CefString& text, 124 const CefRange& replacement_range, 125 int relative_cursor_pos) override; 126 void ImeFinishComposingText(bool keep_selection) override; 127 void ImeCancelComposition() override; 128 void DragTargetDragEnter(CefRefPtr<CefDragData> drag_data, 129 const CefMouseEvent& event, 130 DragOperationsMask allowed_ops) override; 131 void DragTargetDragOver(const CefMouseEvent& event, 132 DragOperationsMask allowed_ops) override; 133 void DragTargetDragLeave() override; 134 void DragTargetDrop(const CefMouseEvent& event) override; 135 void DragSourceSystemDragEnded() override; 136 void DragSourceEndedAt(int x, int y, DragOperationsMask op) override; 137 void SetAudioMuted(bool mute) override; 138 bool IsAudioMuted() override; 139 void SetAccessibilityState(cef_state_t accessibility_state) override; 140 void SetAutoResizeEnabled(bool enabled, 141 const CefSize& min_size, 142 const CefSize& max_size) override; 143 CefRefPtr<CefExtension> GetExtension() override; 144 bool IsBackgroundHost() override; 145 146 // Returns true if windowless rendering is enabled. 147 bool IsWindowless() const override; 148 149 // Returns true if this browser supports picture-in-picture. 150 bool IsPictureInPictureSupported() const; 151 152 // Called when the OS window hosting the browser is destroyed. 153 void WindowDestroyed() override; 154 155 // Destroy the browser members. This method should only be called after the 156 // native browser window is not longer processing messages. 157 void DestroyBrowser() override; 158 159 // Cancel display of the context menu, if any. 160 void CancelContextMenu(); 161 162 bool MaybeAllowNavigation(content::RenderFrameHost* opener, 163 bool is_guest_view, 164 const content::OpenURLParams& params) override; 165 166 // Convert from view coordinates to screen coordinates. Potential display 167 // scaling will be applied to the result. 168 gfx::Point GetScreenPoint(const gfx::Point& view) const; 169 170 void StartDragging(const content::DropData& drop_data, 171 blink::DragOperationsMask allowed_ops, 172 const gfx::ImageSkia& image, 173 const gfx::Vector2d& image_offset, 174 const blink::mojom::DragEventSourceInfo& event_info, 175 content::RenderWidgetHostImpl* source_rwh); 176 void UpdateDragCursor(ui::mojom::DragOperation operation); 177 178 // Accessors that must be called on the UI thread. 179 extensions::ExtensionHost* GetExtensionHost() const; 180 181 void OnSetFocus(cef_focus_source_t source) override; 182 183 // Run the file chooser dialog specified by |params|. Only a single dialog may 184 // be pending at any given time. |callback| will be executed asynchronously 185 // after the dialog is dismissed or if another dialog is already pending. 186 void RunFileChooser(const CefFileDialogRunner::FileChooserParams& params, 187 CefFileDialogRunner::RunFileChooserCallback callback); 188 189 bool HandleContextMenu(content::WebContents* web_contents, 190 const content::ContextMenuParams& params); 191 192 enum DestructionState { 193 DESTRUCTION_STATE_NONE = 0, 194 DESTRUCTION_STATE_PENDING, 195 DESTRUCTION_STATE_ACCEPTED, 196 DESTRUCTION_STATE_COMPLETED 197 }; destruction_state()198 DestructionState destruction_state() const { return destruction_state_; } 199 200 // content::WebContentsDelegate methods. 201 content::WebContents* OpenURLFromTab( 202 content::WebContents* source, 203 const content::OpenURLParams& params) override; 204 bool ShouldAllowRendererInitiatedCrossProcessNavigation( 205 bool is_main_frame_navigation) override; 206 void AddNewContents(content::WebContents* source, 207 std::unique_ptr<content::WebContents> new_contents, 208 const GURL& target_url, 209 WindowOpenDisposition disposition, 210 const gfx::Rect& initial_rect, 211 bool user_gesture, 212 bool* was_blocked) override; 213 void LoadingStateChanged(content::WebContents* source, 214 bool should_show_loading_ui) override; 215 void CloseContents(content::WebContents* source) override; 216 void UpdateTargetURL(content::WebContents* source, const GURL& url) override; 217 bool DidAddMessageToConsole(content::WebContents* source, 218 blink::mojom::ConsoleMessageLevel log_level, 219 const std::u16string& message, 220 int32_t line_no, 221 const std::u16string& source_id) override; 222 void BeforeUnloadFired(content::WebContents* source, 223 bool proceed, 224 bool* proceed_to_fire_unload) override; 225 bool TakeFocus(content::WebContents* source, bool reverse) override; 226 bool HandleContextMenu(content::RenderFrameHost& render_frame_host, 227 const content::ContextMenuParams& params) override; 228 content::KeyboardEventProcessingResult PreHandleKeyboardEvent( 229 content::WebContents* source, 230 const content::NativeWebKeyboardEvent& event) override; 231 bool HandleKeyboardEvent( 232 content::WebContents* source, 233 const content::NativeWebKeyboardEvent& event) override; 234 bool PreHandleGestureEvent(content::WebContents* source, 235 const blink::WebGestureEvent& event) override; 236 bool CanDragEnter(content::WebContents* source, 237 const content::DropData& data, 238 blink::DragOperationsMask operations_allowed) override; 239 void GetCustomWebContentsView( 240 content::WebContents* web_contents, 241 const GURL& target_url, 242 int opener_render_process_id, 243 int opener_render_frame_id, 244 content::WebContentsView** view, 245 content::RenderViewHostDelegateView** delegate_view) override; 246 void WebContentsCreated(content::WebContents* source_contents, 247 int opener_render_process_id, 248 int opener_render_frame_id, 249 const std::string& frame_name, 250 const GURL& target_url, 251 content::WebContents* new_contents) override; 252 void DidNavigatePrimaryMainFramePostCommit( 253 content::WebContents* web_contents) override; 254 content::JavaScriptDialogManager* GetJavaScriptDialogManager( 255 content::WebContents* source) override; 256 void RunFileChooser(content::RenderFrameHost* render_frame_host, 257 scoped_refptr<content::FileSelectListener> listener, 258 const blink::mojom::FileChooserParams& params) override; 259 void EnterFullscreenModeForTab( 260 content::RenderFrameHost* requesting_frame, 261 const blink::mojom::FullscreenOptions& options) override; 262 void ExitFullscreenModeForTab(content::WebContents* web_contents) override; 263 bool IsFullscreenForTabOrPending( 264 const content::WebContents* web_contents) override; 265 blink::mojom::DisplayMode GetDisplayMode( 266 const content::WebContents* web_contents) override; 267 void FindReply(content::WebContents* web_contents, 268 int request_id, 269 int number_of_matches, 270 const gfx::Rect& selection_rect, 271 int active_match_ordinal, 272 bool final_update) override; 273 void UpdatePreferredSize(content::WebContents* source, 274 const gfx::Size& pref_size) override; 275 void ResizeDueToAutoResize(content::WebContents* source, 276 const gfx::Size& new_size) override; 277 void RequestMediaAccessPermission( 278 content::WebContents* web_contents, 279 const content::MediaStreamRequest& request, 280 content::MediaResponseCallback callback) override; 281 bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host, 282 const GURL& security_origin, 283 blink::mojom::MediaStreamType type) override; 284 bool IsNeverComposited(content::WebContents* web_contents) override; 285 content::PictureInPictureResult EnterPictureInPicture( 286 content::WebContents* web_contents, 287 const viz::SurfaceId& surface_id, 288 const gfx::Size& natural_size) override; 289 void ExitPictureInPicture() override; 290 bool IsBackForwardCacheSupported() override; 291 bool IsPrerender2Supported() override; 292 293 // content::WebContentsObserver methods. 294 using content::WebContentsObserver::BeforeUnloadFired; 295 void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; 296 void RenderViewReady() override; 297 void DidFinishNavigation( 298 content::NavigationHandle* navigation_handle) override; 299 void OnAudioStateChanged(bool audible) override; 300 void AccessibilityEventReceived( 301 const content::AXEventNotificationDetails& content_event_bundle) override; 302 void AccessibilityLocationChangesReceived( 303 const std::vector<content::AXLocationChangeNotificationDetails>& locData) 304 override; 305 void WebContentsDestroyed() override; 306 307 private: 308 friend class CefBrowserPlatformDelegateAlloy; 309 310 static CefRefPtr<AlloyBrowserHostImpl> CreateInternal( 311 const CefBrowserSettings& settings, 312 CefRefPtr<CefClient> client, 313 content::WebContents* web_contents, 314 bool own_web_contents, 315 scoped_refptr<CefBrowserInfo> browser_info, 316 CefRefPtr<AlloyBrowserHostImpl> opener, 317 bool is_devtools_popup, 318 CefRefPtr<CefRequestContextImpl> request_context, 319 std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate, 320 CefRefPtr<CefExtension> extension); 321 322 AlloyBrowserHostImpl( 323 const CefBrowserSettings& settings, 324 CefRefPtr<CefClient> client, 325 content::WebContents* web_contents, 326 scoped_refptr<CefBrowserInfo> browser_info, 327 CefRefPtr<AlloyBrowserHostImpl> opener, 328 CefRefPtr<CefRequestContextImpl> request_context, 329 std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate, 330 CefRefPtr<CefExtension> extension); 331 332 // Give the platform delegate an opportunity to create the host window. 333 bool CreateHostWindow(); 334 335 // Create the CefFileDialogManager if it doesn't already exist. 336 void EnsureFileDialogManager(); 337 338 void StartAudioCapturer(); 339 void OnRecentlyAudibleTimerFired(); 340 341 void SetFocusInternal(bool focus); 342 343 CefWindowHandle opener_; 344 const bool is_windowless_; 345 CefWindowHandle host_window_handle_ = kNullWindowHandle; 346 CefRefPtr<CefExtension> extension_; 347 bool is_background_host_ = false; 348 349 // Represents the current browser destruction state. Only accessed on the UI 350 // thread. 351 DestructionState destruction_state_ = DESTRUCTION_STATE_NONE; 352 353 // True if the OS window hosting the browser has been destroyed. Only accessed 354 // on the UI thread. 355 bool window_destroyed_ = false; 356 357 // Used for creating and managing file dialogs. 358 std::unique_ptr<CefFileDialogManager> file_dialog_manager_; 359 360 // Used for creating and managing JavaScript dialogs. 361 std::unique_ptr<CefJavaScriptDialogManager> javascript_dialog_manager_; 362 363 // Used for creating and managing context menus. 364 std::unique_ptr<CefMenuManager> menu_manager_; 365 366 // Used for capturing audio for CefAudioHandler. 367 std::unique_ptr<CefAudioCapturer> audio_capturer_; 368 369 // Timer for determining when "recently audible" transitions to false. This 370 // starts running when a tab stops being audible, and is canceled if it starts 371 // being audible again before it fires. 372 std::unique_ptr<base::OneShotTimer> recently_audible_timer_; 373 }; 374 375 #endif // CEF_LIBCEF_BROWSER_ALLOY_ALLOY_BROWSER_HOST_IMPL_H_ 376