summaryrefslogtreecommitdiffstats
path: root/src/core/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/renderer')
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp8
-rw-r--r--src/core/renderer/web_channel_ipc_transport.cpp175
-rw-r--r--src/core/renderer/web_channel_ipc_transport.h59
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