From 4c6b93dc7515ebd193ec60d5cd2085f901351969 Mon Sep 17 00:00:00 2001
From: Christophe Chapuis <chris.chapuis@gmail.com>
Date: Sat, 26 Sep 2015 22:26:24 +0200
Subject: [PATCH 01/10] Add PalmServiceBridge to WebEngine

* Adapt PalmServiceBridge IDL for Chromium
* Propagate PalmBridgeService related settings from host
* Attempt to have a correct implementation for onserviceresponse attribute
* test returned identifier before using it

Signed-off-by: Christophe Chapuis <chris.chapuis@gmail.com>
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
---
 .../public/common/common_param_traits_macros.h     |   3 +
 chromium/content/public/common/web_preferences.cc  |   5 +-
 chromium/content/public/common/web_preferences.h   |   5 +
 chromium/content/renderer/render_view_impl.cc      |   3 +
 .../WebKit/Source/core/frame/Settings.in           |  11 +
 .../third_party/WebKit/Source/modules/BUILD.gn     |   1 +
 .../WebKit/Source/modules/modules_idl_files.gni    |   1 +
 .../WebKit/Source/modules/webos/BUILD.gn           |  13 +
 .../WebKit/Source/modules/webos/Logging.h          |  11 +
 .../WebKit/Source/modules/webos/LunaServiceMgr.cpp | 316 +++++++++++++++++++++
 .../WebKit/Source/modules/webos/LunaServiceMgr.h   |  53 ++++
 .../Source/modules/webos/PalmServiceBridge.cpp     | 300 +++++++++++++++++++
 .../Source/modules/webos/PalmServiceBridge.h       |  90 ++++++
 .../Source/modules/webos/PalmServiceBridge.idl     |  14 +
 .../WebKit/Source/web/WebSettingsImpl.cpp          |  16 ++
 .../WebKit/Source/web/WebSettingsImpl.h            |   3 +
 .../third_party/WebKit/public/web/WebSettings.h    |   3 +
 17 files changed, 847 insertions(+), 1 deletion(-)
 create mode 100644 chromium/third_party/WebKit/Source/modules/webos/BUILD.gn
 create mode 100644 chromium/third_party/WebKit/Source/modules/webos/Logging.h
 create mode 100644 chromium/third_party/WebKit/Source/modules/webos/LunaServiceMgr.cpp
 create mode 100644 chromium/third_party/WebKit/Source/modules/webos/LunaServiceMgr.h
 create mode 100644 chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.cpp
 create mode 100644 chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.h
 create mode 100644 chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.idl

diff --git a/src/3rdparty/chromium/content/public/common/common_param_traits_macros.h b/src/3rdparty/chromium/content/public/common/common_param_traits_macros.h
index 9b2e0ff..c4568af 100644
--- a/src/3rdparty/chromium/content/public/common/common_param_traits_macros.h
+++ b/src/3rdparty/chromium/content/public/common/common_param_traits_macros.h
@@ -245,6 +245,9 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
   IPC_STRUCT_TRAITS_MEMBER(default_minimum_page_scale_factor)
   IPC_STRUCT_TRAITS_MEMBER(default_maximum_page_scale_factor)
   IPC_STRUCT_TRAITS_MEMBER(hide_download_ui)
+  IPC_STRUCT_TRAITS_MEMBER(luneosPriviledged)
+  IPC_STRUCT_TRAITS_MEMBER(palmServiceBridgeEnabled)
+  IPC_STRUCT_TRAITS_MEMBER(luneosAppIdentifier)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(blink::WebWindowFeatures)
diff --git a/src/3rdparty/chromium/content/public/common/web_preferences.cc b/src/3rdparty/chromium/content/public/common/web_preferences.cc
index 2e9e036..45b6d9f 100644
--- a/src/3rdparty/chromium/content/public/common/web_preferences.cc
+++ b/src/3rdparty/chromium/content/public/common/web_preferences.cc
@@ -222,7 +222,10 @@ WebPreferences::WebPreferences()
       default_minimum_page_scale_factor(1.f),
       default_maximum_page_scale_factor(4.f),
 #endif
