Bug 1298810: Pass Port object to listeners on native messaging ports. r=rpl
authorKris Maglione <maglione.k@gmail.com>
Mon, 29 Aug 2016 13:12:16 -0700
changeset 312056 d981eb1bef3c5815a269a1402b13083a07fcee28
parent 312055 21ec43d33e0c2ac8049355c506282ce076625578
child 312057 586deb42b345e257bc5ea51556db4010b891f1eb
push id81274
push usermaglione.k@gmail.com
push dateWed, 31 Aug 2016 18:27:21 +0000
treeherdermozilla-inbound@d981eb1bef3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrpl
bugs1298810
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1298810: Pass Port object to listeners on native messaging ports. r=rpl MozReview-Commit-ID: 1saUOB1jyE1
toolkit/components/extensions/NativeMessaging.jsm
toolkit/components/extensions/test/xpcshell/test_ext_native_messaging.js
--- a/toolkit/components/extensions/NativeMessaging.jsm
+++ b/toolkit/components/extensions/NativeMessaging.jsm
@@ -372,52 +372,55 @@ this.NativeApp = class extends EventEmit
   }
 
   // Called from Context when the extension is shut down.
   close() {
     this._cleanup();
   }
 
   portAPI() {
-    let api = {
+    let port = {
       name: this.name,
 
       disconnect: () => {
         if (this._isDisconnected) {
           throw new this.context.cloneScope.Error("Attempt to disconnect an already disconnected port");
         }
         this._cleanup();
       },
 
       postMessage: msg => {
         this.send(msg);
       },
 
       onDisconnect: new ExtensionUtils.SingletonEventManager(this.context, "native.onDisconnect", fire => {
         let listener = what => {
-          this.context.runSafe(fire);
+          this.context.runSafeWithoutClone(fire, port);
         };
         this.on("disconnect", listener);
         return () => {
           this.off("disconnect", listener);
         };
       }).api(),
 
       onMessage: new ExtensionUtils.SingletonEventManager(this.context, "native.onMessage", fire => {
         let listener = (what, msg) => {
-          this.context.runSafe(fire, msg);
+          msg = Cu.cloneInto(msg, this.context.cloneScope);
+          this.context.runSafeWithoutClone(fire, msg, port);
         };
         this.on("message", listener);
         return () => {
           this.off("message", listener);
         };
       }).api(),
     };
 
-    return Cu.cloneInto(api, this.context.cloneScope, {cloneFunctions: true});
+    port = Cu.cloneInto(port, this.context.cloneScope, {cloneFunctions: true});
+
+    return port;
   }
 
   sendMessage(msg) {
     let responsePromise = new Promise((resolve, reject) => {
       this.on("message", (what, msg) => { resolve(msg); });
       this.on("disconnect", (what, err) => { reject(err); });
     });
 
--- a/toolkit/components/extensions/test/xpcshell/test_ext_native_messaging.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_native_messaging.js
@@ -211,19 +211,24 @@ add_task(function* test_sendNativeMessag
 
   yield extension.unload();
 });
 
 // Test calling Port.disconnect()
 add_task(function* test_disconnect() {
   function background() {
     let port = browser.runtime.connectNative("echo");
-    port.onMessage.addListener(msg => {
+    port.onMessage.addListener((msg, msgPort) => {
+      browser.test.assertEq(port, msgPort, "onMessage handler should receive the port as the second argument");
       browser.test.sendMessage("message", msg);
     });
+    port.onDisconnect.addListener(msgPort => {
+      browser.test.assertEq(port, msgPort, "onDisconnect handler should receive the port as the second argument");
+      browser.test.sendMessage("disconnected");
+    });
     browser.test.onMessage.addListener((what, payload) => {
       if (what == "send") {
         if (payload._json) {
           let json = payload._json;
           payload.toJSON = () => json;
           delete payload._json;
         }
         port.postMessage(payload);
@@ -259,16 +264,18 @@ add_task(function* test_disconnect() {
 
   let procCount = yield getSubprocessCount();
   equal(procCount, 1, "subprocess is running");
 
   extension.sendMessage("disconnect");
   response = yield extension.awaitMessage("disconnect-result");
   equal(response.success, true, "disconnect succeeded");
 
+  yield extension.awaitMessage("disconnected");
+
   do_print("waiting for subprocess to exit");
   yield waitForSubprocessExit();
   procCount = yield getSubprocessCount();
   equal(procCount, 0, "subprocess is no longer running");
 
   extension.sendMessage("disconnect");
   response = yield extension.awaitMessage("disconnect-result");
   equal(response.success, false, "second call to disconnect failed");