|
@@ -98,38 +98,61 @@ ElectronApiServiceImpl::~ElectronApiServiceImpl() = default;
|
|
|
|
|
|
ElectronApiServiceImpl::ElectronApiServiceImpl(
|
|
|
content::RenderFrame* render_frame,
|
|
|
- RendererClientBase* renderer_client,
|
|
|
- mojom::ElectronRendererAssociatedRequest request)
|
|
|
+ RendererClientBase* renderer_client)
|
|
|
: content::RenderFrameObserver(render_frame),
|
|
|
binding_(this),
|
|
|
- render_frame_(render_frame),
|
|
|
- renderer_client_(renderer_client) {
|
|
|
- binding_.Bind(std::move(request));
|
|
|
- binding_.set_connection_error_handler(base::BindOnce(
|
|
|
- &ElectronApiServiceImpl::OnDestruct, base::Unretained(this)));
|
|
|
-}
|
|
|
+ renderer_client_(renderer_client),
|
|
|
+ weak_factory_(this) {}
|
|
|
|
|
|
-// static
|
|
|
-void ElectronApiServiceImpl::CreateMojoService(
|
|
|
- content::RenderFrame* render_frame,
|
|
|
- RendererClientBase* renderer_client,
|
|
|
+void ElectronApiServiceImpl::BindTo(
|
|
|
mojom::ElectronRendererAssociatedRequest request) {
|
|
|
- DCHECK(render_frame);
|
|
|
+ // Note: BindTo might be called for multiple times.
|
|
|
+ if (binding_.is_bound())
|
|
|
+ binding_.Unbind();
|
|
|
+
|
|
|
+ binding_.Bind(std::move(request));
|
|
|
+ binding_.set_connection_error_handler(
|
|
|
+ base::BindOnce(&ElectronApiServiceImpl::OnConnectionError, GetWeakPtr()));
|
|
|
+}
|
|
|
|
|
|
- // Owns itself. Will be deleted when the render frame is destroyed.
|
|
|
- new ElectronApiServiceImpl(render_frame, renderer_client, std::move(request));
|
|
|
+void ElectronApiServiceImpl::DidCreateDocumentElement() {
|
|
|
+ document_created_ = true;
|
|
|
}
|
|
|
|
|
|
void ElectronApiServiceImpl::OnDestruct() {
|
|
|
delete this;
|
|
|
}
|
|
|
|
|
|
+void ElectronApiServiceImpl::OnConnectionError() {
|
|
|
+ if (binding_.is_bound())
|
|
|
+ binding_.Unbind();
|
|
|
+}
|
|
|
+
|
|
|
void ElectronApiServiceImpl::Message(bool internal,
|
|
|
bool send_to_all,
|
|
|
const std::string& channel,
|
|
|
base::Value arguments,
|
|
|
int32_t sender_id) {
|
|
|
- blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
|
|
|
+ // Don't handle browser messages before document element is created.
|
|
|
+ //
|
|
|
+ // Note: It is probably better to save the message and then replay it after
|
|
|
+ // document is ready, but current behavior has been there since the first
|
|
|
+ // day of Electron, and no one has complained so far.
|
|
|
+ //
|
|
|
+ // Reason 1:
|
|
|
+ // When we receive a message from the browser, we try to transfer it
|
|
|
+ // to a web page, and when we do that Blink creates an empty
|
|
|
+ // document element if it hasn't been created yet, and it makes our init
|
|
|
+ // script to run while `window.location` is still "about:blank".
|
|
|
+ // (See https://github.com/electron/electron/pull/1044.)
|
|
|
+ //
|
|
|
+ // Reason 2:
|
|
|
+ // The libuv message loop integration would be broken for unkown reasons.
|
|
|
+ // (See https://github.com/electron/electron/issues/19368.)
|
|
|
+ if (!document_created_)
|
|
|
+ return;
|
|
|
+
|
|
|
+ blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
|
|
|
if (!frame)
|
|
|
return;
|
|
|
|