michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* Copyright © 2013, Deutsche Telekom, Inc. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const DEBUG = false; michael@0: function debug(s) { michael@0: if (DEBUG) dump("-*- Nfc DOM: " + s + "\n"); michael@0: } michael@0: michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: Cu.import("resource://gre/modules/ObjectWrapper.jsm"); michael@0: michael@0: XPCOMUtils.defineLazyServiceGetter(this, michael@0: "appsService", michael@0: "@mozilla.org/AppsService;1", michael@0: "nsIAppsService"); michael@0: const NFC_PEER_EVENT_READY = 0x01; michael@0: const NFC_PEER_EVENT_LOST = 0x02; michael@0: michael@0: /** michael@0: * NFCTag michael@0: */ michael@0: function MozNFCTag() { michael@0: debug("In MozNFCTag Constructor"); michael@0: this._nfcContentHelper = Cc["@mozilla.org/nfc/content-helper;1"] michael@0: .getService(Ci.nsINfcContentHelper); michael@0: this.session = null; michael@0: michael@0: // Map WebIDL declared enum map names to integer michael@0: this._techTypesMap = []; michael@0: this._techTypesMap['NFC_A'] = 0; michael@0: this._techTypesMap['NFC_B'] = 1; michael@0: this._techTypesMap['NFC_ISO_DEP'] = 2; michael@0: this._techTypesMap['NFC_F'] = 3; michael@0: this._techTypesMap['NFC_V'] = 4; michael@0: this._techTypesMap['NDEF'] = 5; michael@0: this._techTypesMap['NDEF_FORMATABLE'] = 6; michael@0: this._techTypesMap['MIFARE_CLASSIC'] = 7; michael@0: this._techTypesMap['MIFARE_ULTRALIGHT'] = 8; michael@0: this._techTypesMap['NFC_BARCODE'] = 9; michael@0: this._techTypesMap['P2P'] = 10; michael@0: } michael@0: MozNFCTag.prototype = { michael@0: _nfcContentHelper: null, michael@0: _window: null, michael@0: michael@0: initialize: function(aWindow, aSessionToken) { michael@0: this._window = aWindow; michael@0: this.setSessionToken(aSessionToken); michael@0: }, michael@0: michael@0: // ChromeOnly interface michael@0: setSessionToken: function setSessionToken(aSessionToken) { michael@0: debug("Setting session token."); michael@0: this.session = aSessionToken; michael@0: // report to NFC worker: michael@0: this._nfcContentHelper.setSessionToken(aSessionToken); michael@0: }, michael@0: michael@0: _techTypesMap: null, michael@0: michael@0: // NFCTag interface: michael@0: getDetailsNDEF: function getDetailsNDEF() { michael@0: return this._nfcContentHelper.getDetailsNDEF(this._window, this.session); michael@0: }, michael@0: readNDEF: function readNDEF() { michael@0: return this._nfcContentHelper.readNDEF(this._window, this.session); michael@0: }, michael@0: writeNDEF: function writeNDEF(records) { michael@0: return this._nfcContentHelper.writeNDEF(this._window, records, this.session); michael@0: }, michael@0: makeReadOnlyNDEF: function makeReadOnlyNDEF() { michael@0: return this._nfcContentHelper.makeReadOnlyNDEF(this._window, this.session); michael@0: }, michael@0: connect: function connect(enum_tech_type) { michael@0: let int_tech_type = this._techTypesMap[enum_tech_type]; michael@0: return this._nfcContentHelper.connect(this._window, int_tech_type, this.session); michael@0: }, michael@0: close: function close() { michael@0: return this._nfcContentHelper.close(this._window, this.session); michael@0: }, michael@0: michael@0: classID: Components.ID("{4e1e2e90-3137-11e3-aa6e-0800200c9a66}"), michael@0: contractID: "@mozilla.org/nfc/NFCTag;1", michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, michael@0: Ci.nsIDOMGlobalPropertyInitializer]), michael@0: }; michael@0: michael@0: /** michael@0: * NFCPeer michael@0: */ michael@0: function MozNFCPeer() { michael@0: debug("In MozNFCPeer Constructor"); michael@0: this._nfcContentHelper = Cc["@mozilla.org/nfc/content-helper;1"] michael@0: .getService(Ci.nsINfcContentHelper); michael@0: this.session = null; michael@0: } michael@0: MozNFCPeer.prototype = { michael@0: _nfcContentHelper: null, michael@0: _window: null, michael@0: michael@0: initialize: function(aWindow, aSessionToken) { michael@0: this._window = aWindow; michael@0: this.setSessionToken(aSessionToken); michael@0: }, michael@0: michael@0: // ChromeOnly interface michael@0: setSessionToken: function setSessionToken(aSessionToken) { michael@0: debug("Setting session token."); michael@0: this.session = aSessionToken; michael@0: // report to NFC worker: michael@0: return this._nfcContentHelper.setSessionToken(aSessionToken); michael@0: }, michael@0: michael@0: // NFCPeer interface: michael@0: sendNDEF: function sendNDEF(records) { michael@0: // Just forward sendNDEF to writeNDEF michael@0: return this._nfcContentHelper.writeNDEF(this._window, records, this.session); michael@0: }, michael@0: michael@0: sendFile: function sendFile(blob) { michael@0: let data = { michael@0: "blob": blob michael@0: }; michael@0: return this._nfcContentHelper.sendFile(this._window, michael@0: Cu.cloneInto(data, this._window), michael@0: this.session); michael@0: }, michael@0: michael@0: classID: Components.ID("{c1b2bcf0-35eb-11e3-aa6e-0800200c9a66}"), michael@0: contractID: "@mozilla.org/nfc/NFCPeer;1", michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, michael@0: Ci.nsIDOMGlobalPropertyInitializer]), michael@0: }; michael@0: michael@0: /** michael@0: * Navigator NFC object michael@0: */ michael@0: function mozNfc() { michael@0: debug("In mozNfc Constructor"); michael@0: try { michael@0: this._nfcContentHelper = Cc["@mozilla.org/nfc/content-helper;1"] michael@0: .getService(Ci.nsINfcContentHelper); michael@0: } catch(e) { michael@0: debug("No NFC support.") michael@0: } michael@0: } michael@0: mozNfc.prototype = { michael@0: _nfcContentHelper: null, michael@0: _window: null, michael@0: _wrap: function _wrap(obj) { michael@0: return Cu.cloneInto(obj, this._window); michael@0: }, michael@0: michael@0: init: function init(aWindow) { michael@0: debug("mozNfc init called"); michael@0: this._window = aWindow; michael@0: }, michael@0: michael@0: // Only apps which have nfc-manager permission can call the following interfaces michael@0: // 'checkP2PRegistration' , 'notifyUserAcceptedP2P' , 'notifySendFileStatus', michael@0: // 'startPoll', 'stopPoll', and 'powerOff'. michael@0: checkP2PRegistration: function checkP2PRegistration(manifestUrl) { michael@0: // Get the AppID and pass it to ContentHelper michael@0: let appID = appsService.getAppLocalIdByManifestURL(manifestUrl); michael@0: return this._nfcContentHelper.checkP2PRegistration(this._window, appID); michael@0: }, michael@0: michael@0: notifyUserAcceptedP2P: function notifyUserAcceptedP2P(manifestUrl) { michael@0: let appID = appsService.getAppLocalIdByManifestURL(manifestUrl); michael@0: // Notify chrome process of user's acknowledgement michael@0: this._nfcContentHelper.notifyUserAcceptedP2P(this._window, appID); michael@0: }, michael@0: michael@0: notifySendFileStatus: function notifySendFileStatus(status, requestId) { michael@0: this._nfcContentHelper.notifySendFileStatus(this._window, michael@0: status, requestId); michael@0: }, michael@0: michael@0: startPoll: function startPoll() { michael@0: return this._nfcContentHelper.startPoll(this._window); michael@0: }, michael@0: michael@0: stopPoll: function stopPoll() { michael@0: return this._nfcContentHelper.stopPoll(this._window); michael@0: }, michael@0: michael@0: powerOff: function powerOff() { michael@0: return this._nfcContentHelper.powerOff(this._window); michael@0: }, michael@0: michael@0: getNFCTag: function getNFCTag(sessionToken) { michael@0: let obj = new MozNFCTag(); michael@0: let nfcTag = this._window.MozNFCTag._create(this._window, obj); michael@0: if (nfcTag) { michael@0: obj.initialize(this._window, sessionToken); michael@0: return nfcTag; michael@0: } else { michael@0: debug("Error: Unable to create NFCTag"); michael@0: return null; michael@0: } michael@0: }, michael@0: michael@0: getNFCPeer: function getNFCPeer(sessionToken) { michael@0: let obj = new MozNFCPeer(); michael@0: let nfcPeer = this._window.MozNFCPeer._create(this._window, obj); michael@0: if (nfcPeer) { michael@0: obj.initialize(this._window, sessionToken); michael@0: return nfcPeer; michael@0: } else { michael@0: debug("Error: Unable to create NFCPeer"); michael@0: return null; michael@0: } michael@0: }, michael@0: michael@0: // get/set onpeerready michael@0: get onpeerready() { michael@0: return this.__DOM_IMPL__.getEventHandler("onpeerready"); michael@0: }, michael@0: michael@0: set onpeerready(handler) { michael@0: this.__DOM_IMPL__.setEventHandler("onpeerready", handler); michael@0: }, michael@0: michael@0: // get/set onpeerlost michael@0: get onpeerlost() { michael@0: return this.__DOM_IMPL__.getEventHandler("onpeerlost"); michael@0: }, michael@0: michael@0: set onpeerlost(handler) { michael@0: this.__DOM_IMPL__.setEventHandler("onpeerlost", handler); michael@0: }, michael@0: michael@0: eventListenerWasAdded: function(evt) { michael@0: let eventType = this.getEventType(evt); michael@0: if (eventType == -1) michael@0: return; michael@0: this.registerTarget(eventType); michael@0: }, michael@0: michael@0: eventListenerWasRemoved: function(evt) { michael@0: let eventType = this.getEventType(evt); michael@0: if (eventType == -1) michael@0: return; michael@0: this.unregisterTarget(eventType); michael@0: }, michael@0: michael@0: registerTarget: function registerTarget(event) { michael@0: let self = this; michael@0: let appId = this._window.document.nodePrincipal.appId; michael@0: this._nfcContentHelper.registerTargetForPeerEvent(this._window, appId, michael@0: event, function(evt, sessionToken) { michael@0: self.session = sessionToken; michael@0: self.firePeerEvent(evt, sessionToken); michael@0: }); michael@0: }, michael@0: michael@0: unregisterTarget: function unregisterTarget(event) { michael@0: let appId = this._window.document.nodePrincipal.appId; michael@0: this._nfcContentHelper.unregisterTargetForPeerEvent(this._window, michael@0: appId, event); michael@0: }, michael@0: michael@0: getEventType: function getEventType(evt) { michael@0: let eventType = -1; michael@0: switch (evt) { michael@0: case 'peerready': michael@0: eventType = NFC_PEER_EVENT_READY; michael@0: break; michael@0: case 'peerlost': michael@0: eventType = NFC_PEER_EVENT_LOST; michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: return eventType; michael@0: }, michael@0: michael@0: firePeerEvent: function firePeerEvent(evt, sessionToken) { michael@0: let peerEvent = (NFC_PEER_EVENT_READY === evt) ? "peerready" : "peerlost"; michael@0: let detail = { michael@0: "detail":sessionToken michael@0: }; michael@0: let event = new this._window.CustomEvent(peerEvent, this._wrap(detail)); michael@0: this.__DOM_IMPL__.dispatchEvent(event); michael@0: }, michael@0: michael@0: classID: Components.ID("{6ff2b290-2573-11e3-8224-0800200c9a66}"), michael@0: contractID: "@mozilla.org/navigatorNfc;1", michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, michael@0: Ci.nsIDOMGlobalPropertyInitializer]), michael@0: }; michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozNFCTag, MozNFCPeer, mozNfc]);