author | Thomas Zimmermann <tdz@users.sourceforge.net> |
Thu, 12 Mar 2015 07:43:00 -0400 | |
changeset 233507 | 6c311023dcabbea2d89401f9a11dce3c1e4e8fd0 |
parent 233506 | 9379160419158cec5b8657620c8ebfa9fef44926 |
child 233508 | 226052175769bb2d401835741e45f10cf11bbed4 |
push id | 28414 |
push user | ryanvm@gmail.com |
push date | Fri, 13 Mar 2015 16:15:53 +0000 |
treeherder | mozilla-central@1722c4635fac [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | allstars.chh |
bugs | 1109592 |
milestone | 39.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
|
dom/nfc/gonk/Nfc.js | file | annotate | diff | comparison | revisions | |
dom/nfc/gonk/NfcService.cpp | file | annotate | diff | comparison | revisions |
--- a/dom/nfc/gonk/Nfc.js +++ b/dom/nfc/gonk/Nfc.js @@ -493,27 +493,16 @@ let SessionHelper = { }, isP2PSession: function isP2PSession(id) { return (this.tokenMap[id] != null) && this.tokenMap[id].isP2P; } }; function Nfc() { - debug("Starting Nfc Service"); - - let nfcService = Cc["@mozilla.org/nfc/service;1"].getService(Ci.nsINfcService); - if (!nfcService) { - debug("No nfc service component available!"); - return; - } - - nfcService.start(this); - this.nfcService = nfcService; - gMessageManager.init(this); this.targetsByRequestId = {}; } Nfc.prototype = { classID: NFC_CID, @@ -524,16 +513,49 @@ Nfc.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsINfcGonkEventListener]), rfState: NFC.NFC_RF_STATE_IDLE, nfcService: null, targetsByRequestId: null, + // temporary variables while NFC initialization is pending + pendingNfcService: null, + pendingMessageQueue: [], + + /** + * Start NFC service + */ + startNfcService: function startNfcService() { + debug("Starting Nfc Service"); + + let nfcService = + Cc["@mozilla.org/nfc/service;1"].getService(Ci.nsINfcService); + if (!nfcService) { + debug("No nfc service component available!"); + return false; + } + + nfcService.start(this); + this.pendingNfcService = nfcService; + + return true; + }, + + /** + * Shutdown NFC service + */ + shutdownNfcService : function shutdownNfcService() { + debug("Shutting down Nfc Service"); + + this.nfcService.shutdown(); + this.nfcService = null; + }, + /** * Send arbitrary message to Nfc service. * * @param nfcMessageType * A text message type. * @param message [optional] * An optional message object to send. */ @@ -568,48 +590,51 @@ Nfc.prototype = { return null; } delete this.targetsByRequestId[requestId]; return target; }, /** - * Send Error response to content. This is used only - * in case of discovering an error in message received from - * content process. + * Send Error response to content process. * * @param message * An nsIMessageListener's message parameter. + * @param errorMsg + * A string with an error message. */ - sendNfcErrorResponse: function sendNfcErrorResponse(message, errorCode) { + sendNfcErrorResponse: function sendNfcErrorResponse(message, errorMsg) { if (!message.target) { return; } let nfcMsgType = message.name + "Response"; - message.data.errorMsg = this.getErrorMessage(errorCode); + message.data.errorMsg = errorMsg; message.target.sendAsyncMessage(nfcMsgType, message.data); }, - getErrorMessage: function getErrorMessage(errorCode) { - return NFC.NFC_ERROR_MSG[errorCode]; - }, - /** * Process the incoming message from the NFC Service. */ onEvent: function onEvent(event) { let message = Cu.cloneInto(event, this); DEBUG && debug("Received message from NFC Service: " + JSON.stringify(message)); message.type = message.rspType || message.ntfType; switch (message.type) { case NfcNotificationType.INITIALIZED: - // Do nothing. + this.nfcService = this.pendingNfcService; + // Send messages that have been queued up during initialization + // TODO: Bug 1141007: send error responses if the message + // indicates an error during initialization. + while (this.pendingMessageQueue.length) { + this.receiveMessage(this.pendingMessageQueue.shift()); + } + this.pendingNfcService = null; break; case NfcNotificationType.TECH_DISCOVERED: // Update the upper layers with a session token (alias) message.sessionToken = SessionHelper.registerSession(message.sessionId, message.isP2P); // Do not expose the actual session to the content let sessionId = message.sessionId; delete message.sessionId; @@ -643,16 +668,19 @@ Nfc.prototype = { break; case NfcResponseType.CHANGE_RF_STATE_RSP: this.sendNfcResponse(message); if (!message.errorMsg) { this.rfState = message.rfState; gMessageManager.onRFStateChanged(this.rfState); } + if (this.rfState == NFC.NFC_RF_STATE_IDLE) { + this.shutdownNfcService(); + } break; case NfcResponseType.READ_NDEF_RSP: // Fall through. case NfcResponseType.WRITE_NDEF_RSP: case NfcResponseType.MAKE_READ_ONLY_RSP: case NfcResponseType.FORMAT_RSP: case NfcResponseType.TRANSCEIVE_RSP: this.sendNfcResponse(message); break; @@ -680,24 +708,43 @@ Nfc.prototype = { */ gSystemMessenger.broadcastMessage("nfc-hci-event-transaction", message); }, /** * Process a message from the gMessageManager. */ receiveMessage: function receiveMessage(message) { - // Return early if we don't need the NFC Service. + // Return early if we don't need the NFC Service. We won't start + // the NFC daemon here. switch (message.name) { case "NFC:QueryInfo": return {rfState: this.rfState}; default: break; } + // Start NFC Service if necessary. Messages are held in a + // queue while initialization is being performed. + if (!this.nfcService) { + if ((message.name == "NFC:ChangeRFState") && + (message.data.rfState != "idle") && + !this.pendingNfcService) { + this.startNfcService(); // error handled in next branch + } + if (this.pendingNfcService) { + this.pendingMessageQueue.push(message); + } else { + this.sendNfcErrorResponse(message, "NotInitialize"); + } + return; + } + + // NFC Service is running and we have a message for it. This + // is the case during normal operation. if (message.name != "NFC:ChangeRFState") { // Update the current sessionId before sending to the NFC service. message.data.sessionId = SessionHelper.getId(message.data.sessionToken); } let command = CommandMsgTable[message.name]; if (!command) { debug("Unknown message: " + message.name); @@ -733,18 +780,24 @@ Nfc.prototype = { */ observe: function(subject, topic, data) { if (topic != "profile-after-change") { debug("Should receive 'profile-after-change' only, received " + topic); } }, shutdown: function shutdown() { - this.nfcService.shutdown(); - this.nfcService = null; + // We shutdown before initialization has been completed. The + // pending messages will receive an error response. + while (this.pendingMessageQueue.length) { + this.sendNfcErrorResponse(this.pendingMessageQueue.shift(), "NotInitialize"); + } + if (this.nfcService) { + this.shutdownNfcService(); + } } }; function NfcTechDiscoveredSysMsg(sessionToken, isP2P, records) { this.sessionToken = sessionToken; this.isP2P = isP2P; this.records = records; }
--- a/dom/nfc/gonk/NfcService.cpp +++ b/dom/nfc/gonk/NfcService.cpp @@ -259,17 +259,16 @@ public: } private: NfcMessageHandler* mHandler; nsAutoPtr<UnixSocketRawData> mData; }; NfcService::NfcService() - : mConsumer(new NfcConsumer(this)) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!gNfcService); } NfcService::~NfcService() { MOZ_ASSERT(!gNfcService); @@ -305,16 +304,18 @@ NfcService::Start(nsINfcGonkEventListene NS_WARNING("Can't create Nfc worker thread."); Shutdown(); return NS_ERROR_FAILURE; } mListener = aListener; mHandler = new NfcMessageHandler(); + mConsumer = new NfcConsumer(this); + return NS_OK; } NS_IMETHODIMP NfcService::Shutdown() { MOZ_ASSERT(NS_IsMainThread());