// Copyright (c) 2012 The Chromium Embedded Framework 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_RENDERER_FRAME_IMPL_H_ #define CEF_LIBCEF_RENDERER_FRAME_IMPL_H_ #pragma once #include #include #include "include/cef_frame.h" #include "include/cef_v8.h" #include "libcef/renderer/blink_glue.h" #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" #include "cef/libcef/common/mojom/cef.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" namespace base { class ListValue; } namespace blink { class ResourceLoadInfoNotifierWrapper; class WebLocalFrame; class WebURLLoader; class WebURLLoaderFactory; } // namespace blink class GURL; class CefBrowserImpl; // Implementation of CefFrame. CefFrameImpl objects are owned by the // CefBrowerImpl and will be detached when the browser is notified that the // associated renderer WebFrame will close. class CefFrameImpl : public CefFrame, public cef::mojom::RenderFrame, public blink_glue::CefExecutionContextLifecycleStateObserver { public: CefFrameImpl(CefBrowserImpl* browser, blink::WebLocalFrame* frame, int64_t frame_id); CefFrameImpl(const CefFrameImpl&) = delete; CefFrameImpl& operator=(const CefFrameImpl&) = delete; ~CefFrameImpl() override; // CefFrame implementation. bool IsValid() override; void Undo() override; void Redo() override; void Cut() override; void Copy() override; void Paste() override; void Delete() override; void SelectAll() override; void ViewSource() override; void GetSource(CefRefPtr visitor) override; void GetText(CefRefPtr visitor) override; void LoadRequest(CefRefPtr request) override; void LoadURL(const CefString& url) override; void ExecuteJavaScript(const CefString& jsCode, const CefString& scriptUrl, int startLine) override; bool IsMain() override; bool IsFocused() override; CefString GetName() override; int64 GetIdentifier() override; CefRefPtr GetParent() override; CefString GetURL() override; CefRefPtr GetBrowser() override; CefRefPtr GetV8Context() override; void VisitDOM(CefRefPtr visitor) override; CefRefPtr CreateURLRequest( CefRefPtr request, CefRefPtr client) override; void SendProcessMessage(CefProcessId target_process, CefRefPtr message) override; // Used by CefRenderURLRequest. std::unique_ptr CreateURLLoader(); std::unique_ptr CreateResourceLoadInfoNotifierWrapper(); // Forwarded from CefRenderFrameObserver. void OnAttached(); void OnWasShown(); void OnDidCommitProvisionalLoad(); void OnDidFinishLoad(); void OnDraggableRegionsChanged(); void OnContextCreated(v8::Local context); void OnContextReleased(); void OnDetached(); blink::WebLocalFrame* web_frame() const { return frame_; } private: // Execute an action on the associated WebLocalFrame. This will queue the // action if the JavaScript context is not yet created. using LocalFrameAction = base::OnceCallback; void ExecuteOnLocalFrame(const std::string& function_name, LocalFrameAction action); enum class ConnectReason { RENDER_FRAME_CREATED, WAS_SHOWN, RETRY, }; // Initiate the connection to the BrowserFrame channel. void ConnectBrowserFrame(ConnectReason reason); // Returns the remote BrowserFrame object. using BrowserFrameType = mojo::Remote; const BrowserFrameType& GetBrowserFrame(bool expect_acked = true); // Called if the BrowserFrame connection attempt times out. void OnBrowserFrameTimeout(); enum class DisconnectReason { DETACHED, BROWSER_FRAME_DETACHED, CONNECT_TIMEOUT, RENDER_FRAME_DISCONNECT, BROWSER_FRAME_DISCONNECT, }; // Called if/when a disconnect occurs. This may occur due to frame navigation, // destruction, or insertion into the bfcache (when the browser-side frame // representation is destroyed and closes the connection). void OnDisconnect(DisconnectReason reason); // Send an action to the remote BrowserFrame. This will queue the action if // the remote frame is not yet attached. using BrowserFrameAction = base::OnceCallback; void SendToBrowserFrame(const std::string& function_name, BrowserFrameAction action); void MaybeInitializeScriptContext(); // cef::mojom::RenderFrame methods: void FrameAttachedAck() override; void FrameDetached() override; void SendMessage(const std::string& name, base::Value arguments) override; void SendSharedMemoryRegion(const std::string& name, base::ReadOnlySharedMemoryRegion region) override; void SendCommand(const std::string& command) override; void SendCommandWithResponse( const std::string& command, cef::mojom::RenderFrame::SendCommandWithResponseCallback callback) override; void SendJavaScript(const std::u16string& jsCode, const std::string& scriptUrl, int32_t startLine) override; void LoadRequest(cef::mojom::RequestParamsPtr params) override; void DidStopLoading() override; void MoveOrResizeStarted() override; // blink_glue::CefExecutionContextLifecycleStateObserver methods: void ContextLifecycleStateChanged( blink::mojom::blink::FrameLifecycleState state) override; std::string GetDebugString() const; CefBrowserImpl* browser_; blink::WebLocalFrame* frame_; const int64 frame_id_; bool did_commit_provisional_load_ = false; bool did_initialize_script_context_ = false; bool context_created_ = false; std::queue> queued_context_actions_; // Number of times that browser reconnect has been attempted. size_t browser_connect_retry_ct_ = 0; // Current browser connection state. enum class ConnectionState { DISCONNECTED, CONNECTION_PENDING, CONNECTION_ACKED, RECONNECT_PENDING, } browser_connection_state_ = ConnectionState::DISCONNECTED; base::OneShotTimer browser_connect_timer_; std::queue> queued_browser_actions_; std::unique_ptr url_loader_factory_; mojo::Receiver receiver_{this}; mojo::Remote browser_frame_; std::unique_ptr execution_context_lifecycle_state_observer_; base::WeakPtrFactory weak_ptr_factory_{this}; IMPLEMENT_REFCOUNTING(CefFrameImpl); }; #endif // CEF_LIBCEF_RENDERER_FRAME_IMPL_H_