Add transfer map argument to Intent constructor
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Apr 2012 01:15:30 +0000 (01:15 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Apr 2012 01:15:30 +0000 (01:15 +0000)
http://dvcs.w3.org/hg/web-intents/raw-file/tip/spec/Overview.html
This adds the ability to pass transferables (i.e. MessagePorts)
through web intents, and puts the calling convention in line
with the Web Messaging spec:
http://dev.w3.org/html5/postmsg/

Implementation in chromium API follows the port-passing method
of PlatformMessagePortChannel.

https://bugs.webkit.org/show_bug.cgi?id=80200

Patch by Greg Billock <gbillock@google.com> on 2012-04-10
Reviewed by Adam Barth.

* Modules/intents/Intent.cpp:
(WebCore::Intent::create):
* Modules/intents/Intent.idl:
* WebCore.gypi:
* bindings/v8/custom/V8IntentCustom.cpp: Added.
(WebCore):
(WebCore::V8Intent::constructorCallback):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@113799 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/webintents/web-intents-invoke-port-expected.txt [new file with mode: 0644]
LayoutTests/webintents/web-intents-invoke-port.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/intents/Intent.cpp
Source/WebCore/Modules/intents/Intent.h
Source/WebCore/Modules/intents/Intent.idl
Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
Source/WebCore/bindings/scripts/test/V8/V8TestSerializedScriptValueInterface.cpp
Source/WebKit/chromium/public/WebIntent.h
Source/WebKit/chromium/src/WebIntent.cpp
Tools/DumpRenderTree/chromium/WebViewHost.cpp

diff --git a/LayoutTests/webintents/web-intents-invoke-port-expected.txt b/LayoutTests/webintents/web-intents-invoke-port-expected.txt
new file mode 100644 (file)
index 0000000..d1b3a92
--- /dev/null
@@ -0,0 +1,7 @@
+Received Web Intent: action=action1 type=mime/type1
+Have 1 ports
+PASS successfullyParsed is true
+
+TEST COMPLETE
+* sent intent
+
diff --git a/LayoutTests/webintents/web-intents-invoke-port.html b/LayoutTests/webintents/web-intents-invoke-port.html
new file mode 100644 (file)
index 0000000..8b72b1a
--- /dev/null
@@ -0,0 +1,34 @@
+<html>
+  <head>
+    <script src="../fast/js/resources/js-test-pre.js"></script>
+    <script src="resources/web-intents-testing.js"></script>
+    <script>
+      var channel = new MessageChannel();
+      channel.port2.onMessage = function(e) {
+        debug("* got message");
+      };
+
+      function buttonClicked() {
+        try {
+          var intent1 = new WebKitIntent("action1", "mime/type1", channel.port1, "not a port");
+          testFailed("Should have thrown TypeError");
+        } catch (e) {
+          if (!(e instanceof TypeError)) testFailed("Should throw type error on non-port arg");
+        }
+        try {
+          var intent1 = new WebKitIntent("action1", "mime/type1", channel.port1, ["not a port"]);
+          testFailed("Should have thrown TypeError");
+        } catch (e) {
+          if (!(e instanceof TypeError)) testFailed("Should throw type error on non-port arg");
+        }
+
+        navigator.webkitStartActivity(new WebKitIntent("action1", "mime/type1", channel.port1, [channel.port1]));
+        debug("* sent intent");
+      }
+    </script>
+  </head>
+<body onload="simulateButtonPress()">
+<input type="button" id="button" value="Start Web Intent" onmouseup="buttonClicked()">
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index 5a92c71..f176583 100644 (file)
@@ -1,3 +1,27 @@
+2012-04-10  Greg Billock  <gbillock@google.com>
+
+        Add transfer map argument to Intent constructor
+        http://dvcs.w3.org/hg/web-intents/raw-file/tip/spec/Overview.html
+        This adds the ability to pass transferables (i.e. MessagePorts)
+        through web intents, and puts the calling convention in line
+        with the Web Messaging spec:
+        http://dev.w3.org/html5/postmsg/
+
+        Implementation in chromium API follows the port-passing method
+        of PlatformMessagePortChannel.
+
+        https://bugs.webkit.org/show_bug.cgi?id=80200
+
+        Reviewed by Adam Barth.
+
+        * Modules/intents/Intent.cpp:
+        (WebCore::Intent::create):
+        * Modules/intents/Intent.idl:
+        * WebCore.gypi:
+        * bindings/v8/custom/V8IntentCustom.cpp: Added.
+        (WebCore):
+        (WebCore::V8Intent::constructorCallback):
+
 2012-04-10  Patrick Gansterer  <paroga@webkit.org>
 
         Cleanup wtf/Platform.h and config.h files
index 60a3248..053d429 100644 (file)
@@ -32,6 +32,7 @@
 #if ENABLE(WEB_INTENTS)
 
 #include "ExceptionCode.h"
+#include "MessagePort.h"
 #include "SerializedScriptValue.h"
 
 namespace WebCore {
@@ -50,12 +51,39 @@ PassRefPtr<Intent> Intent::create(const String& action, const String& type, Pass
     return adoptRef(new Intent(action, type, data));
 }
 
+PassRefPtr<Intent> Intent::create(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, const MessagePortArray& ports, ExceptionCode& ec)
+{
+    if (action.isEmpty()) {
+        ec = SYNTAX_ERR;
+        return 0;
+    }
+    if (type.isEmpty()) {
+        ec = SYNTAX_ERR;
+        return 0;
+    }
+
+    OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(&ports, ec);
+
+    return adoptRef(new Intent(action, type, data, channels.release()));
+}
+
 Intent::Intent(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data)
     : m_action(action)
     , m_type(type)
 {
     if (data)
-        m_data = SerializedScriptValue::createFromWire(data->toWireString());
+        m_data = data;
+    else
+        m_data = SerializedScriptValue::nullValue();
+}
+
+Intent::Intent(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, PassOwnPtr<MessagePortChannelArray> ports)
+    : m_action(action)
+    , m_type(type)
+    , m_ports(ports)
+{
+    if (data)
+        m_data = data;
     else
         m_data = SerializedScriptValue::nullValue();
 }
@@ -75,6 +103,11 @@ SerializedScriptValue* Intent::data() const
     return m_data.get();
 }
 
+MessagePortChannelArray* Intent::messagePorts() const
+{
+    return m_ports.get();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEB_INTENTS)
index 96bebd6..33ef69e 100644 (file)
@@ -31,6 +31,8 @@
 
 #if ENABLE(WEB_INTENTS)
 
+#include "MessagePort.h"
+#include "MessagePortChannel.h"
 #include <wtf/Forward.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -46,6 +48,7 @@ typedef int ExceptionCode;
 class Intent : public RefCounted<Intent> {
 public:
     static PassRefPtr<Intent> create(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, ExceptionCode&);
+    static PassRefPtr<Intent> create(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, const MessagePortArray& ports, ExceptionCode&);
 
     const String& action() const;
     const String& type() const;
@@ -54,12 +57,16 @@ public:
     int identifier() const;
     void setIdentifier(int);
 
+    MessagePortChannelArray* messagePorts() const;
+
 private:
     Intent(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data);
+    Intent(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, PassOwnPtr<MessagePortChannelArray> ports);
 
     String m_action;
     String m_type;
     RefPtr<SerializedScriptValue> m_data;
+    OwnPtr<MessagePortChannelArray> m_ports;
 };
 
 } // namespace WebCore
