diff options
Diffstat (limited to 'src/core/renderer')
-rw-r--r-- | src/core/renderer/content_renderer_client_qt.cpp | 8 | ||||
-rw-r--r-- | src/core/renderer/web_channel_ipc_transport.cpp | 175 | ||||
-rw-r--r-- | src/core/renderer/web_channel_ipc_transport.h | 59 |
3 files changed, 240 insertions, 2 deletions
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index a13a7999c..f8970e7a0 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -50,6 +50,7 @@ #include "ui/base/webui/jstemplate_builder.h" #include "content/public/common/web_preferences.h" +#include "renderer/web_channel_ipc_transport.h" #include "renderer/qt_render_view_observer.h" #include "grit/renderer_resources.h" @@ -66,14 +67,17 @@ ContentRendererClientQt::~ContentRendererClientQt() void ContentRendererClientQt::RenderThreadStarted() { + content::RenderThread *renderThread = content::RenderThread::Get(); + renderThread->RegisterExtension(WebChannelIPCTransport::getV8Extension()); m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave); - content::RenderThread::Get()->AddObserver(m_visitedLinkSlave.data()); + renderThread->AddObserver(m_visitedLinkSlave.data()); } void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view) { - // RenderViewObserver destroys itself with its RenderView. + // RenderViewObservers destroy themselves with their RenderView. new QtRenderViewObserver(render_view); + new WebChannelIPCTransport(render_view); } bool ContentRendererClientQt::HasErrorPage(int httpStatusCode, std::string *errorDomain) diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp new file mode 100644 index 000000000..0491a6103 --- /dev/null +++ b/src/core/renderer/web_channel_ipc_transport.cpp @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// 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 file. + +#include "renderer/web_channel_ipc_transport.h" + +#include "common/qt_messages.h" + +#include "content/public/renderer/render_view.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "third_party/WebKit/public/web/WebView.h" +#include "v8/include/v8.h" + +#include <QJsonDocument> + +static const char kWebChannelTransportExtensionName[] = "v8/WebChannelTransport"; + +static const char kWebChannelTransportApi[] = + "if (typeof(navigator) === 'undefined')" \ + " navigator = {};" \ + "if (typeof(navigator.qtWebChannelTransport) === 'undefined')" \ + " navigator.qtWebChannelTransport = {};" \ + "navigator.qtWebChannelTransport.send = function(message) {" \ + " native function NativeQtSendMessage();" \ + " NativeQtSendMessage(message);" \ + "};"; + +class WebChannelTransportExtension : public v8::Extension { +public: + static content::RenderView *GetRenderView(); + + WebChannelTransportExtension() : v8::Extension(kWebChannelTransportExtensionName, kWebChannelTransportApi) + { + } + + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(v8::Isolate* isolate, v8::Handle<v8::String> name) Q_DECL_OVERRIDE; + + static void NativeQtSendMessage(const v8::FunctionCallbackInfo<v8::Value>& args) + { + content::RenderView *renderView = GetRenderView(); + if (!renderView || args.Length() != 1) + return; + v8::Handle<v8::Value> val = args[0]; + if (!val->IsString() && !val->IsStringObject()) + return; + v8::String::Utf8Value utf8(val->ToString()); + + QByteArray valueData(*utf8, utf8.length()); + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(valueData, &error); + if (error.error != QJsonParseError::NoError) + qWarning("%s %d: Parsing error: %s",__FILE__, __LINE__, qPrintable(error.errorString())); + int size = 0; + const char *rawData = doc.rawData(&size); + renderView->Send(new WebChannelIPCTransportHost_SendMessage(renderView->GetRoutingID(), std::vector<char>(rawData, rawData + size))); + } +}; + +content::RenderView *WebChannelTransportExtension::GetRenderView() +{ + blink::WebLocalFrame *webframe = blink::WebLocalFrame::frameForCurrentContext(); + DCHECK(webframe) << "There should be an active frame since we just got a native function called."; + if (!webframe) + return 0; + + blink::WebView *webview = webframe->view(); + if (!webview) + return 0; // can happen during closing + + return content::RenderView::FromWebView(webview); +} + +v8::Handle<v8::FunctionTemplate> WebChannelTransportExtension::GetNativeFunctionTemplate(v8::Isolate *isolate, v8::Handle<v8::String> name) +{ + if (name->Equals(v8::String::NewFromUtf8(isolate, "NativeQtSendMessage"))) + return v8::FunctionTemplate::New(isolate, NativeQtSendMessage); + + return v8::Handle<v8::FunctionTemplate>(); +} + +WebChannelIPCTransport::WebChannelIPCTransport(content::RenderView *renderView) + : content::RenderViewObserver(renderView) +{ +} + +void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector<char> &binaryJSON) +{ + blink::WebView *webView = render_view()->GetWebView(); + if (!webView) + return; + + QJsonDocument doc = QJsonDocument::fromRawData(binaryJSON.data(), binaryJSON.size(), QJsonDocument::BypassValidation); + Q_ASSERT(doc.isObject()); + QByteArray json = doc.toJson(QJsonDocument::Compact); + + v8::Isolate *isolate = v8::Isolate::GetCurrent(); + v8::HandleScope handleScope(isolate); + blink::WebFrame *frame = webView->mainFrame(); + v8::Handle<v8::Context> context = frame->mainWorldScriptContext(); + v8::Context::Scope contextScope(context); + + v8::Handle<v8::Object> global(context->Global()); + v8::Handle<v8::Value> navigatorValue(global->Get(v8::String::NewFromUtf8(isolate, "navigator"))); + if (!navigatorValue->IsObject()) + return; + v8::Handle<v8::Value> navigatorQtValue(navigatorValue->ToObject()->Get(v8::String::NewFromUtf8(isolate, "qtWebChannelTransport"))); + if (!navigatorQtValue->IsObject()) + return; + v8::Handle<v8::Value> onmessageCallbackValue(navigatorQtValue->ToObject()->Get(v8::String::NewFromUtf8(isolate, "onmessage"))); + if (!onmessageCallbackValue->IsFunction()) { + qWarning("onmessage is not a callable property of navigator.qtWebChannelTransport. Some things might not work as expected."); + return; + } + + v8::Handle<v8::Object> messageObject(v8::Object::New(isolate)); + messageObject->ForceSet(v8::String::NewFromUtf8(isolate, "data") + , v8::String::NewFromUtf8(isolate, json.constData(), v8::String::kNormalString, json.size()) + , v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); + + v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(onmessageCallbackValue); + const int argc = 1; + v8::Handle<v8::Value> argv[argc]; + argv[0] = messageObject; + frame->callFunctionEvenIfScriptDisabled(callback, navigatorQtValue->ToObject(), argc, argv); +} + +v8::Extension *WebChannelIPCTransport::getV8Extension() +{ + return new WebChannelTransportExtension; +} + +bool WebChannelIPCTransport::OnMessageReceived(const IPC::Message &message) +{ + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(WebChannelIPCTransport, message) + IPC_MESSAGE_HANDLER(WebChannelIPCTransport_Message, dispatchWebChannelMessage) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h new file mode 100644 index 000000000..29e819e95 --- /dev/null +++ b/src/core/renderer/web_channel_ipc_transport.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef NAVIGATOR_QT_EXTENSION_H +#define NAVIGATOR_QT_EXTENSION_H + +#include "base/values.h" +#include "content/public/renderer/render_view_observer.h" +#include <QtCore/qcompilerdetection.h> + +namespace v8 { +class Extension; +} + +class WebChannelIPCTransport : public content::RenderViewObserver { +public: + static v8::Extension* getV8Extension(); + + WebChannelIPCTransport(content::RenderView *); + +private: + void dispatchWebChannelMessage(const std::vector<char> &binaryJSON); + virtual bool OnMessageReceived(const IPC::Message &message) Q_DECL_OVERRIDE; +}; + +#endif // NAVIGATOR_QT_EXTENSION_H |