Bug 1298810: Pass Port object to listeners on native messaging ports. r=rpl a=ritu
authorKris Maglione <maglione.k@gmail.com>
Mon, 29 Aug 2016 13:12:16 -0700
changeset 350076 fde69933d9cc084bd7bcc70d7304b8ca032b67d8
parent 350075 6ea5133aab19860080b3d8b2221c2d5b5c17a465
child 350077 b16b9d1eea136bba9d512610e79700192be4e646
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrpl, ritu
bugs1298810
milestone50.0a2
Bug 1298810: Pass Port object to listeners on native messaging ports. r=rpl a=ritu MozReview-Commit-ID: 1saUOB1jyE1
toolkit/components/extensions/NativeMessaging.jsm
toolkit/components/extensions/test/mochitest/test_chrome_ext_native_messaging.html
--- a/toolkit/components/extensions/NativeMessaging.jsm
+++ b/toolkit/components/extensions/NativeMessaging.jsm
@@ -370,52 +370,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/mochitest/test_chrome_ext_native_messaging.html
+++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_native_messaging.html
@@ -405,19 +405,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);
@@ -452,16 +457,18 @@ add_task(function* test_disconnect() {
 
   let procCount = yield getSubprocessCount();
   is(procCount, 1, "subprocess is running");
 
   extension.sendMessage("disconnect");
   response = yield extension.awaitMessage("disconnect-result");
   is(response.success, true, "disconnect succeeded");
 
+  yield extension.awaitMessage("disconnected");
+
   info("waiting for subprocess to exit");
   yield waitForSubprocessExit();
   procCount = yield getSubprocessCount();
   is(procCount, 0, "subprocess is no longer running");
 
   extension.sendMessage("disconnect");
   response = yield extension.awaitMessage("disconnect-result");
   is(response.success, false, "second call to disconnect failed");