index b3e2369..ef08250 100644 (file)
@@ -26,7 +26,7 @@
 module window {
   interface [
       Conditional=WEB_INTENTS,
-      Constructor(in DOMString action, in DOMString type, in [Optional=DefaultIsNullString] SerializedScriptValue data),
+      Constructor(in DOMString action, in DOMString type, in [Optional=DefaultIsNullString, TransferList=transferList] SerializedScriptValue data, in [Optional=DefaultIsUndefined] Array transferList),
       ConstructorRaisesException
   ] Intent {
         readonly attribute DOMString action;
index dc50502..ddd1081 100644 (file)
@@ -1601,7 +1601,7 @@ sub GenerateParametersCheck
                     die "IDL error: TransferList refers to a nonexistent argument";
                 }
 
-                AddToImplIncludes("ArrayBuffer.h");
+                AddToImplIncludes("wtf/ArrayBuffer.h");
                 AddToImplIncludes("MessagePort.h");
                 $TransferListName = ucfirst($transferListName);
                 $parameterCheckString .= "    MessagePortArray messagePortArray$TransferListName;\n";
index 22fe288..bd30b62 100644 (file)
@@ -23,7 +23,6 @@
 
 #if ENABLE(Condition1) || ENABLE(Condition2)
 
-#include "ArrayBuffer.h"
 #include "ExceptionCode.h"
 #include "MessagePort.h"
 #include "RuntimeEnabledFeatures.h"
@@ -34,6 +33,7 @@
 #include "V8DOMWrapper.h"
 #include "V8IsolatedContext.h"
 #include "V8Proxy.h"
+#include <wtf/ArrayBuffer.h>
 #include <wtf/UnusedParam.h>
 
 namespace WebCore {
index d01098f..73a6213 100644 (file)
 #ifndef WebIntent_h
 #define WebIntent_h
 
+#include "WebMessagePortChannel.h"
 #include "platform/WebCommon.h"
 #include "platform/WebPrivatePtr.h"
 #include "platform/WebString.h"
+#include "platform/WebVector.h"
 
 namespace WebCore { class Intent; }
 
@@ -62,6 +64,9 @@ public:
     WEBKIT_EXPORT WebString type() const;
     WEBKIT_EXPORT WebString data() const;
 
+    // Caller takes ownership of the ports.
+    WEBKIT_EXPORT WebMessagePortChannelArray* messagePortChannelsRelease() const;
+
 #if WEBKIT_IMPLEMENTATION
     WebIntent(const WTF::PassRefPtr<WebCore::Intent>&);
 #endif
index 77d766d..8a7d6aa 100644 (file)
@@ -32,6 +32,7 @@
 #include "WebIntent.h"
 
 #include "Intent.h"
+#include "PlatformMessagePortChannel.h"
 #include "SerializedScriptValue.h"
 
 namespace WebKit {
@@ -102,4 +103,21 @@ WebString WebIntent::data() const
 #endif
 }
 
+WebMessagePortChannelArray* WebIntent::messagePortChannelsRelease() const
+{
+    // Note: see PlatformMessagePortChannel::postMessageToRemote.
+    WebMessagePortChannelArray* webChannels = 0;
+    WebCore::MessagePortChannelArray* messagePorts = m_private->messagePorts();
+    if (messagePorts) {
+        webChannels = new WebMessagePortChannelArray(messagePorts->size());
+        for (size_t i = 0; i < messagePorts->size(); ++i) {
+            WebCore::PlatformMessagePortChannel* platformChannel = messagePorts->at(i)->channel();
+            (*webChannels)[i] = platformChannel->webChannelRelease();
+            (*webChannels)[i]->setClient(0);
+        }
+    }
+
+    return webChannels;
+}
+
 } // namespace WebKit
index b3e9dda..b65e6b0 100644 (file)
@@ -1327,7 +1327,14 @@ void WebViewHost::dispatchIntent(WebFrame* source, const WebIntentRequest& reque
     printf("Received Web Intent: action=%s type=%s\n",
            request.intent().action().utf8().data(),
            request.intent().type().utf8().data());
+    WebMessagePortChannelArray* ports = request.intent().messagePortChannelsRelease();
     m_currentRequest = request;
+    if (ports) {
+        printf("Have %d ports\n", static_cast<int>(ports->size()));
+        for (size_t i = 0; i < ports->size(); ++i)
+            (*ports)[i]->destroy();
+        delete ports;
+    }
 }
 
 // Public functions -----------------------------------------------------------