-      hide_download_ui(false) {
+      hide_download_ui(false),
+      luneosPriviledged(false),
+      palmServiceBridgeEnabled(false),
+      luneosAppIdentifier("") {
   standard_font_family_map[kCommonScript] =
       base::ASCIIToUTF16("Times New Roman");
   fixed_font_family_map[kCommonScript] = base::ASCIIToUTF16("Courier New");
diff --git a/src/3rdparty/chromium/content/public/common/web_preferences.h b/src/3rdparty/chromium/content/public/common/web_preferences.h
index 44ff927..fbdeae8 100644
--- a/src/3rdparty/chromium/content/public/common/web_preferences.h
+++ b/src/3rdparty/chromium/content/public/common/web_preferences.h
@@ -264,6 +264,11 @@ struct CONTENT_EXPORT WebPreferences {
   // Whether download UI should be hidden on this page.
   bool hide_download_ui;
 
+  // Follwing settings are for LuneOS usage
+  bool luneosPriviledged;
+  bool palmServiceBridgeEnabled;
+  std::string luneosAppIdentifier;
+  
   // We try to keep the default values the same as the default values in
   // chrome, except for the cases where it would require lots of extra work for
   // the embedder to use the same default value.
diff --git a/src/3rdparty/chromium/content/renderer/render_view_impl.cc b/src/3rdparty/chromium/content/renderer/render_view_impl.cc
index a32fe58..512f621 100644
--- a/src/3rdparty/chromium/content/renderer/render_view_impl.cc
+++ b/src/3rdparty/chromium/content/renderer/render_view_impl.cc
@@ -1031,6 +1031,9 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
 #elif defined(TOOLKIT_QT)
   settings->setFullscreenSupported(prefs.fullscreen_supported);
 #endif
+  settings->setLuneosPriviledged(prefs.luneosPriviledged);
+  settings->setPalmServiceBridgeEnabled(prefs.palmServiceBridgeEnabled);
+  settings->setLuneosAppIdentifier(base::ASCIIToUTF16(prefs.luneosAppIdentifier));
 
   settings->setAutoplayExperimentMode(
       blink::WebString::fromUTF8(prefs.autoplay_experiment_mode));
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/core/frame/Settings.in b/src/3rdparty/chromium/third_party/WebKit/Source/core/frame/Settings.in
index b66cff7..5a50982 100644
--- a/src/3rdparty/chromium/third_party/WebKit/Source/core/frame/Settings.in
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/core/frame/Settings.in
@@ -405,6 +405,17 @@ useDefaultImageInterpolationQuality initial=false
 # tokenizes input bytes. The default is to tokenize with a post task.
 parseHTMLOnMainThreadSyncTokenize initial=false
 
+# #### LuneOS specific #####
+
+# Whether PalmBridge is enabled or not
+palmServiceBridgeEnabled initial=false
+
+# Whether the LuneOS app has priviledge access
+luneosPriviledged initial=false
+
+# LuneOS app identifier
+luneosAppIdentifier type=String, initial=""
+
 # Variant of the ParseHTMLOnMainThread experiment. This is designed to coalesce
 # TokenizedChunks when the experiment is running in threaded mode.
 parseHTMLOnMainThreadCoalesceChunks initial=false
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/modules/BUILD.gn b/src/3rdparty/chromium/third_party/WebKit/Source/modules/BUILD.gn
index ab332ef..4e8e58d 100644
--- a/src/3rdparty/chromium/third_party/WebKit/Source/modules/BUILD.gn
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/modules/BUILD.gn
@@ -150,6 +150,7 @@ target(modules_target_type, "modules") {
     "//third_party/WebKit/Source/modules/vr",
     "//third_party/WebKit/Source/modules/wake_lock",
     "//third_party/WebKit/Source/modules/webaudio",
+    "//third_party/WebKit/Source/modules/webos",
     "//third_party/WebKit/Source/modules/webdatabase",
     "//third_party/WebKit/Source/modules/webgl",
     "//third_party/WebKit/Source/modules/webmidi",
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/modules/modules_idl_files.gni b/src/3rdparty/chromium/third_party/WebKit/Source/modules/modules_idl_files.gni
index e9dd62f..a7bae9b 100644
--- a/src/3rdparty/chromium/third_party/WebKit/Source/modules/modules_idl_files.gni
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -368,6 +368,7 @@ modules_idl_files =
                     "webmidi/MIDIOutput.idl",
                     "webmidi/MIDIOutputMap.idl",
                     "webmidi/MIDIPort.idl",
+                    "webos/PalmServiceBridge.idl",
                     "websockets/CloseEvent.idl",
                     "websockets/WebSocket.idl",
                     "webusb/USB.idl",
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/BUILD.gn b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/BUILD.gn
new file mode 100644
index 0000000..effd211
--- /dev/null
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2017 Herman van Hazendonk. All rights reserved.
+
+import("//third_party/WebKit/Source/modules/modules.gni")
+
+blink_modules_sources("webos") {
+  sources = [
+    "Logging.h",
+    "LunaServiceMgr.cpp",
+    "LunaServiceMgr.h",
+    "PalmServiceBridge.cpp",
+    "PalmServiceBridge.h",
+  ]
+}
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/Logging.h b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/Logging.h
new file mode 100644
index 0000000..d472ae2
--- /dev/null
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/Logging.h
@@ -0,0 +1,11 @@
+#ifndef LOGGING_H_
+#define LOGGING_H_
+
+#include <PmLogLib.h>
+
+extern PmLogContext LogContext;
+
+#define DEBUG(...) \
+	PmLogDebug(LogContext, ##__VA_ARGS__)
+
+#endif
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/LunaServiceMgr.cpp b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/LunaServiceMgr.cpp
new file mode 100644
index 0000000..55feab8
--- /dev/null
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/LunaServiceMgr.cpp
@@ -0,0 +1,316 @@
+#include "config.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/bind.h"
+
+#include <glib.h>
+#include "LunaServiceMgr.h"
+#include "Logging.h"
+
+#include <unistd.h>
+#include <lunaservice.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <wtf/text/WTFString.h>
+#include <wtf/text/CString.h>
+
+namespace blink {
+
+/**
+* @brief Internal callback for service responses.
+*
+* @param  sh
+* @param  reply
+* @param  ctx
+*
+* @retval
+*/
+static bool
+message_filter(LSHandle *sh, LSMessage* reply, void* ctx)
+{
+    const char* payload = LSMessageGetPayload(reply);
+
+    LunaServiceManagerListener* listener = (LunaServiceManagerListener*)ctx;
+
+    if (listener) {
+        listener->serviceResponse(payload);
+        return true;
+    }
+
+    return false;
+}
+
+bool doIterateNext = true;
+void GMainContextIterate()
+{
+    g_main_context_iteration(g_main_context_default(), false);
+    // be called again in 100ms
+    base::MessageLoop *pCurrentMsgLoop = base::MessageLoop::current();
+    if( doIterateNext && pCurrentMsgLoop )
+    {
+        pCurrentMsgLoop->PostDelayedTask(FROM_HERE, base::Bind(&GMainContextIterate), base::TimeDelta::FromMilliseconds(100));
+    }
+}
+
+LunaServiceManager* s_instance = 0;
+
+/**
+* @brief Obtains the singleton LunaServiceManager.
+*
+* @retval the LunaServiceManager
+*/
+LunaServiceManager* LunaServiceManager::instance()
+{
+    bool retVal;
+    if (s_instance)
+        return s_instance;
+
+    s_instance = new LunaServiceManager();
+    retVal = s_instance->init();
+    if (!retVal)
+        goto error;
+
+    return s_instance;
+
+error:
+    fprintf(stderr, "*******************************************************************\n");
+    fprintf(stderr, "*  Could got get an instance of LunaServiceManager.               *\n");
+    fprintf(stderr, "*  Try running with luna-dbus start; luna-dbus run <executable>.  *\n");
+    fprintf(stderr, "*******************************************************************\n");
+    exit(-1);
+}
+
+/**
+* @brief Private constructor to enforce singleton.
+*/
+LunaServiceManager::LunaServiceManager() :
+      publicBus(0)
+    , privateBus(0)
+    , palmServiceHandle(0)
+    , publicBusHighPriority(0)
+    , privateBusHighPriority(0)
+    , palmServiceHandleHighPriority(0)
+{
+}
+
+LunaServiceManager::~LunaServiceManager()
+{
+    doIterateNext = false;
+    // ED : Close the single connection to DBUS.
+    if (palmServiceHandle) {
+        bool retVal;
+        LSError lserror;
+        LSErrorInit(&lserror);
+
+        retVal = LSUnregisterPalmService(palmServiceHandle, &lserror);
+        if (!retVal) {
+            g_warning("LSUnregisterPalmService ERROR %d: %s (%s @ %s:%d)",
+                lserror.error_code, lserror.message,
+                lserror.func, lserror.file, lserror.line);
+            LSErrorFree(&lserror);
+        }
+    }
+}
+
+bool LunaServiceManager::init()
+{
+    bool init;
+    LSError lserror;
+    LSErrorInit(&lserror);
+
+    DEBUG("LunaServiceManager: Starting iteration on GLib event loop ...");
+    GMainContextIterate();
+
+    DEBUG("LunaServiceManager: initializing ...");
+
+    String id("com.palm.luna-");
+    id.append(String::number(getpid()));
+    String active = (id + "-active");
+    String phone = (id + "-phone");
+    init = LSRegisterPalmService(id.utf8().data(), &palmServiceHandle, &lserror);
+    if (!init)
+        goto error;
+
+    init = LSGmainAttachPalmService(palmServiceHandle,
+            g_main_loop_new(g_main_context_default(), TRUE), &lserror);
+    if (!init)
+        goto error;
+
+    privateBus = LSPalmServiceGetPrivateConnection(palmServiceHandle);
+    publicBus = LSPalmServiceGetPublicConnection(palmServiceHandle);
+
+    if (privateBus) {
+        init = LSGmainSetPriority(privateBus, G_PRIORITY_DEFAULT, &lserror);
+        if (!init)
+            goto error;
+    }
+
+    if (publicBus) {
+        init = LSGmainSetPriority(publicBus, G_PRIORITY_DEFAULT, &lserror);
+        if (!init)
+            goto error;
+    }
+
+    init = LSRegisterPalmService(phone.utf8().data(), &palmServiceHandleHighPriority, &lserror);
+    if (!init)
+        goto error;
+
+    init = LSGmainAttachPalmService(palmServiceHandleHighPriority,
+            g_main_loop_new(g_main_context_default(), TRUE), &lserror);
+    if (!init)
+        goto error;
+
+    privateBusHighPriority = LSPalmServiceGetPrivateConnection(palmServiceHandleHighPriority);
+    publicBusHighPriority = LSPalmServiceGetPublicConnection(palmServiceHandleHighPriority);
+
+    if (privateBusHighPriority) {
+        init = LSGmainSetPriority(privateBusHighPriority, G_PRIORITY_HIGH, &lserror);
+        if (!init)
+            goto error;
+    }
+
+    if (publicBusHighPriority) {
+        init = LSGmainSetPriority(publicBusHighPriority, G_PRIORITY_HIGH, &lserror);
+        if (!init)
+            goto error;
+    }
+
+
+    init = LSRegisterPalmService(active.utf8().data(), &palmServiceHandleMediumPriority, &lserror);
+    if (!init)
+        goto error;
+
+    init = LSGmainAttachPalmService(palmServiceHandleMediumPriority,
+            g_main_loop_new(g_main_context_default(), TRUE), &lserror);
+    if (!init)
+        goto error;
+
+    privateBusMediumPriority = LSPalmServiceGetPrivateConnection(palmServiceHandleMediumPriority);
+    publicBusMediumPriority = LSPalmServiceGetPublicConnection(palmServiceHandleMediumPriority);
+
+    if (privateBusMediumPriority) {
+        init = LSGmainSetPriority(privateBusMediumPriority, G_PRIORITY_HIGH + 50, &lserror);
+        if (!init)
+            goto error;
+    }
+
+    if (publicBusMediumPriority) {
+        init = LSGmainSetPriority(publicBusMediumPriority, G_PRIORITY_HIGH + 50, &lserror);
+        if (!init)
+            goto error;
+    }
+
+error:
+    if (!init) {
+        g_warning("Cannot initialize LunaServiceManager ERROR %d: %s (%s @ %s:%d)",
+            lserror.error_code, lserror.message,
+            lserror.func, lserror.file, lserror.line);
+        LSErrorFree(&lserror);
+    }
+
+    return init;
+}
+
+/**
+* @brief This method will make the async call to DBUS.
+*
+* @param  uri
+* @param  payload
+* @param  inListener
+*
+* @retval 0 if message could not be sent.
+* @retval >0 serial number for the message.
+*/
+unsigned long LunaServiceManager::call(const char* uri, const char* payload, LunaServiceManagerListener* inListener,
+                                       const char* callerId, bool usePrivateBus)
+{
+    bool retVal;
+    LSError lserror;
+    LSErrorInit(&lserror);
+    LSMessageToken token = 0;
+    LSHandle* serviceHandle = 0;
+
+    DEBUG("LunaServiceManager: calling %s payload %s inListener %p callerId %s usePrivateBus %d",
+          uri, payload, inListener, callerId, usePrivateBus);
+
+    if (callerId && (!(*callerId)))
+        callerId = 0;
+
+    static int phoneAppIdLen = strlen("com.palm.app.phone");
+    if (callerId && !(strncmp(callerId, "com.palm.app.phone", phoneAppIdLen))) {
+
+        if (!usePrivateBus)
+            serviceHandle = publicBusHighPriority;
+        else
+            serviceHandle = privateBusHighPriority;
+
+    } else {
+/*  else if (callerId && activeAppId && strncmp(callerId, activeAppId, strlen(activeAppId)) == 0) {
+
+
+        if (!usePrivateBus)
+            serviceHandle = publicBusMediumPriority;
+        else
+            serviceHandle = privateBusMediumPriority;
+    }
+*/
+        if (!usePrivateBus)
+            serviceHandle = publicBus;
+        else
+            serviceHandle = privateBus;
+    }
+
+    if (!inListener)
+        retVal = LSCallFromApplication(serviceHandle, uri, payload, callerId, 0, 0, &token, &lserror);
+    else {
+        retVal = LSCallFromApplication(serviceHandle, uri, payload, callerId, message_filter, inListener, &token, &lserror);
+        if (retVal) {
+            inListener->listenerToken = token;
+            inListener->sh = serviceHandle;
+        }
+    }
+
+    if (!retVal) {
+        g_warning("LSCallFromApplication ERROR %d: %s (%s @ %s:%d)",
+            lserror.error_code, lserror.message,
+            lserror.func, lserror.file, lserror.line);
+        LSErrorFree(&lserror);
+        token = 0;
+        goto error;
+    }
+
+error:
+    return token;
+}
+
+/**
+ * @brief Terminates a call causing any subscription for responses to end.
+ *        This is also called by garbage collector's collect()
+ *        when no more references to inListener exist.
+ *
+ * @param  inListener
+ */
+void LunaServiceManager::cancel(LunaServiceManagerListener* inListener)
+{
+    bool retVal;
+    LSError lserror;
+
+    if (!inListener || !inListener->listenerToken)
+        return;
+
+    DEBUG("LunaServiceManager: canceling call inListener %p", inListener);
+
+    LSErrorInit(&lserror);
+
+    if (!LSCallCancel(inListener->sh, inListener->listenerToken, &lserror)) {
+        g_warning("LSCallCancel ERROR %d: %s (%s @ %s:%d)",
+            lserror.error_code, lserror.message,
+            lserror.func, lserror.file, lserror.line);
+        LSErrorFree(&lserror);
+    }
+
+    // set the token to zero to indicate we have been canceled
+    inListener->listenerToken = 0;
+}
+};
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/LunaServiceMgr.h b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/LunaServiceMgr.h
new file mode 100644
index 0000000..d167f70
--- /dev/null
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/LunaServiceMgr.h
@@ -0,0 +1,53 @@
+
+#ifndef LunaServiceMgr_h
+#define LunaServiceMgr_h
+
+#include <lunaservice.h>
+
+namespace blink {
+
+struct LunaServiceManagerListener {
+        LunaServiceManagerListener() : listenerToken(LSMESSAGE_TOKEN_INVALID), sh(0) { }
+        virtual ~LunaServiceManagerListener() { }
+        virtual void serviceResponse(const char* body) = 0;
+        LSMessageToken listenerToken;
+        LSHandle* sh;
+};
+
+
+//
+//  LunaServiceManager
+//
+// This class is a singleton which handles all the client requests
+// for a WebKit instance.
+
+class LunaServiceManager {
+    public:
+        ~LunaServiceManager();
+
+        static LunaServiceManager* instance();
+        unsigned long call(const char* uri, const char* payload, LunaServiceManagerListener*, const char* callerId, bool usePrivateBus = false);
+        void cancel(LunaServiceManagerListener*);
+
+    private:
+        bool init();
+        LunaServiceManager();
+
+        LSHandle* publicBus;
+        LSHandle* privateBus;
+        LSPalmService* palmServiceHandle;
+
+        // The Medium Priority bus is used for the active app
+        LSHandle* publicBusMediumPriority;
+        LSHandle* privateBusMediumPriority;
+        LSPalmService* palmServiceHandleMediumPriority;
+
+        // The High Priority bus is used only for the Phone app
+        LSHandle* publicBusHighPriority;
+        LSHandle* privateBusHighPriority;
+        LSPalmService* palmServiceHandleHighPriority;
+};
+
+}
+
+#endif
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.cpp b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.cpp
new file mode 100644
index 0000000..22c160e
--- /dev/null
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.cpp
@@ -0,0 +1,300 @@
+#include "config.h"
+#include "PalmServiceBridge.h"
+#include "Logging.h"
+
+#include "core/dom/Document.h"
+#include "core/events/Event.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/frame/Frame.h"
+#include "platform/Logging.h"
+#include "core/page/Page.h"
+#include "core/frame/Settings.h"
+#include <wtf/text/WTFString.h>
+#include "bindings/core/v8/ScriptSourceCode.h"
+#include "bindings/core/v8/ScriptController.h"
+#include "bindings/core/v8/ScriptState.h"
+#include "bindings/core/v8/V8Binding.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include <wtf/RefCountedLeakCounter.h>
+
+#include <map>
+#include <set>
+
+bool LoggingInitialized = false;
+PmLogContext LogContext;
+
+namespace blink {
+
+typedef std::set<PalmServiceBridge*> ServicesSet;
+typedef std::map<Document*, ServicesSet*> ServicesSetMap;
+
+#ifndef NDEBUG
+static WTF::RefCountedLeakCounter serviceBridgeCounter("PalmServiceBridge");
+#endif
+
+static ServicesSetMap* servicesByDocument()
+{
+    static ServicesSetMap map;
+    return &map;
+}
+
+int PalmServiceBridge::numHandlesForUrl(const char* appId)
+{
+    for (ServicesSetMap::iterator setIt = servicesByDocument()->begin(); setIt != servicesByDocument()->end(); ++setIt) {
+        if (!strcmp(appId, setIt->first->url().string().utf8().data()))
+            return setIt->second->size();
+    }
+
+    return 0;
+}
+
+void PalmServiceBridge::handlesForUrl(const char* appId, std::list<PalmServiceBridge*>& outHandles)
+{
+    outHandles.clear();
+    for (ServicesSetMap::iterator setIt = servicesByDocument()->begin(); setIt != servicesByDocument()->end(); ++setIt) {
+        if (!strcmp(appId, setIt->first->url().string().utf8().data())) {
+            ServicesSet* set = setIt->second;
+
+            for (ServicesSet::iterator s = set->begin(); s != set->end(); ++s)
+                outHandles.push_back(*s);
+
+            return;
+        }
+    }
+}
+
+static void addToServicesByDocument(Document* doc, PalmServiceBridge* svc)
+{
+    if (!doc || !svc)
+        return;
+
+    ServicesSet* set = 0;
+    ServicesSetMap::iterator it = servicesByDocument()->find(doc);
+    if (it == servicesByDocument()->end()) {
+        set = new ServicesSet();
+        (*servicesByDocument())[doc] = set;
+    } else
+        set = it->second;
+
+    set->insert(svc);
+}
+
+static void removeFromServicesByDocument(Document* doc, PalmServiceBridge* svc)
+{
+    if (!doc || !svc)
+        return;
+
+    ServicesSetMap::iterator it = servicesByDocument()->find(doc);
+    if (it == servicesByDocument()->end())
+        return;
+
+    ServicesSet* set = it->second;
+    if (!set)
+        return;
+
+    set->erase(svc);
+    if (!set->size()) {
+        // remove from the hash map
+        delete set;
+        servicesByDocument()->erase(it);
+    }
+}
+
+PalmServiceBridge::PalmServiceBridge(ExecutionContext* context, bool subscribe)
+    : ActiveDOMObject(context),
+      m_canceled(false),
+      m_subscribed(subscribe),
+      m_inServiceCallback(false),
+      m_identifier(0),
+      m_isPrivileged(false)
+{
+    if (!LoggingInitialized) {
+        PmLogGetContext("QtWebEngineProcess", &LogContext);
+        LoggingInitialized = true;
+    }
+
+    addToServicesByDocument(document(), this);
+
+#ifndef NDEBUG
+    serviceBridgeCounter.increment();
+#endif
+    Frame *frame = document()->frame();
+    Settings* settings = document()->settings();
+    if (settings != 0 && document()->page()->mainFrame() == frame) {
+        m_identifier = strdup(settings->luneosAppIdentifier().utf8().data());
+    }
+    else {
+        v8::Local<v8::Value> identifier;
+
+        identifier = document()->frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode("PalmSystem && PalmSystem.getIdentifierForFrame(window.frameElement.id, window.frameElement.src)"));
+
+        // Failure is reported as a null string.
+        if (identifier.IsEmpty() || !identifier->IsString())
+            m_identifier = strdup("dummy_identifier 0");
+        else
+            m_identifier = strdup(toCoreString(v8::Handle<v8::String>::Cast(identifier)).utf8().data());
+    }
+
+    if (settings != 0)
+        m_isPrivileged = settings->luneosPriviledged();
+
+    DEBUG("PalmServiceBridge[%p]: created (subscribe %d identifier %s privileged %d)",
+          this, subscribe, m_identifier, m_isPrivileged);
+}
+
+bool PalmServiceBridge::init(Document* d, bool subscribe)
+{
+    m_subscribed = subscribe;
+
+    DEBUG("PalmServiceBridge[%p]: initialized (subscribe %d)", this, subscribe);
+
+    return true;
+}
+
+PalmServiceBridge::~PalmServiceBridge()
+{
+    DEBUG("PalmServiceBridge[%p]: destroying (identifier %s privileged %d subscribed %d)",
+          this, m_identifier, m_isPrivileged, m_subscribed);
+
+    cancel();
+
+    if (m_scriptState)
+        m_scriptState->clear();
+
+    if (executionContext() && document())
+        removeFromServicesByDocument(document(), this);
+
+    if (m_identifier)
+        free(m_identifier);
+
+#ifndef NDEBUG
+    serviceBridgeCounter.decrement();
+#endif
+}
+
+void PalmServiceBridge::detachServices(Document* doc)
+{
+    ServicesSetMap::iterator it = servicesByDocument()->find(doc);
+    if (it == servicesByDocument()->end())
+        return;
+
+    ServicesSet* services = it->second;
+    servicesByDocument()->erase(it);
+
+    if (services) {
+        while (services->size()) {
+            ServicesSet::iterator sit = services->begin();
+            (*sit)->cancel();
+            services->erase(sit);
+        }
+        delete services;
+    }
+
+}
+
+void PalmServiceBridge::cancelServices(Document* doc)
+{
+    ServicesSetMap::iterator it = servicesByDocument()->find(doc);
+    if (it == servicesByDocument()->end())
+        return;
+
+    ServicesSet* services = it->second;
+
+    if (services) {
+        for (ServicesSet::iterator sit = services->begin(); sit != services->end(); ++sit) {
+            PalmServiceBridge* br = *sit;
+            br->cancel();
+        }
+    }
+}
+
+String PalmServiceBridge::version()
+{
+    return String("1.1");
+}
+
+int PalmServiceBridge::token()
+{
+    return (int)listenerToken;
+}
+
+int PalmServiceBridge::call(const String& uri, const String& payload, ExceptionState& exceptionState)
+{
+    DEBUG("PalmServiceBridge[%p]: calling on uri %s payload %s (identifier %s privileged %d subscribed %d)",
+          this, uri.utf8().data(), payload.utf8().data(), m_identifier, m_isPrivileged, m_subscribed);
+
+    LunaServiceManager::instance()->call(uri.utf8().data(), payload.utf8().data(), this, m_identifier, m_isPrivileged);
+    if (LSMESSAGE_TOKEN_INVALID == listenerToken) {
+        exceptionState.throwDOMException(EncodingError, "The LS2 call returned an invalid token.");
+        cancel();
+    }
+
+    return (int)listenerToken;
+}
+
+void PalmServiceBridge::serviceResponse(const char* body)
+{
+    if (m_canceled || !document() || !m_scriptState)
+        return;
+
+    if (!body)
+        body = "";
+
+    DEBUG("PalmServiceBridge[%p]: got service response %s (identifier %s privileged %d subscribed %d)",
+          this, body, m_identifier, m_isPrivileged, m_subscribed);
+
+    /* here we need to get the v8::Function associated with our v8 object */
+    ScriptState *pScriptState = m_scriptState->get();
+    v8::Isolate *isolateCurrent = pScriptState->isolate();
+    v8::HandleScope handleScope(isolateCurrent);
+    v8::Handle<v8::Value> cbValue = m_callbackScriptValue.v8ValueUnsafe();
+    if (!cbValue.IsEmpty() && cbValue->IsFunction()) {
+        v8::Handle<v8::Function> cbFctV8 = cbValue.As<v8::Function>();
+        v8::Handle<v8::Value> argv[1];
+        argv[0] = v8::String::NewFromUtf8(isolateCurrent, body);
+
+        cbFctV8->Call(pScriptState->context()->Global(), 1, argv);
+    }
+
+   // document()->updateStyleIfNeeded();
+}
+
+void PalmServiceBridge::cancel()
+{
+    if (m_canceled)
+        return;
+
+    m_canceled = true;
+    if (listenerToken) {
+        DEBUG("PalmServiceBridge[%p]: canceling current call (identifier %s privileged %d subscribed %d)",
+            this, m_identifier, m_isPrivileged, m_subscribed);
+
+        LunaServiceManager::instance()->cancel(this);
+    }
+}
+
+void PalmServiceBridge::stop()
+{
+    DEBUG("PalmServiceBridge[%p]: stopping ... (identifier %s privileged %d subscribed %d)",
+        this, m_identifier, m_isPrivileged, m_subscribed);
+
+    cancel();
+}
+
+bool PalmServiceBridge::canSuspend() const
+{
+    return false;
+}
+
+void PalmServiceBridge::contextDestroyed()
+{
+    ActiveDOMObject::contextDestroyed();
+}
+
+Document* PalmServiceBridge::document() const
+{
+    ASSERT(executionContext()->isDocument());
+    return static_cast<Document*>(executionContext());
+}
+
+} // namespace blink
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.h b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.h
new file mode 100644
index 0000000..4984a09
--- /dev/null
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.h
@@ -0,0 +1,90 @@
+#ifndef PalmServiceBridge_h
+#define PalmServiceBridge_h
+
+#include "core/dom/ActiveDOMObject.h"
+#include "core/dom/StringCallback.h"
+#include "bindings/core/v8/ScriptWrappable.h"
+#include "bindings/core/v8/V8Binding.h"
+#include "bindings/core/v8/ScriptValue.h"
+#include "core/events/Event.h"
+#include "core/events/EventListener.h"
+#include "core/events/EventTarget.h"
+#include "LunaServiceMgr.h"
+#include <wtf/OwnPtr.h>
+#include "wtf/PassOwnPtr.h"
+
+// #include <heap/Strong.h>
+// #include <heap/StrongInlines.h>
+
+#include <glib.h>
+#include <list>
+
+
+namespace blink {
+
+class Document;
+
+
+class PalmServiceBridge : public RefCounted<PalmServiceBridge>,
+                          public LunaServiceManagerListener,
+                          public ActiveDOMObject, public ScriptWrappable {
+    DEFINE_WRAPPERTYPEINFO();
+    public:
+        static PassRefPtr<PalmServiceBridge> create(ExecutionContext* context, bool subscribe = false)
+        {
+            return adoptRef(new PalmServiceBridge(context, subscribe));
+        }
+
+        bool init(Document*, bool subscribed = false);
+        ~PalmServiceBridge();
+
+        static int numHandlesForUrl(const char* appId);
+        static void handlesForUrl(const char* appId, std::list<PalmServiceBridge*>& outHandles);
+
+        virtual PalmServiceBridge* toPalmServiceBridge() { return this; }
+
+        static void detachServices(Document*);
+        static void cancelServices(Document*);
+
+        String version();
+
+        int token();
+
+        int call(const String& uri, const String& payload, ExceptionState&);
+        void cancel();
+
+        void setOnservicecallback(ScriptValue& cbScriptValue) {
+            m_callbackScriptValue = cbScriptValue;
+            if (m_scriptState) {
+                m_scriptState->clear();
+            }
+            m_scriptState = adoptPtr(new ScriptStateProtectingContext(cbScriptValue.scriptState()));
+        }
+        ScriptValue onservicecallback() const { return m_callbackScriptValue; }
+
+        // callback from LunaServiceManagerListener
+        virtual void serviceResponse(const char* body);
+
+        Document* document() const;
+
+        // ActiveDOMObject:
+        virtual void contextDestroyed();
+        virtual bool canSuspend() const;
+        virtual void stop();
+
+    private:
+        ScriptValue m_callbackScriptValue;
+        OwnPtr<ScriptStateProtectingContext> m_scriptState;
+
+        bool m_canceled;
+        bool m_subscribed;
+        bool m_inServiceCallback;
+        char *m_identifier;
+        bool m_isPrivileged;
+
+        PalmServiceBridge(ExecutionContext*, bool);
+        PalmServiceBridge();
+};
+}
+
+#endif
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.idl b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.idl
new file mode 100644
index 0000000..43e1fdd
--- /dev/null
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/modules/webos/PalmServiceBridge.idl
@@ -0,0 +1,14 @@
+callback ServiceCallback = void (DOMString message);
+
+[
+    Exposed=(Window,Worker),
+    ActiveDOMObject,
+    Constructor,
+    ConstructorCallWith=ExecutionContext
+] interface PalmServiceBridge {
+
+    [RaisesException] unsigned long call(DOMString method, DOMString url);
+    void cancel();
+
+    attribute ServiceCallback onservicecallback;
+};
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/web/WebSettingsImpl.cpp b/src/3rdparty/chromium/third_party/WebKit/Source/web/WebSettingsImpl.cpp
index 65d5d91..c3afa5b 100644
--- a/src/3rdparty/chromium/third_party/WebKit/Source/web/WebSettingsImpl.cpp
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/web/WebSettingsImpl.cpp
@@ -714,4 +714,20 @@ void WebSettingsImpl::setExpensiveBackgroundThrottlingMaxDelay(float maxDelay) {
   m_expensiveBackgroundThrottlingMaxDelay = maxDelay;
 }
 
+// LuneOS specific settings
+void WebSettingsImpl::setLuneosAppIdentifier(const WebString& appId)
+{
+    m_settings->setLuneosAppIdentifier(appId);
+}
+
+void WebSettingsImpl::setLuneosPriviledged(bool enabled)
+{
+    m_settings->setLuneosPriviledged(enabled);
+}
+
+void WebSettingsImpl::setPalmServiceBridgeEnabled(bool enabled)
+{
+    m_settings->setPalmServiceBridgeEnabled(enabled);
+}
+
 }  // namespace blink
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/web/WebSettingsImpl.h b/src/3rdparty/chromium/third_party/WebKit/Source/web/WebSettingsImpl.h
index dab96e4..f493abe 100644
--- a/src/3rdparty/chromium/third_party/WebKit/Source/web/WebSettingsImpl.h
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/web/WebSettingsImpl.h
@@ -118,6 +118,8 @@ class WEB_EXPORT WebSettingsImpl final
   void setShouldReuseGlobalForUnownedMainFrame(bool) override;
   void setProgressBarCompletion(ProgressBarCompletion) override;
   void setLocalStorageEnabled(bool) override;
+  void setLuneosAppIdentifier(const WebString&) override;
+  void setLuneosPriviledged(bool) override;
   void setMainFrameClipsContent(bool) override;
   void setMainFrameResizesAreOrientationChanges(bool) override;
   void setMaxTouchPoints(int) override;
@@ -130,6 +132,7 @@ class WEB_EXPORT WebSettingsImpl final
   void setMockScrollbarsEnabled(bool) override;
   void setHideScrollbars(bool) override;
   void setOfflineWebApplicationCacheEnabled(bool) override;
+  void setPalmServiceBridgeEnabled(bool) override;
   void setPassiveEventListenerDefault(PassiveEventListenerDefault) override;
   void setPasswordEchoDurationInSeconds(double) override;
   void setPasswordEchoEnabled(bool) override;
diff --git a/src/3rdparty/chromium/third_party/WebKit/public/web/WebSettings.h b/src/3rdparty/chromium/third_party/WebKit/public/web/WebSettings.h
index 124be31..769a64c 100644
--- a/src/3rdparty/chromium/third_party/WebKit/public/web/WebSettings.h
+++ b/src/3rdparty/chromium/third_party/WebKit/public/web/WebSettings.h
@@ -197,6 +197,8 @@ class WebSettings {
   virtual void setShouldReuseGlobalForUnownedMainFrame(bool) = 0;
   virtual void setProgressBarCompletion(ProgressBarCompletion) = 0;
   virtual void setLocalStorageEnabled(bool) = 0;
+  virtual void setLuneosAppIdentifier(const WebString&) = 0;
+  virtual void setLuneosPriviledged(bool) = 0;
   virtual void setMainFrameClipsContent(bool) = 0;
   virtual void setMainFrameResizesAreOrientationChanges(bool) = 0;
   virtual void setMaxTouchPoints(int) = 0;
@@ -209,6 +211,7 @@ class WebSettings {
   virtual void setMockScrollbarsEnabled(bool) = 0;
   virtual void setHideScrollbars(bool) = 0;
   virtual void setOfflineWebApplicationCacheEnabled(bool) = 0;
+  virtual void setPalmServiceBridgeEnabled(bool) = 0;
   virtual void setPassiveEventListenerDefault(PassiveEventListenerDefault) = 0;
   virtual void setPasswordEchoDurationInSeconds(double) = 0;
   virtual void setPasswordEchoEnabled(bool) = 0;
-- 
2.7.4

