From d096c7322cf2dde6f4aaa7f01700bf6483c99921 Mon Sep 17 00:00:00 2001 From: Yoshi Huang Date: Thu, 24 Jul 2014 12:16:02 +0800 Subject: [PATCH] Bug 1043186 - Part 1: Add a nsINfcPeerEventListener. r=dimi --- dom/nfc/nsNfc.js | 63 ++++++++++++++--------- dom/nfc/tests/marionette/test_nfc_peer.js | 3 +- dom/system/gonk/NfcContentHelper.js | 37 ++++++------- dom/system/gonk/nsINfcContentHelper.idl | 36 +++++++------ 4 files changed, 80 insertions(+), 59 deletions(-) diff --git a/dom/nfc/nsNfc.js b/dom/nfc/nsNfc.js index 2e39fabd997..a35c12d672e 100644 --- a/dom/nfc/nsNfc.js +++ b/dom/nfc/nsNfc.js @@ -136,6 +136,8 @@ function mozNfc() { } catch(e) { debug("No NFC support.") } + + this._nfcContentHelper.registerPeerEventListener(this); } mozNfc.prototype = { _nfcContentHelper: null, @@ -234,19 +236,47 @@ mozNfc.prototype = { }, registerTarget: function registerTarget(event) { - let self = this; let appId = this._window.document.nodePrincipal.appId; - this._nfcContentHelper.registerTargetForPeerEvent(this._window, appId, - event, function(evt, sessionToken) { - self.session = sessionToken; - self.firePeerEvent(evt, sessionToken); - }); + this._nfcContentHelper.registerTargetForPeerEvent(this._window, appId, event); }, unregisterTarget: function unregisterTarget(event) { let appId = this._window.document.nodePrincipal.appId; - this._nfcContentHelper.unregisterTargetForPeerEvent(this._window, - appId, event); + this._nfcContentHelper.unregisterTargetForPeerEvent(this._window, appId, event); + }, + + notifyPeerReady: function notifyPeerReady(sessionToken) { + if (this.hasDeadWrapper()) { + dump("this._window or this.__DOM_IMPL__ is a dead wrapper."); + return; + } + + this.session = sessionToken; + + debug("fire onpeerready sessionToken : " + sessionToken); + let detail = { + "detail":sessionToken + }; + let event = new this._window.CustomEvent("peerready", this._wrap(detail)); + this.__DOM_IMPL__.dispatchEvent(event); + }, + + notifyPeerLost: function notifyPeerLost(sessionToken) { + if (this.hasDeadWrapper()) { + dump("this._window or this.__DOM_IMPL__ is a dead wrapper."); + return; + } + + if (sessionToken != this.session) { + dump("Unpaired session for notifyPeerLost." + sessionToken); + return; + } + + this.session = null; + + debug("fire onpeerlost"); + let event = new this._window.Event("peerlost"); + this.__DOM_IMPL__.dispatchEvent(event); }, getEventType: function getEventType(evt) { @@ -268,24 +298,11 @@ mozNfc.prototype = { return Cu.isDeadWrapper(this._window) || Cu.isDeadWrapper(this.__DOM_IMPL__); }, - firePeerEvent: function firePeerEvent(evt, sessionToken) { - if (this.hasDeadWrapper()) { - dump("this._window or this.__DOM_IMPL__ is a dead wrapper."); - return; - } - - let peerEvent = (NFC_PEER_EVENT_READY === evt) ? "peerready" : "peerlost"; - let detail = { - "detail":sessionToken - }; - let event = new this._window.CustomEvent(peerEvent, this._wrap(detail)); - this.__DOM_IMPL__.dispatchEvent(event); - }, - classID: Components.ID("{6ff2b290-2573-11e3-8224-0800200c9a66}"), contractID: "@mozilla.org/navigatorNfc;1", QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, - Ci.nsIDOMGlobalPropertyInitializer]), + Ci.nsIDOMGlobalPropertyInitializer, + Ci.nsINfcPeerEventListener]), }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozNFCTag, MozNFCPeer, mozNfc]); diff --git a/dom/nfc/tests/marionette/test_nfc_peer.js b/dom/nfc/tests/marionette/test_nfc_peer.js index 1cb57b22b56..ce0f3052037 100644 --- a/dom/nfc/tests/marionette/test_nfc_peer.js +++ b/dom/nfc/tests/marionette/test_nfc_peer.js @@ -17,8 +17,9 @@ function peerReadyCb(evt) { NCI.deactivate(); } -function peerLostCb() { +function peerLostCb(evt) { log("peerLostCb called"); + ok(evt.detail === undefined, "evt.detail should be undefined"); ok(true); nfc.onpeerlost = null; toggleNFC(false).then(runNextTest); diff --git a/dom/system/gonk/NfcContentHelper.js b/dom/system/gonk/NfcContentHelper.js index d55839be592..03fb8a8beb5 100644 --- a/dom/system/gonk/NfcContentHelper.js +++ b/dom/system/gonk/NfcContentHelper.js @@ -80,10 +80,6 @@ function NfcContentHelper() { Services.obs.addObserver(this, "xpcom-shutdown", false); this._requestMap = []; - - // Maintains an array of PeerEvent related callbacks, mainly - // one for 'peerReady' and another for 'peerLost'. - this.peerEventsCallbackMap = {}; } NfcContentHelper.prototype = { @@ -100,7 +96,7 @@ NfcContentHelper.prototype = { }), _requestMap: null, - peerEventsCallbackMap: null, + peerEventListener: null, encodeNDEFRecords: function encodeNDEFRecords(records) { let encodedRecords = []; @@ -261,29 +257,29 @@ NfcContentHelper.prototype = { }); }, - registerTargetForPeerEvent: function registerTargetForPeerEvent(window, - appId, event, callback) { + registerPeerEventListener: function registerPeerEventListener(listener) { + this.peerEventListener = listener; + }, + + registerTargetForPeerEvent: + function registerTargetForPeerEvent(window, appId, event) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } - this.peerEventsCallbackMap[event] = callback; + cpmm.sendAsyncMessage("NFC:RegisterPeerTarget", { appId: appId, event: event }); }, - unregisterTargetForPeerEvent: function unregisterTargetForPeerEvent(window, - appId, event) { + unregisterTargetForPeerEvent: + function unregisterTargetForPeerEvent(window, appId, event) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } - let callback = this.peerEventsCallbackMap[event]; - if (callback != null) { - delete this.peerEventsCallbackMap[event]; - } cpmm.sendAsyncMessage("NFC:UnregisterPeerTarget", { appId: appId, @@ -427,12 +423,13 @@ NfcContentHelper.prototype = { } break; case "NFC:PeerEvent": - let callback = this.peerEventsCallbackMap[result.event]; - if (callback) { - callback.peerNotification(result.event, result.sessionToken); - } else { - debug("PeerEvent: No valid callback registered for the event " + - result.event); + switch (result.event) { + case NFC.NFC_PEER_EVENT_READY: + this.peerEventListener.notifyPeerReady(result.sessionToken); + break; + case NFC.NFC_PEER_EVENT_LOST: + this.peerEventListener.notifyPeerLost(result.sessionToken); + break; } break; } diff --git a/dom/system/gonk/nsINfcContentHelper.idl b/dom/system/gonk/nsINfcContentHelper.idl index a87d62d09d1..45a3384226e 100644 --- a/dom/system/gonk/nsINfcContentHelper.idl +++ b/dom/system/gonk/nsINfcContentHelper.idl @@ -7,24 +7,27 @@ interface nsIVariant; -[scriptable, function, uuid(26673d1a-4af4-470a-ba96-f1f54b1f2052)] -interface nsINfcPeerCallback : nsISupports +[scriptable, uuid(57fc2998-1058-4fd5-8dd9-0e303218d5fd)] +interface nsINfcPeerEventListener : nsISupports { /** - * Callback function used to notify NFC peer events. - * - * @param event - * An event indicating 'PeerReady' or 'PeerLost' - * One of NFC_EVENT_PEER_XXXX + * Callback function used to notify peerready. * * @param sessionToken * SessionToken received from Chrome process */ - void peerNotification(in unsigned long event, - in DOMString sessionToken); + void notifyPeerReady(in DOMString sessionToken); + + /** + * Callback function used to notify peerlost. + * + * @param sessionToken + * SessionToken received from Chrome process + */ + void notifyPeerLost(in DOMString sessionToken); }; -[scriptable, uuid(26e8123f-ba00-4708-ac77-d1902457168c)] +[scriptable, uuid(21559f98-526c-44c8-94fb-2095a112c47c)] interface nsINfcContentHelper : nsISupports { const long NFC_EVENT_PEER_READY = 0x01; @@ -61,6 +64,13 @@ interface nsINfcContentHelper : nsISupports in jsval blob, in DOMString sessionToken); + /** + * Register the peer event listener. + * + * @param listener An instance of the nsINfcPeerEventListener. + */ + void registerPeerEventListener(in nsINfcPeerEventListener listener); + /** * Register the given application id with Chrome process * @@ -72,14 +82,10 @@ interface nsINfcContentHelper : nsISupports * * @param event * Event to be registered. Either NFC_EVENT_PEER_READY or NFC_EVENT_PEER_LOST - * - * @param callback - * Callback that is used to notify upper layers whenever PeerEvents happen. */ void registerTargetForPeerEvent(in nsIDOMWindow window, in unsigned long appId, - in octet event, - in nsINfcPeerCallback callback); + in octet event); /** * Unregister the given application id with Chrome process *