michael@0: /* Copyright 2012 Mozilla Foundation and Mozilla contributors michael@0: * michael@0: * Licensed under the Apache License, Version 2.0 (the "License"); michael@0: * you may not use this file except in compliance with the License. michael@0: * You may obtain a copy of the License at michael@0: * michael@0: * http://www.apache.org/licenses/LICENSE-2.0 michael@0: * michael@0: * Unless required by applicable law or agreed to in writing, software michael@0: * distributed under the License is distributed on an "AS IS" BASIS, michael@0: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. michael@0: * See the License for the specific language governing permissions and michael@0: * limitations under the License. michael@0: */ michael@0: michael@0: /* Copyright © 2013, Deutsche Telekom, Inc. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: let NFC = {}; michael@0: Cu.import("resource://gre/modules/nfc_consts.js", NFC); michael@0: michael@0: Cu.import("resource://gre/modules/systemlibs.js"); michael@0: const NFC_ENABLED = libcutils.property_get("ro.moz.nfc.enabled", "false") === "true"; michael@0: michael@0: // set to true in nfc_consts.js to see debug messages michael@0: let DEBUG = NFC.DEBUG_NFC; michael@0: michael@0: let debug; michael@0: if (DEBUG) { michael@0: debug = function (s) { michael@0: dump("-*- Nfc: " + s + "\n"); michael@0: }; michael@0: } else { michael@0: debug = function (s) {}; michael@0: } michael@0: michael@0: const NFC_CONTRACTID = "@mozilla.org/nfc;1"; michael@0: const NFC_CID = michael@0: Components.ID("{2ff24790-5e74-11e1-b86c-0800200c9a66}"); michael@0: michael@0: const NFC_IPC_MSG_NAMES = [ michael@0: "NFC:SetSessionToken" michael@0: ]; michael@0: michael@0: const NFC_IPC_READ_PERM_MSG_NAMES = [ michael@0: "NFC:ReadNDEF", michael@0: "NFC:GetDetailsNDEF", michael@0: "NFC:Connect", michael@0: "NFC:Close", michael@0: ]; michael@0: michael@0: const NFC_IPC_WRITE_PERM_MSG_NAMES = [ michael@0: "NFC:WriteNDEF", michael@0: "NFC:MakeReadOnlyNDEF", michael@0: "NFC:SendFile", michael@0: "NFC:RegisterPeerTarget", michael@0: "NFC:UnregisterPeerTarget" michael@0: ]; michael@0: michael@0: const NFC_IPC_MANAGER_PERM_MSG_NAMES = [ michael@0: "NFC:CheckP2PRegistration", michael@0: "NFC:NotifyUserAcceptedP2P", michael@0: "NFC:NotifySendFileStatus", michael@0: "NFC:StartPoll", michael@0: "NFC:StopPoll", michael@0: "NFC:PowerOff" michael@0: ]; michael@0: michael@0: XPCOMUtils.defineLazyServiceGetter(this, "ppmm", michael@0: "@mozilla.org/parentprocessmessagemanager;1", michael@0: "nsIMessageBroadcaster"); michael@0: XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger", michael@0: "@mozilla.org/system-message-internal;1", michael@0: "nsISystemMessagesInternal"); michael@0: XPCOMUtils.defineLazyServiceGetter(this, "gSystemWorkerManager", michael@0: "@mozilla.org/telephony/system-worker-manager;1", michael@0: "nsISystemWorkerManager"); michael@0: XPCOMUtils.defineLazyServiceGetter(this, "UUIDGenerator", michael@0: "@mozilla.org/uuid-generator;1", michael@0: "nsIUUIDGenerator"); michael@0: XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { michael@0: return { michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, michael@0: Ci.nsIObserver]), michael@0: michael@0: nfc: null, michael@0: michael@0: // Manage message targets in terms of sessionToken. Only the authorized and michael@0: // registered contents can receive related messages. michael@0: targetsBySessionTokens: {}, michael@0: sessionTokens: [], michael@0: michael@0: // Manage registered Peer Targets michael@0: peerTargetsMap: {}, michael@0: currentPeerAppId: null, michael@0: michael@0: init: function init(nfc) { michael@0: this.nfc = nfc; michael@0: michael@0: Services.obs.addObserver(this, NFC.TOPIC_XPCOM_SHUTDOWN, false); michael@0: this._registerMessageListeners(); michael@0: }, michael@0: michael@0: _shutdown: function _shutdown() { michael@0: this.nfc = null; michael@0: michael@0: Services.obs.removeObserver(this, NFC.TOPIC_XPCOM_SHUTDOWN); michael@0: this._unregisterMessageListeners(); michael@0: }, michael@0: michael@0: _registerMessageListeners: function _registerMessageListeners() { michael@0: ppmm.addMessageListener("child-process-shutdown", this); michael@0: michael@0: for (let msgname of NFC_IPC_MSG_NAMES) { michael@0: ppmm.addMessageListener(msgname, this); michael@0: } michael@0: michael@0: for (let msgname of NFC_IPC_READ_PERM_MSG_NAMES) { michael@0: ppmm.addMessageListener(msgname, this); michael@0: } michael@0: michael@0: for (let msgname of NFC_IPC_WRITE_PERM_MSG_NAMES) { michael@0: ppmm.addMessageListener(msgname, this); michael@0: } michael@0: michael@0: for (let msgname of NFC_IPC_MANAGER_PERM_MSG_NAMES) { michael@0: ppmm.addMessageListener(msgname, this); michael@0: } michael@0: }, michael@0: michael@0: _unregisterMessageListeners: function _unregisterMessageListeners() { michael@0: ppmm.removeMessageListener("child-process-shutdown", this); michael@0: michael@0: for (let msgname of NFC_IPC_MSG_NAMES) { michael@0: ppmm.removeMessageListener(msgname, this); michael@0: } michael@0: michael@0: for (let msgname of NFC_IPC_READ_PERM_MSG_NAMES) { michael@0: ppmm.removeMessageListener(msgname, this); michael@0: } michael@0: michael@0: for (let msgname of NFC_IPC_WRITE_PERM_MSG_NAMES) { michael@0: ppmm.removeMessageListener(msgname, this); michael@0: } michael@0: michael@0: for (let msgname of NFC_IPC_MANAGER_PERM_MSG_NAMES) { michael@0: ppmm.removeMessageListener(msgname, this); michael@0: } michael@0: michael@0: ppmm = null; michael@0: }, michael@0: michael@0: _registerMessageTarget: function _registerMessageTarget(sessionToken, target) { michael@0: let targets = this.targetsBySessionTokens[sessionToken]; michael@0: if (!targets) { michael@0: targets = this.targetsBySessionTokens[sessionToken] = []; michael@0: let list = this.sessionTokens; michael@0: if (list.indexOf(sessionToken) == -1) { michael@0: list.push(sessionToken); michael@0: } michael@0: } michael@0: michael@0: if (targets.indexOf(target) != -1) { michael@0: debug("Already registered this target!"); michael@0: return; michael@0: } michael@0: michael@0: targets.push(target); michael@0: debug("Registered :" + sessionToken + " target: " + target); michael@0: }, michael@0: michael@0: _unregisterMessageTarget: function _unregisterMessageTarget(sessionToken, target) { michael@0: if (sessionToken == null) { michael@0: // Unregister the target for every sessionToken when no sessionToken is specified. michael@0: for (let session of this.sessionTokens) { michael@0: this._unregisterMessageTarget(session, target); michael@0: } michael@0: return; michael@0: } michael@0: michael@0: // Unregister the target for a specified sessionToken. michael@0: let targets = this.targetsBySessionTokens[sessionToken]; michael@0: if (!targets) { michael@0: return; michael@0: } michael@0: michael@0: if (target == null) { michael@0: debug("Unregistered all targets for the " + sessionToken + " targets: " + targets); michael@0: targets = []; michael@0: let list = this.sessionTokens; michael@0: if (sessionToken !== null) { michael@0: let index = list.indexOf(sessionToken); michael@0: if (index > -1) { michael@0: list.splice(index, 1); michael@0: } michael@0: } michael@0: return; michael@0: } michael@0: michael@0: let index = targets.indexOf(target); michael@0: if (index != -1) { michael@0: targets.splice(index, 1); michael@0: } michael@0: }, michael@0: michael@0: _sendTargetMessage: function _sendTargetMessage(sessionToken, message, options) { michael@0: let targets = this.targetsBySessionTokens[sessionToken]; michael@0: if (!targets) { michael@0: return; michael@0: } michael@0: michael@0: for (let target of targets) { michael@0: target.sendAsyncMessage(message, options); michael@0: } michael@0: }, michael@0: michael@0: registerPeerTarget: function registerPeerTarget(msg) { michael@0: let appInfo = msg.json; michael@0: // Sanity check on PeerEvent michael@0: if (!this.isValidPeerEvent(appInfo.event)) { michael@0: return; michael@0: } michael@0: let targets = this.peerTargetsMap; michael@0: let targetInfo = targets[appInfo.appId]; michael@0: // If the application Id is already registered michael@0: if (targetInfo) { michael@0: // If the event is not registered michael@0: if (targetInfo.event !== appInfo.event) { michael@0: // Update the event field ONLY michael@0: targetInfo.event |= appInfo.event; michael@0: } michael@0: // Otherwise event is already registered, return! michael@0: return; michael@0: } michael@0: // Target not registered yet! Add to the target map michael@0: michael@0: // Registered targetInfo target consists of 2 fields (values) michael@0: // target : Target to notify the right content for peer notifications michael@0: // event : NFC_PEER_EVENT_READY (0x01) Or NFC_PEER_EVENT_LOST (0x02) michael@0: let newTargetInfo = { target : msg.target, michael@0: event : appInfo.event }; michael@0: targets[appInfo.appId] = newTargetInfo; michael@0: }, michael@0: michael@0: unregisterPeerTarget: function unregisterPeerTarget(msg) { michael@0: let appInfo = msg.json; michael@0: // Sanity check on PeerEvent michael@0: if (!this.isValidPeerEvent(appInfo.event)) { michael@0: return; michael@0: } michael@0: let targets = this.peerTargetsMap; michael@0: let targetInfo = targets[appInfo.appId]; michael@0: if (targetInfo) { michael@0: // Application Id registered and the event exactly matches. michael@0: if (targetInfo.event === appInfo.event) { michael@0: // Remove the target from the list of registered targets michael@0: delete targets[appInfo.appId] michael@0: } michael@0: else { michael@0: // Otherwise, update the event field ONLY, by removing the event flag michael@0: targetInfo.event &= ~appInfo.event; michael@0: } michael@0: } michael@0: }, michael@0: michael@0: removePeerTarget: function removePeerTarget(target) { michael@0: let targets = this.peerTargetsMap; michael@0: Object.keys(targets).forEach((appId) => { michael@0: let targetInfo = targets[appId]; michael@0: if (targetInfo && targetInfo.target === target) { michael@0: // Remove the target from the list of registered targets michael@0: delete targets[appId]; michael@0: } michael@0: }); michael@0: }, michael@0: michael@0: isRegisteredP2PTarget: function isRegisteredP2PTarget(appId, event) { michael@0: let targetInfo = this.peerTargetsMap[appId]; michael@0: // Check if it is a registered target for the 'event' michael@0: return ((targetInfo != null) && (targetInfo.event & event !== 0)); michael@0: }, michael@0: michael@0: notifyPeerEvent: function notifyPeerEvent(appId, event) { michael@0: let targetInfo = this.peerTargetsMap[appId]; michael@0: // Check if the application id is a registeredP2PTarget michael@0: if (this.isRegisteredP2PTarget(appId, event)) { michael@0: targetInfo.target.sendAsyncMessage("NFC:PeerEvent", { michael@0: event: event, michael@0: sessionToken: this.nfc.sessionTokenMap[this.nfc._currentSessionId] michael@0: }); michael@0: return; michael@0: } michael@0: debug("Application ID : " + appId + " is not a registered target" + michael@0: "for the event " + event + " notification"); michael@0: }, michael@0: michael@0: isValidPeerEvent: function isValidPeerEvent(event) { michael@0: // Valid values : 0x01, 0x02 Or 0x03 michael@0: return ((event === NFC.NFC_PEER_EVENT_READY) || michael@0: (event === NFC.NFC_PEER_EVENT_LOST) || michael@0: (event === (NFC.NFC_PEER_EVENT_READY | NFC.NFC_PEER_EVENT_LOST))); michael@0: }, michael@0: michael@0: /** michael@0: * nsIMessageListener interface methods. michael@0: */ michael@0: michael@0: receiveMessage: function receiveMessage(msg) { michael@0: debug("Received '" + msg.name + "' message from content process"); michael@0: if (msg.name == "child-process-shutdown") { michael@0: // By the time we receive child-process-shutdown, the child process has michael@0: // already forgotten its permissions so we need to unregister the target michael@0: // for every permission. michael@0: this._unregisterMessageTarget(null, msg.target); michael@0: this.removePeerTarget(msg.target); michael@0: return null; michael@0: } michael@0: michael@0: if (NFC_IPC_MSG_NAMES.indexOf(msg.name) != -1) { michael@0: // Do nothing. michael@0: } else if (NFC_IPC_READ_PERM_MSG_NAMES.indexOf(msg.name) != -1) { michael@0: if (!msg.target.assertPermission("nfc-read")) { michael@0: debug("Nfc message " + msg.name + michael@0: " from a content process with no 'nfc-read' privileges."); michael@0: return null; michael@0: } michael@0: } else if (NFC_IPC_WRITE_PERM_MSG_NAMES.indexOf(msg.name) != -1) { michael@0: if (!msg.target.assertPermission("nfc-write")) { michael@0: debug("Nfc Peer message " + msg.name + michael@0: " from a content process with no 'nfc-write' privileges."); michael@0: return null; michael@0: } michael@0: } else if (NFC_IPC_MANAGER_PERM_MSG_NAMES.indexOf(msg.name) != -1) { michael@0: if (!msg.target.assertPermission("nfc-manager")) { michael@0: debug("NFC message " + message.name + michael@0: " from a content process with no 'nfc-manager' privileges."); michael@0: return null; michael@0: } michael@0: } else { michael@0: debug("Ignoring unknown message type: " + msg.name); michael@0: return null; michael@0: } michael@0: michael@0: switch (msg.name) { michael@0: case "NFC:SetSessionToken": michael@0: this._registerMessageTarget(this.nfc.sessionTokenMap[this.nfc._currentSessionId], msg.target); michael@0: debug("Registering target for this SessionToken : " + michael@0: this.nfc.sessionTokenMap[this.nfc._currentSessionId]); michael@0: return null; michael@0: case "NFC:RegisterPeerTarget": michael@0: this.registerPeerTarget(msg); michael@0: return null; michael@0: case "NFC:UnregisterPeerTarget": michael@0: this.unregisterPeerTarget(msg); michael@0: return null; michael@0: case "NFC:CheckP2PRegistration": michael@0: // Check if the application id is a valid registered target. michael@0: // (It should have registered for NFC_PEER_EVENT_READY). michael@0: let isRegistered = this.isRegisteredP2PTarget(msg.json.appId, michael@0: NFC.NFC_PEER_EVENT_READY); michael@0: // Remember the current AppId if registered. michael@0: this.currentPeerAppId = (isRegistered) ? msg.json.appId : null; michael@0: let status = (isRegistered) ? NFC.GECKO_NFC_ERROR_SUCCESS : michael@0: NFC.GECKO_NFC_ERROR_GENERIC_FAILURE; michael@0: // Notify the content process immediately of the status michael@0: msg.target.sendAsyncMessage(msg.name + "Response", { michael@0: status: status, michael@0: requestId: msg.json.requestId michael@0: }); michael@0: return null; michael@0: case "NFC:NotifyUserAcceptedP2P": michael@0: // Notify the 'NFC_PEER_EVENT_READY' since user has acknowledged michael@0: this.notifyPeerEvent(msg.json.appId, NFC.NFC_PEER_EVENT_READY); michael@0: return null; michael@0: case "NFC:NotifySendFileStatus": michael@0: // Upon receiving the status of sendFile operation, send the response michael@0: // to appropriate content process. michael@0: this.sendNfcResponseMessage(msg.name + "Response", msg.json); michael@0: return null; michael@0: default: michael@0: return this.nfc.receiveMessage(msg); michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * nsIObserver interface methods. michael@0: */ michael@0: michael@0: observe: function observe(subject, topic, data) { michael@0: switch (topic) { michael@0: case NFC.TOPIC_XPCOM_SHUTDOWN: michael@0: this._shutdown(); michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: sendNfcResponseMessage: function sendNfcResponseMessage(message, data) { michael@0: this._sendTargetMessage(this.nfc.sessionTokenMap[this.nfc._currentSessionId], message, data); michael@0: }, michael@0: }; michael@0: }); michael@0: michael@0: function Nfc() { michael@0: debug("Starting Worker"); michael@0: this.worker = new ChromeWorker("resource://gre/modules/nfc_worker.js"); michael@0: this.worker.onerror = this.onerror.bind(this); michael@0: this.worker.onmessage = this.onmessage.bind(this); michael@0: michael@0: gMessageManager.init(this); michael@0: michael@0: // Maps sessionId (that are generated from nfcd) with a unique guid : 'SessionToken' michael@0: this.sessionTokenMap = {}; michael@0: this.targetsByRequestId = {}; michael@0: michael@0: gSystemWorkerManager.registerNfcWorker(this.worker); michael@0: } michael@0: michael@0: Nfc.prototype = { michael@0: michael@0: classID: NFC_CID, michael@0: classInfo: XPCOMUtils.generateCI({classID: NFC_CID, michael@0: classDescription: "Nfc", michael@0: interfaces: [Ci.nsIWorkerHolder]}), michael@0: michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIWorkerHolder]), michael@0: michael@0: _currentSessionId: null, michael@0: michael@0: powerLevel: NFC.NFC_POWER_LEVEL_UNKNOWN, michael@0: michael@0: onerror: function onerror(event) { michael@0: debug("Got an error: " + event.filename + ":" + michael@0: event.lineno + ": " + event.message + "\n"); michael@0: event.preventDefault(); michael@0: }, michael@0: michael@0: /** michael@0: * Send arbitrary message to worker. michael@0: * michael@0: * @param nfcMessageType michael@0: * A text message type. michael@0: * @param message [optional] michael@0: * An optional message object to send. michael@0: */ michael@0: sendToWorker: function sendToWorker(nfcMessageType, message) { michael@0: message = message || {}; michael@0: message.type = nfcMessageType; michael@0: this.worker.postMessage(message); michael@0: }, michael@0: michael@0: /** michael@0: * Send Error response to content. michael@0: * michael@0: * @param message michael@0: * An nsIMessageListener's message parameter. michael@0: */ michael@0: sendNfcErrorResponse: function sendNfcErrorResponse(message) { michael@0: if (!message.target) { michael@0: return; michael@0: } michael@0: michael@0: let nfcMsgType = message.name + "Response"; michael@0: message.target.sendAsyncMessage(nfcMsgType, { michael@0: sessionId: message.json.sessionToken, michael@0: requestId: message.json.requestId, michael@0: status: NFC.GECKO_NFC_ERROR_GENERIC_FAILURE michael@0: }); michael@0: }, michael@0: michael@0: /** michael@0: * Process the incoming message from the NFC worker michael@0: */ michael@0: onmessage: function onmessage(event) { michael@0: let message = event.data; michael@0: debug("Received message from NFC worker: " + JSON.stringify(message)); michael@0: michael@0: switch (message.type) { michael@0: case "techDiscovered": michael@0: this._currentSessionId = message.sessionId; michael@0: michael@0: // Check if the session token already exists. If exists, continue to use the same one. michael@0: // If not, generate a new token. michael@0: if (!this.sessionTokenMap[this._currentSessionId]) { michael@0: this.sessionTokenMap[this._currentSessionId] = UUIDGenerator.generateUUID().toString(); michael@0: } michael@0: // Update the upper layers with a session token (alias) michael@0: message.sessionToken = this.sessionTokenMap[this._currentSessionId]; michael@0: // Do not expose the actual session to the content michael@0: delete message.sessionId; michael@0: michael@0: gSystemMessenger.broadcastMessage("nfc-manager-tech-discovered", message); michael@0: break; michael@0: case "techLost": michael@0: gMessageManager._unregisterMessageTarget(this.sessionTokenMap[this._currentSessionId], null); michael@0: michael@0: // Update the upper layers with a session token (alias) michael@0: message.sessionToken = this.sessionTokenMap[this._currentSessionId]; michael@0: // Do not expose the actual session to the content michael@0: delete message.sessionId; michael@0: michael@0: gSystemMessenger.broadcastMessage("nfc-manager-tech-lost", message); michael@0: // Notify 'PeerLost' to appropriate registered target, if any michael@0: gMessageManager.notifyPeerEvent(this.currentPeerAppId, NFC.NFC_PEER_EVENT_LOST); michael@0: delete this.sessionTokenMap[this._currentSessionId]; michael@0: this._currentSessionId = null; michael@0: this.currentPeerAppId = null; michael@0: break; michael@0: case "ConfigResponse": michael@0: let target = this.targetsByRequestId[message.requestId]; michael@0: if (!target) { michael@0: debug("No target for requestId: " + message.requestId); michael@0: return; michael@0: } michael@0: delete this.targetsByRequestId[message.requestId]; michael@0: michael@0: if (message.status == NFC.GECKO_NFC_ERROR_SUCCESS) { michael@0: this.powerLevel = message.powerLevel; michael@0: } michael@0: michael@0: target.sendAsyncMessage("NFC:ConfigResponse", message); michael@0: break; michael@0: case "ConnectResponse": // Fall through. michael@0: case "CloseResponse": michael@0: case "GetDetailsNDEFResponse": michael@0: case "ReadNDEFResponse": michael@0: case "MakeReadOnlyNDEFResponse": michael@0: case "WriteNDEFResponse": michael@0: message.sessionToken = this.sessionTokenMap[this._currentSessionId]; michael@0: // Do not expose the actual session to the content michael@0: delete message.sessionId; michael@0: gMessageManager.sendNfcResponseMessage("NFC:" + message.type, message); michael@0: break; michael@0: default: michael@0: throw new Error("Don't know about this message type: " + message.type); michael@0: } michael@0: }, michael@0: michael@0: // nsINfcWorker michael@0: worker: null, michael@0: michael@0: sessionTokenMap: null, michael@0: michael@0: targetsByRequestId: null, michael@0: michael@0: /** michael@0: * Process a message from the content process. michael@0: */ michael@0: receiveMessage: function receiveMessage(message) { michael@0: debug("Received '" + JSON.stringify(message) + "' message from content process"); michael@0: michael@0: // Handle messages without sessionToken. michael@0: if (message.name == "NFC:StartPoll") { michael@0: this.targetsByRequestId[message.json.requestId] = message.target; michael@0: this.setConfig({powerLevel: NFC.NFC_POWER_LEVEL_ENABLED, michael@0: requestId: message.json.requestId}); michael@0: return null; michael@0: } else if (message.name == "NFC:StopPoll") { michael@0: this.targetsByRequestId[message.json.requestId] = message.target; michael@0: this.setConfig({powerLevel: NFC.NFC_POWER_LEVEL_LOW, michael@0: requestId: message.json.requestId}); michael@0: return null; michael@0: } else if (message.name == "NFC:PowerOff") { michael@0: this.targetsByRequestId[message.json.requestId] = message.target; michael@0: this.setConfig({powerLevel: NFC.NFC_POWER_LEVEL_DISABLED, michael@0: requestId: message.json.requestId}); michael@0: return null; michael@0: } michael@0: michael@0: if (this.powerLevel != NFC.NFC_POWER_LEVEL_ENABLED) { michael@0: debug("NFC is not enabled. current powerLevel:" + this.powerLevel); michael@0: this.sendNfcErrorResponse(message); michael@0: return null; michael@0: } michael@0: michael@0: // Sanity check on sessionId michael@0: if (message.json.sessionToken !== this.sessionTokenMap[this._currentSessionId]) { michael@0: debug("Invalid Session Token: " + message.json.sessionToken + michael@0: " Expected Session Token: " + this.sessionTokenMap[this._currentSessionId]); michael@0: this.sendNfcErrorResponse(message); michael@0: return null; michael@0: } michael@0: michael@0: // Update the current sessionId before sending to the worker michael@0: message.json.sessionId = this._currentSessionId; michael@0: michael@0: switch (message.name) { michael@0: case "NFC:GetDetailsNDEF": michael@0: this.sendToWorker("getDetailsNDEF", message.json); michael@0: break; michael@0: case "NFC:ReadNDEF": michael@0: this.sendToWorker("readNDEF", message.json); michael@0: break; michael@0: case "NFC:WriteNDEF": michael@0: this.sendToWorker("writeNDEF", message.json); michael@0: break; michael@0: case "NFC:MakeReadOnlyNDEF": michael@0: this.sendToWorker("makeReadOnlyNDEF", message.json); michael@0: break; michael@0: case "NFC:Connect": michael@0: this.sendToWorker("connect", message.json); michael@0: break; michael@0: case "NFC:Close": michael@0: this.sendToWorker("close", message.json); michael@0: break; michael@0: case "NFC:SendFile": michael@0: // Chrome process is the arbitrator / mediator between michael@0: // system app (content process) that issued nfc 'sendFile' operation michael@0: // and system app that handles the system message : michael@0: // 'nfc-manager-send-file'. System app subsequently handover's michael@0: // the data to alternate carrier's (BT / WiFi) 'sendFile' interface. michael@0: michael@0: // Notify system app to initiate BT send file operation michael@0: gSystemMessenger.broadcastMessage("nfc-manager-send-file", michael@0: message.json); michael@0: break; michael@0: default: michael@0: debug("UnSupported : Message Name " + message.name); michael@0: return null; michael@0: } michael@0: michael@0: return null; michael@0: }, michael@0: michael@0: setConfig: function setConfig(prop) { michael@0: this.sendToWorker("config", prop); michael@0: } michael@0: }; michael@0: michael@0: if (NFC_ENABLED) { michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Nfc]); michael@0: }