summaryrefslogtreecommitdiffstats
path: root/src/core/renderer/web_channel_ipc_transport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/renderer/web_channel_ipc_transport.cpp')
-rw-r--r--src/core/renderer/web_channel_ipc_transport.cpp174
1 files changed, 66 insertions, 108 deletions
diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp
index 745fe8b1e..89b20c7d1 100644
--- a/src/core/renderer/web_channel_ipc_transport.cpp
+++ b/src/core/renderer/web_channel_ipc_transport.cpp
@@ -1,49 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright (c) 2012 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.Chromium file.
#include "renderer/web_channel_ipc_transport.h"
-#include "common/qt_messages.h"
-
#include "content/public/renderer/render_frame.h"
#include "gin/arguments.h"
#include "gin/handle.h"
@@ -54,26 +16,25 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "v8/include/v8.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "qtwebengine/browser/qtwebchannel.mojom.h"
-#include <QJsonDocument>
-
namespace QtWebEngineCore {
-class WebChannelTransport : public gin::Wrappable<WebChannelTransport> {
+class WebChannelTransport : public gin::Wrappable<WebChannelTransport>
+{
public:
static gin::WrapperInfo kWrapperInfo;
static void Install(blink::WebLocalFrame *frame, uint worldId);
static void Uninstall(blink::WebLocalFrame *frame, uint worldId);
+
private:
WebChannelTransport() {}
void NativeQtSendMessage(gin::Arguments *args);
// gin::WrappableBase
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate *isolate) override;
-
- DISALLOW_COPY_AND_ASSIGN(WebChannelTransport);
+ mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportHost> m_remote;
+ content::RenderFrame *m_renderFrame = nullptr;
};
gin::WrapperInfo WebChannelTransport::kWrapperInfo = { gin::kEmbedderNativeGin };
@@ -87,20 +48,23 @@ void WebChannelTransport::Install(blink::WebLocalFrame *frame, uint worldId)
context = frame->MainWorldScriptContext();
else
context = frame->IsolatedWorldScriptContext(worldId);
+ if (context.IsEmpty())
+ return;
v8::Context::Scope contextScope(context);
gin::Handle<WebChannelTransport> transport = gin::CreateHandle(isolate, new WebChannelTransport);
+ if (transport.IsEmpty())
+ return;
v8::Local<v8::Object> global = context->Global();
- v8::Local<v8::Value> qtObjectValue = global->Get(gin::StringToV8(isolate, "qt"));
v8::Local<v8::Object> qtObject;
- if (qtObjectValue.IsEmpty() || !qtObjectValue->IsObject()) {
- qtObject = v8::Object::New(isolate);
- global->Set(gin::StringToV8(isolate, "qt"), qtObject);
- } else {
- qtObject = v8::Local<v8::Object>::Cast(qtObjectValue);
- }
- qtObject->Set(gin::StringToV8(isolate, "webChannelTransport"), transport.ToV8());
+ qtObject = v8::Object::New(isolate);
+ global->CreateDataProperty(context,
+ gin::StringToSymbol(isolate, "qt"),
+ qtObject).Check();
+ qtObject->CreateDataProperty(context,
+ gin::StringToSymbol(isolate, "webChannelTransport"),
+ transport.ToV8()).Check();
}
void WebChannelTransport::Uninstall(blink::WebLocalFrame *frame, uint worldId)
@@ -112,16 +76,16 @@ void WebChannelTransport::Uninstall(blink::WebLocalFrame *frame, uint worldId)
context = frame->MainWorldScriptContext();
else
context = frame->IsolatedWorldScriptContext(worldId);
+ if (context.IsEmpty())
+ return;
v8::Context::Scope contextScope(context);
v8::Local<v8::Object> global(context->Global());
- v8::Local<v8::Value> qtObjectValue = global->Get(gin::StringToV8(isolate, "qt"));
- if (qtObjectValue.IsEmpty() || !qtObjectValue->IsObject())
+ v8::Local<v8::Value> qtObjectValue;
+ if (!global->Get(context, gin::StringToV8(isolate, "qt")).ToLocal(&qtObjectValue) || !qtObjectValue->IsObject())
return;
v8::Local<v8::Object> qtObject = v8::Local<v8::Object>::Cast(qtObjectValue);
- // FIXME: ?
- auto whocares = qtObject->Delete(context, gin::StringToV8(isolate, "webChannelTransport"));
- Q_UNUSED(whocares);
+ qtObject->Delete(context, gin::StringToV8(isolate, "webChannelTransport")).Check();
}
void WebChannelTransport::NativeQtSendMessage(gin::Arguments *args)
@@ -147,45 +111,39 @@ void WebChannelTransport::NativeQtSendMessage(gin::Arguments *args)
return;
}
v8::Local<v8::String> jsonString = v8::Local<v8::String>::Cast(jsonValue);
+ std::vector<uint8_t> json(jsonString->Utf8Length(isolate), 0);
+ jsonString->WriteUtf8(isolate, reinterpret_cast<char *>(json.data()), json.size(), nullptr,
+ v8::String::REPLACE_INVALID_UTF8);
- QByteArray json(jsonString->Utf8Length(isolate), 0);
- jsonString->WriteUtf8(isolate,
- json.data(), json.size(),
- nullptr, v8::String::REPLACE_INVALID_UTF8);
-
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(json, &error);
- if (error.error != QJsonParseError::NoError) {
- args->ThrowTypeError("Invalid JSON");
- return;
+ if (!m_remote) {
+ renderFrame->GetRemoteAssociatedInterfaces()->GetInterface(&m_remote);
+ m_renderFrame = renderFrame;
}
+ DCHECK(renderFrame == m_renderFrame);
- int size = 0;
- const char *rawData = doc.rawData(&size);
- qtwebchannel::mojom::WebChannelTransportHostAssociatedPtr webChannelTransport;
- renderFrame->GetRemoteAssociatedInterfaces()->GetInterface(&webChannelTransport);
- webChannelTransport->DispatchWebChannelMessage(std::vector<uint8_t>(rawData, rawData + size));
+ m_remote->DispatchWebChannelMessage(json);
}
gin::ObjectTemplateBuilder WebChannelTransport::GetObjectTemplateBuilder(v8::Isolate *isolate)
{
- return gin::Wrappable<WebChannelTransport>::GetObjectTemplateBuilder(isolate)
- .SetMethod("send", &WebChannelTransport::NativeQtSendMessage);
+ return gin::Wrappable<WebChannelTransport>::GetObjectTemplateBuilder(isolate).SetMethod(
+ "send", &WebChannelTransport::NativeQtSendMessage);
}
WebChannelIPCTransport::WebChannelIPCTransport(content::RenderFrame *renderFrame)
: content::RenderFrameObserver(renderFrame)
, m_worldId(0)
, m_worldInitialized(false)
+ , m_binding(this)
{
- renderFrame->GetAssociatedInterfaceRegistry()->AddInterface(
- base::Bind(&WebChannelIPCTransport::BindRequest, base::Unretained(this)));
+ renderFrame->GetAssociatedInterfaceRegistry()->AddInterface<qtwebchannel::mojom::WebChannelTransportRender>(
+ base::BindRepeating(&WebChannelIPCTransport::BindReceiver, base::Unretained(this)));
}
-void WebChannelIPCTransport::BindRequest(
- qtwebchannel::mojom::WebChannelTransportRenderAssociatedRequest request) {
-
- m_binding.AddBinding(this, std::move(request));
+void WebChannelIPCTransport::BindReceiver(
+ mojo::PendingAssociatedReceiver<qtwebchannel::mojom::WebChannelTransportRender> receiver)
+{
+ m_binding.Bind(std::move(receiver));
}
void WebChannelIPCTransport::SetWorldId(uint32_t worldId)
@@ -205,25 +163,21 @@ void WebChannelIPCTransport::SetWorldId(uint32_t worldId)
void WebChannelIPCTransport::ResetWorldId()
{
- if (m_worldInitialized && m_canUseContext)
+ if (m_worldInitialized && m_canUseContext)
WebChannelTransport::Uninstall(render_frame()->GetWebFrame(), m_worldId);
m_worldInitialized = false;
m_worldId = 0;
}
-void WebChannelIPCTransport::DispatchWebChannelMessage(const std::vector<uint8_t> &binaryJson, uint32_t worldId)
+void WebChannelIPCTransport::DispatchWebChannelMessage(const std::vector<uint8_t> &json,
+ uint32_t worldId)
{
DCHECK(m_worldId == worldId);
if (!m_canUseContext)
return;
- QJsonDocument doc = QJsonDocument::fromRawData(reinterpret_cast<const char *>(binaryJson.data()),
- binaryJson.size(), QJsonDocument::BypassValidation);
- DCHECK(doc.isObject());
- QByteArray json = doc.toJson(QJsonDocument::Compact);
-
blink::WebLocalFrame *frame = render_frame()->GetWebFrame();
v8::Isolate *isolate = blink::MainThreadIsolate();
v8::HandleScope handleScope(isolate);
@@ -235,26 +189,30 @@ void WebChannelIPCTransport::DispatchWebChannelMessage(const std::vector<uint8_t
v8::Context::Scope contextScope(context);
v8::Local<v8::Object> global(context->Global());
- v8::Local<v8::Value> qtObjectValue(global->Get(gin::StringToV8(isolate, "qt")));
- if (qtObjectValue.IsEmpty() || !qtObjectValue->IsObject())
+ v8::Local<v8::Value> qtObjectValue;
+ if (!global->Get(context, gin::StringToV8(isolate, "qt")).ToLocal(&qtObjectValue) || !qtObjectValue->IsObject())
return;
v8::Local<v8::Object> qtObject = v8::Local<v8::Object>::Cast(qtObjectValue);
- v8::Local<v8::Value> webChannelObjectValue(qtObject->Get(gin::StringToV8(isolate, "webChannelTransport")));
- if (webChannelObjectValue.IsEmpty() || !webChannelObjectValue->IsObject())
+ v8::Local<v8::Value> webChannelObjectValue;
+ if (!qtObject->Get(context, gin::StringToV8(isolate, "webChannelTransport")).ToLocal(&webChannelObjectValue)
+ || !webChannelObjectValue->IsObject())
return;
v8::Local<v8::Object> webChannelObject = v8::Local<v8::Object>::Cast(webChannelObjectValue);
- v8::Local<v8::Value> callbackValue(webChannelObject->Get(gin::StringToV8(isolate, "onmessage")));
- if (callbackValue.IsEmpty() || !callbackValue->IsFunction()) {
- LOG(WARNING) << "onmessage is not a callable property of qt.webChannelTransport. Some things might not work as expected.";
+ v8::Local<v8::Value> callbackValue;
+ if (!webChannelObject->Get(context, gin::StringToV8(isolate, "onmessage")).ToLocal(&callbackValue)
+ || !callbackValue->IsFunction()) {
+ LOG(WARNING) << "onmessage is not a callable property of qt.webChannelTransport. Some things might not work as "
+ "expected.";
return;
}
v8::Local<v8::Object> messageObject(v8::Object::New(isolate));
v8::Maybe<bool> wasSet = messageObject->DefineOwnProperty(
- context,
- v8::String::NewFromUtf8(isolate, "data"),
- v8::String::NewFromUtf8(isolate, json.constData(), v8::String::kNormalString, json.size()),
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
+ context, v8::String::NewFromUtf8(isolate, "data").ToLocalChecked(),
+ v8::String::NewFromUtf8(isolate, reinterpret_cast<const char *>(json.data()),
+ v8::NewStringType::kNormal, json.size())
+ .ToLocalChecked(),
+ v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
DCHECK(!wasSet.IsNothing() && wasSet.FromJust());
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(callbackValue);
@@ -262,21 +220,21 @@ void WebChannelIPCTransport::DispatchWebChannelMessage(const std::vector<uint8_t
frame->CallFunctionEvenIfScriptDisabled(callback, webChannelObject, 1, argv);
}
-void WebChannelIPCTransport::WillReleaseScriptContext(v8::Local<v8::Context> context, int worldId)
-{
- if (static_cast<uint>(worldId) == m_worldId)
- m_canUseContext = false;
-}
-
-void WebChannelIPCTransport::DidClearWindowObject()
+void WebChannelIPCTransport::DidCreateScriptContext(v8::Local<v8::Context> context, int32_t worldId)
{
- if (!m_canUseContext) {
+ if (static_cast<uint>(worldId) == m_worldId && !m_canUseContext) {
m_canUseContext = true;
if (m_worldInitialized)
WebChannelTransport::Install(render_frame()->GetWebFrame(), m_worldId);
}
}
+void WebChannelIPCTransport::WillReleaseScriptContext(v8::Local<v8::Context> context, int worldId)
+{
+ if (static_cast<uint>(worldId) == m_worldId)
+ m_canUseContext = false;
+}
+
void WebChannelIPCTransport::OnDestruct()
{
delete this;