// Copyright (c) 2012 The Chromium Embedded Framework Authors. // Portions copyright (c) 2011 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. #ifndef CEF_LIBCEF_BROWSER_ALLOY_ALLOY_BROWSER_HOST_IMPL_H_ #define CEF_LIBCEF_BROWSER_ALLOY_ALLOY_BROWSER_HOST_IMPL_H_ #pragma once #include #include #include #include "base/synchronization/lock.h" #include "cef/include/cef_browser.h" #include "cef/include/cef_client.h" #include "cef/include/cef_frame.h" #include "cef/libcef/browser/browser_host_base.h" #include "cef/libcef/browser/browser_info.h" #include "cef/libcef/browser/frame_host_impl.h" #include "cef/libcef/browser/menu_manager.h" #include "cef/libcef/browser/request_context_impl.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP) #include "extensions/common/mojom/view_type.mojom-forward.h" #endif class CefAudioCapturer; class CefBrowserInfo; class SiteInstance; // CefBrowser implementation for the alloy runtime. Method calls are delegated // to the CefPlatformDelegate or the WebContents as appropriate. All methods are // thread-safe unless otherwise indicated. // // WebContentsDelegate: Interface for handling WebContents delegations. There is // a one-to-one relationship between AlloyBrowserHostImpl and WebContents // instances. // // WebContentsObserver: Interface for observing WebContents notifications and // IPC messages. There is a one-to-one relationship between WebContents and // RenderViewHost instances. IPC messages received by the RenderViewHost will be // forwarded to this WebContentsObserver implementation via WebContents. IPC // messages sent using AlloyBrowserHostImpl::Send() will be forwarded to the // RenderViewHost (after posting to the UI thread if necessary). Use // WebContentsObserver::routing_id() when sending IPC messages. class AlloyBrowserHostImpl : public CefBrowserHostBase, public content::WebContentsDelegate, public content::WebContentsObserver { public: // Used for handling the response to command messages. class CommandResponseHandler : public virtual CefBaseRefCounted { public: virtual void OnResponse(const std::string& response) = 0; }; ~AlloyBrowserHostImpl() override; // Create a new AlloyBrowserHostImpl instance with owned WebContents. static CefRefPtr Create( CefBrowserCreateParams& create_params); // Safe (checked) conversion from CefBrowserHostBase to AlloyBrowserHostImpl. // Use this method instead of static_cast. static CefRefPtr FromBaseChecked( CefRefPtr host_base); // Returns the browser associated with the specified RenderViewHost. static CefRefPtr GetBrowserForHost( const content::RenderViewHost* host); // Returns the browser associated with the specified RenderFrameHost. static CefRefPtr GetBrowserForHost( const content::RenderFrameHost* host); // Returns the browser associated with the specified WebContents. static CefRefPtr GetBrowserForContents( const content::WebContents* contents); // Returns the browser associated with the specified global ID. static CefRefPtr GetBrowserForGlobalId( const content::GlobalRenderFrameHostId& global_id); // CefBrowserHost methods. void CloseBrowser(bool force_close) override; bool TryCloseBrowser() override; CefWindowHandle GetWindowHandle() override; CefWindowHandle GetOpenerWindowHandle() override; void Find(const CefString& searchText, bool forward, bool matchCase, bool findNext) override; void StopFinding(bool clearSelection) override; bool IsWindowRenderingDisabled() override; void WasResized() override; void WasHidden(bool hidden) override; void NotifyScreenInfoChanged() override; void Invalidate(PaintElementType type) override; void SendExternalBeginFrame() override; void SendTouchEvent(const CefTouchEvent& event) override; void SendCaptureLostEvent() override; int GetWindowlessFrameRate() override; void SetWindowlessFrameRate(int frame_rate) override; void ImeSetComposition(const CefString& text, const std::vector& underlines, const CefRange& replacement_range, const CefRange& selection_range) override; void ImeCommitText(const CefString& text, const CefRange& replacement_range, int relative_cursor_pos) override; void ImeFinishComposingText(bool keep_selection) override; void ImeCancelComposition() override; void DragTargetDragEnter(CefRefPtr drag_data, const CefMouseEvent& event, DragOperationsMask allowed_ops) override; void DragTargetDragOver(const CefMouseEvent& event, DragOperationsMask allowed_ops) override; void DragTargetDragLeave() override; void DragTargetDrop(const CefMouseEvent& event) override; void DragSourceSystemDragEnded() override; void DragSourceEndedAt(int x, int y, DragOperationsMask op) override; void SetAudioMuted(bool mute) override; bool IsAudioMuted() override; void SetAutoResizeEnabled(bool enabled, const CefSize& min_size, const CefSize& max_size) override; #if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP) CefRefPtr GetExtension() override; bool IsBackgroundHost() override; #endif bool CanExecuteChromeCommand(int command_id) override; void ExecuteChromeCommand(int command_id, cef_window_open_disposition_t disposition) override; // CefBrowserHostBase methods: bool IsWindowless() const override; bool IsAlloyStyle() const override { return true; } bool IsVisible() const override; // Returns true if this browser supports picture-in-picture. bool IsPictureInPictureSupported() const; // Called when the OS window hosting the browser is destroyed. void WindowDestroyed() override; bool WillBeDestroyed() const override; // Destroy the browser members. This method should only be called after the // native browser window is not longer processing messages. void DestroyBrowser() override; // Cancel display of the context menu, if any. void CancelContextMenu(); bool MaybeAllowNavigation(content::RenderFrameHost* opener, const content::OpenURLParams& params) override; // Convert from view DIP coordinates to screen coordinates. If // |want_dip_coords| is true return DIP instead of device (pixel) coordinates // on Windows/Linux. gfx::Point GetScreenPoint(const gfx::Point& view, bool want_dip_coords) const; void StartDragging(const content::DropData& drop_data, blink::DragOperationsMask allowed_ops, const gfx::ImageSkia& image, const gfx::Vector2d& image_offset, const blink::mojom::DragEventSourceInfo& event_info, content::RenderWidgetHostImpl* source_rwh); void UpdateDragOperation(ui::mojom::DragOperation operation, bool document_is_handling_drag); #if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP) // Accessors that must be called on the UI thread. extensions::ExtensionHost* GetExtensionHost() const; #endif void OnSetFocus(cef_focus_source_t source) override; bool ShowContextMenu(const content::ContextMenuParams& params); enum DestructionState { DESTRUCTION_STATE_NONE = 0, DESTRUCTION_STATE_PENDING, DESTRUCTION_STATE_ACCEPTED, DESTRUCTION_STATE_COMPLETED }; DestructionState destruction_state() const { return destruction_state_; } // content::WebContentsDelegate methods. content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params, base::OnceCallback navigation_handle_callback) override; #if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP) bool ShouldAllowRendererInitiatedCrossProcessNavigation( bool is_main_frame_navigation) override; #endif void AddNewContents(content::WebContents* source, std::unique_ptr new_contents, const GURL& target_url, WindowOpenDisposition disposition, const blink::mojom::WindowFeatures& window_features, bool user_gesture, bool* was_blocked) override; void LoadingStateChanged(content::WebContents* source, bool should_show_loading_ui) override; void CloseContents(content::WebContents* source) override; void UpdateTargetURL(content::WebContents* source, const GURL& url) override; bool DidAddMessageToConsole(content::WebContents* source, blink::mojom::ConsoleMessageLevel log_level, const std::u16string& message, int32_t line_no, const std::u16string& source_id) override; void ContentsZoomChange(bool zoom_in) override; void BeforeUnloadFired(content::WebContents* source, bool proceed, bool* proceed_to_fire_unload) override; bool TakeFocus(content::WebContents* source, bool reverse) override; void CanDownload(const GURL& url, const std::string& request_method, base::OnceCallback callback) override; content::KeyboardEventProcessingResult PreHandleKeyboardEvent( content::WebContents* source, const input::NativeWebKeyboardEvent& event) override; bool HandleKeyboardEvent(content::WebContents* source, const input::NativeWebKeyboardEvent& event) override; #if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP) bool PreHandleGestureEvent(content::WebContents* source, const blink::WebGestureEvent& event) override; #endif bool CanDragEnter(content::WebContents* source, const content::DropData& data, blink::DragOperationsMask operations_allowed) override; void GetCustomWebContentsView( content::WebContents* web_contents, const GURL& target_url, int opener_render_process_id, int opener_render_frame_id, raw_ptr* view, raw_ptr* delegate_view) override; void WebContentsCreated(content::WebContents* source_contents, int opener_render_process_id, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, content::WebContents* new_contents) override; void RendererUnresponsive( content::WebContents* source, content::RenderWidgetHost* render_widget_host, base::RepeatingClosure hang_monitor_restarter) override; void RendererResponsive( content::WebContents* source, content::RenderWidgetHost* render_widget_host) override; content::JavaScriptDialogManager* GetJavaScriptDialogManager( content::WebContents* source) override; void RunFileChooser(content::RenderFrameHost* render_frame_host, scoped_refptr listener, const blink::mojom::FileChooserParams& params) override; void EnterFullscreenModeForTab( content::RenderFrameHost* requesting_frame, const blink::mojom::FullscreenOptions& options) override; void ExitFullscreenModeForTab(content::WebContents* web_contents) override; bool IsFullscreenForTabOrPending( const content::WebContents* web_contents) override; blink::mojom::DisplayMode GetDisplayMode( const content::WebContents* web_contents) override; void FindReply(content::WebContents* web_contents, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) override; void UpdatePreferredSize(content::WebContents* source, const gfx::Size& pref_size) override; void ResizeDueToAutoResize(content::WebContents* source, const gfx::Size& new_size) override; void RequestMediaAccessPermission( content::WebContents* web_contents, const content::MediaStreamRequest& request, content::MediaResponseCallback callback) override; bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host, const url::Origin& security_origin, blink::mojom::MediaStreamType type) override; #if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP) bool IsNeverComposited(content::WebContents* web_contents) override; #endif content::PictureInPictureResult EnterPictureInPicture( content::WebContents* web_contents) override; void ExitPictureInPicture() override; bool IsBackForwardCacheSupported(content::WebContents& web_contents) override; content::PreloadingEligibility IsPrerender2Supported( content::WebContents& web_contents) override; void DraggableRegionsChanged( const std::vector& regions, content::WebContents* contents) override; // content::WebContentsObserver methods. using content::WebContentsObserver::BeforeUnloadFired; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; void OnAudioStateChanged(bool audible) override; void AccessibilityEventReceived( const ui::AXUpdatesAndEvents& details) override; void AccessibilityLocationChangesReceived( const std::vector& details) override; void WebContentsDestroyed() override; private: friend class CefBrowserPlatformDelegateAlloy; static CefRefPtr CreateInternal( const CefBrowserSettings& settings, CefRefPtr client, content::WebContents* web_contents, bool own_web_contents, scoped_refptr browser_info, CefRefPtr opener, bool is_devtools_popup, CefRefPtr request_context, std::unique_ptr platform_delegate #if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP) , CefRefPtr extension #endif ); AlloyBrowserHostImpl( const CefBrowserSettings& settings, CefRefPtr client, content::WebContents* web_contents, scoped_refptr browser_info, CefRefPtr opener, CefRefPtr request_context, std::unique_ptr platform_delegate #if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP) , CefRefPtr extension #endif ); // Give the platform delegate an opportunity to create the host window. bool CreateHostWindow(); void StartAudioCapturer(); void OnRecentlyAudibleTimerFired(); CefWindowHandle opener_; const bool is_windowless_; CefWindowHandle host_window_handle_ = kNullWindowHandle; #if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP) CefRefPtr extension_; bool is_background_host_ = false; #endif // Represents the current browser destruction state. Only accessed on the UI // thread. DestructionState destruction_state_ = DESTRUCTION_STATE_NONE; // True if the OS window hosting the browser has been destroyed. Only accessed // on the UI thread. bool window_destroyed_ = false; // Used for creating and managing context menus. std::unique_ptr menu_manager_; // Used for capturing audio for CefAudioHandler. std::unique_ptr audio_capturer_; // Timer for determining when "recently audible" transitions to false. This // starts running when a tab stops being audible, and is canceled if it starts // being audible again before it fires. std::unique_ptr recently_audible_timer_; }; #endif // CEF_LIBCEF_BROWSER_ALLOY_ALLOY_BROWSER_HOST_IMPL_H_