dom/system/gonk/NfcContentHelper.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* Copyright 2012 Mozilla Foundation and Mozilla contributors
michael@0 2 *
michael@0 3 * Licensed under the Apache License, Version 2.0 (the "License");
michael@0 4 * you may not use this file except in compliance with the License.
michael@0 5 * You may obtain a copy of the License at
michael@0 6 *
michael@0 7 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 8 *
michael@0 9 * Unless required by applicable law or agreed to in writing, software
michael@0 10 * distributed under the License is distributed on an "AS IS" BASIS,
michael@0 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
michael@0 12 * See the License for the specific language governing permissions and
michael@0 13 * limitations under the License.
michael@0 14 */
michael@0 15
michael@0 16 /* Copyright © 2013, Deutsche Telekom, Inc. */
michael@0 17
michael@0 18 "use strict";
michael@0 19
michael@0 20 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
michael@0 21
michael@0 22 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 23 Cu.import("resource://gre/modules/Services.jsm");
michael@0 24 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
michael@0 25
michael@0 26 let NFC = {};
michael@0 27 Cu.import("resource://gre/modules/nfc_consts.js", NFC);
michael@0 28
michael@0 29 Cu.import("resource://gre/modules/systemlibs.js");
michael@0 30 const NFC_ENABLED = libcutils.property_get("ro.moz.nfc.enabled", "false") === "true";
michael@0 31
michael@0 32 // set to true to in nfc_consts.js to see debug messages
michael@0 33 let DEBUG = NFC.DEBUG_CONTENT_HELPER;
michael@0 34
michael@0 35 let debug;
michael@0 36 if (DEBUG) {
michael@0 37 debug = function (s) {
michael@0 38 dump("-*- NfcContentHelper: " + s + "\n");
michael@0 39 };
michael@0 40 } else {
michael@0 41 debug = function (s) {};
michael@0 42 }
michael@0 43
michael@0 44 const NFCCONTENTHELPER_CID =
michael@0 45 Components.ID("{4d72c120-da5f-11e1-9b23-0800200c9a66}");
michael@0 46
michael@0 47 const NFC_IPC_MSG_NAMES = [
michael@0 48 "NFC:ReadNDEFResponse",
michael@0 49 "NFC:WriteNDEFResponse",
michael@0 50 "NFC:GetDetailsNDEFResponse",
michael@0 51 "NFC:MakeReadOnlyNDEFResponse",
michael@0 52 "NFC:ConnectResponse",
michael@0 53 "NFC:CloseResponse",
michael@0 54 "NFC:CheckP2PRegistrationResponse",
michael@0 55 "NFC:PeerEvent",
michael@0 56 "NFC:NotifySendFileStatusResponse",
michael@0 57 "NFC:ConfigResponse"
michael@0 58 ];
michael@0 59
michael@0 60 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
michael@0 61 "@mozilla.org/childprocessmessagemanager;1",
michael@0 62 "nsISyncMessageSender");
michael@0 63
michael@0 64 function GetDetailsNDEFResponse(details) {
michael@0 65 this.canBeMadeReadOnly = details.canBeMadeReadOnly;
michael@0 66 this.isReadOnly = details.isReadOnly;
michael@0 67 this.maxSupportedLength = details.maxSupportedLength;
michael@0 68 }
michael@0 69 GetDetailsNDEFResponse.prototype = {
michael@0 70 __exposedProps__ : {canBeMadeReadOnly: 'r',
michael@0 71 isReadOnly: 'r',
michael@0 72 maxSupportedLength: 'r'}
michael@0 73 };
michael@0 74
michael@0 75 function NfcContentHelper() {
michael@0 76 this.initDOMRequestHelper(/* aWindow */ null, NFC_IPC_MSG_NAMES);
michael@0 77 Services.obs.addObserver(this, "xpcom-shutdown", false);
michael@0 78
michael@0 79 this._requestMap = [];
michael@0 80
michael@0 81 // Maintains an array of PeerEvent related callbacks, mainly
michael@0 82 // one for 'peerReady' and another for 'peerLost'.
michael@0 83 this.peerEventsCallbackMap = {};
michael@0 84 }
michael@0 85
michael@0 86 NfcContentHelper.prototype = {
michael@0 87 __proto__: DOMRequestIpcHelper.prototype,
michael@0 88
michael@0 89 QueryInterface: XPCOMUtils.generateQI([Ci.nsINfcContentHelper,
michael@0 90 Ci.nsISupportsWeakReference,
michael@0 91 Ci.nsIObserver]),
michael@0 92 classID: NFCCONTENTHELPER_CID,
michael@0 93 classInfo: XPCOMUtils.generateCI({
michael@0 94 classID: NFCCONTENTHELPER_CID,
michael@0 95 classDescription: "NfcContentHelper",
michael@0 96 interfaces: [Ci.nsINfcContentHelper]
michael@0 97 }),
michael@0 98
michael@0 99 _requestMap: null,
michael@0 100 peerEventsCallbackMap: null,
michael@0 101
michael@0 102 encodeNDEFRecords: function encodeNDEFRecords(records) {
michael@0 103 let encodedRecords = [];
michael@0 104 for (let i = 0; i < records.length; i++) {
michael@0 105 let record = records[i];
michael@0 106 encodedRecords.push({
michael@0 107 tnf: record.tnf,
michael@0 108 type: record.type,
michael@0 109 id: record.id,
michael@0 110 payload: record.payload,
michael@0 111 });
michael@0 112 }
michael@0 113 return encodedRecords;
michael@0 114 },
michael@0 115
michael@0 116 // NFC interface:
michael@0 117 setSessionToken: function setSessionToken(sessionToken) {
michael@0 118 if (sessionToken == null) {
michael@0 119 throw Components.Exception("No session token!",
michael@0 120 Cr.NS_ERROR_UNEXPECTED);
michael@0 121 return;
michael@0 122 }
michael@0 123 // Report session to Nfc.js only.
michael@0 124 cpmm.sendAsyncMessage("NFC:SetSessionToken", {
michael@0 125 sessionToken: sessionToken,
michael@0 126 });
michael@0 127 },
michael@0 128
michael@0 129 // NFCTag interface
michael@0 130 getDetailsNDEF: function getDetailsNDEF(window, sessionToken) {
michael@0 131 if (window == null) {
michael@0 132 throw Components.Exception("Can't get window object",
michael@0 133 Cr.NS_ERROR_UNEXPECTED);
michael@0 134 }
michael@0 135 let request = Services.DOMRequest.createRequest(window);
michael@0 136 let requestId = btoa(this.getRequestId(request));
michael@0 137 this._requestMap[requestId] = window;
michael@0 138
michael@0 139 cpmm.sendAsyncMessage("NFC:GetDetailsNDEF", {
michael@0 140 requestId: requestId,
michael@0 141 sessionToken: sessionToken
michael@0 142 });
michael@0 143 return request;
michael@0 144 },
michael@0 145
michael@0 146 readNDEF: function readNDEF(window, sessionToken) {
michael@0 147 if (window == null) {
michael@0 148 throw Components.Exception("Can't get window object",
michael@0 149 Cr.NS_ERROR_UNEXPECTED);
michael@0 150 }
michael@0 151 let request = Services.DOMRequest.createRequest(window);
michael@0 152 let requestId = btoa(this.getRequestId(request));
michael@0 153 this._requestMap[requestId] = window;
michael@0 154
michael@0 155 cpmm.sendAsyncMessage("NFC:ReadNDEF", {
michael@0 156 requestId: requestId,
michael@0 157 sessionToken: sessionToken
michael@0 158 });
michael@0 159 return request;
michael@0 160 },
michael@0 161
michael@0 162 writeNDEF: function writeNDEF(window, records, sessionToken) {
michael@0 163 if (window == null) {
michael@0 164 throw Components.Exception("Can't get window object",
michael@0 165 Cr.NS_ERROR_UNEXPECTED);
michael@0 166 }
michael@0 167 let request = Services.DOMRequest.createRequest(window);
michael@0 168 let requestId = btoa(this.getRequestId(request));
michael@0 169 this._requestMap[requestId] = window;
michael@0 170
michael@0 171 let encodedRecords = this.encodeNDEFRecords(records);
michael@0 172 cpmm.sendAsyncMessage("NFC:WriteNDEF", {
michael@0 173 requestId: requestId,
michael@0 174 sessionToken: sessionToken,
michael@0 175 records: encodedRecords
michael@0 176 });
michael@0 177 return request;
michael@0 178 },
michael@0 179
michael@0 180 makeReadOnlyNDEF: function makeReadOnlyNDEF(window, sessionToken) {
michael@0 181 if (window == null) {
michael@0 182 throw Components.Exception("Can't get window object",
michael@0 183 Cr.NS_ERROR_UNEXPECTED);
michael@0 184 }
michael@0 185
michael@0 186 let request = Services.DOMRequest.createRequest(window);
michael@0 187 let requestId = btoa(this.getRequestId(request));
michael@0 188 this._requestMap[requestId] = window;
michael@0 189
michael@0 190 cpmm.sendAsyncMessage("NFC:MakeReadOnlyNDEF", {
michael@0 191 requestId: requestId,
michael@0 192 sessionToken: sessionToken
michael@0 193 });
michael@0 194 return request;
michael@0 195 },
michael@0 196
michael@0 197 connect: function connect(window, techType, sessionToken) {
michael@0 198 if (window == null) {
michael@0 199 throw Components.Exception("Can't get window object",
michael@0 200 Cr.NS_ERROR_UNEXPECTED);
michael@0 201 }
michael@0 202 let request = Services.DOMRequest.createRequest(window);
michael@0 203 let requestId = btoa(this.getRequestId(request));
michael@0 204 this._requestMap[requestId] = window;
michael@0 205
michael@0 206 cpmm.sendAsyncMessage("NFC:Connect", {
michael@0 207 requestId: requestId,
michael@0 208 sessionToken: sessionToken,
michael@0 209 techType: techType
michael@0 210 });
michael@0 211 return request;
michael@0 212 },
michael@0 213
michael@0 214 close: function close(window, sessionToken) {
michael@0 215 if (window == null) {
michael@0 216 throw Components.Exception("Can't get window object",
michael@0 217 Cr.NS_ERROR_UNEXPECTED);
michael@0 218 }
michael@0 219 let request = Services.DOMRequest.createRequest(window);
michael@0 220 let requestId = btoa(this.getRequestId(request));
michael@0 221 this._requestMap[requestId] = window;
michael@0 222
michael@0 223 cpmm.sendAsyncMessage("NFC:Close", {
michael@0 224 requestId: requestId,
michael@0 225 sessionToken: sessionToken
michael@0 226 });
michael@0 227 return request;
michael@0 228 },
michael@0 229
michael@0 230 sendFile: function sendFile(window, data, sessionToken) {
michael@0 231 if (window == null) {
michael@0 232 throw Components.Exception("Can't get window object",
michael@0 233 Cr.NS_ERROR_UNEXPECTED);
michael@0 234 }
michael@0 235 let request = Services.DOMRequest.createRequest(window);
michael@0 236 let requestId = btoa(this.getRequestId(request));
michael@0 237 this._requestMap[requestId] = window;
michael@0 238
michael@0 239 cpmm.sendAsyncMessage("NFC:SendFile", {
michael@0 240 requestId: requestId,
michael@0 241 sessionToken: sessionToken,
michael@0 242 blob: data.blob
michael@0 243 });
michael@0 244 return request;
michael@0 245 },
michael@0 246
michael@0 247 notifySendFileStatus: function notifySendFileStatus(window, status,
michael@0 248 requestId) {
michael@0 249 if (window == null) {
michael@0 250 throw Components.Exception("Can't get window object",
michael@0 251 Cr.NS_ERROR_UNEXPECTED);
michael@0 252 }
michael@0 253
michael@0 254 cpmm.sendAsyncMessage("NFC:NotifySendFileStatus", {
michael@0 255 status: status,
michael@0 256 requestId: requestId
michael@0 257 });
michael@0 258 },
michael@0 259
michael@0 260 registerTargetForPeerEvent: function registerTargetForPeerEvent(window,
michael@0 261 appId, event, callback) {
michael@0 262 if (window == null) {
michael@0 263 throw Components.Exception("Can't get window object",
michael@0 264 Cr.NS_ERROR_UNEXPECTED);
michael@0 265 }
michael@0 266 this.peerEventsCallbackMap[event] = callback;
michael@0 267 cpmm.sendAsyncMessage("NFC:RegisterPeerTarget", {
michael@0 268 appId: appId,
michael@0 269 event: event
michael@0 270 });
michael@0 271 },
michael@0 272
michael@0 273 unregisterTargetForPeerEvent: function unregisterTargetForPeerEvent(window,
michael@0 274 appId, event) {
michael@0 275 if (window == null) {
michael@0 276 throw Components.Exception("Can't get window object",
michael@0 277 Cr.NS_ERROR_UNEXPECTED);
michael@0 278 }
michael@0 279 let callback = this.peerEventsCallbackMap[event];
michael@0 280 if (callback != null) {
michael@0 281 delete this.peerEventsCallbackMap[event];
michael@0 282 }
michael@0 283
michael@0 284 cpmm.sendAsyncMessage("NFC:UnregisterPeerTarget", {
michael@0 285 appId: appId,
michael@0 286 event: event
michael@0 287 });
michael@0 288 },
michael@0 289
michael@0 290 checkP2PRegistration: function checkP2PRegistration(window, appId) {
michael@0 291 if (window == null) {
michael@0 292 throw Components.Exception("Can't get window object",
michael@0 293 Cr.NS_ERROR_UNEXPECTED);
michael@0 294 }
michael@0 295 let request = Services.DOMRequest.createRequest(window);
michael@0 296 let requestId = btoa(this.getRequestId(request));
michael@0 297 this._requestMap[requestId] = window;
michael@0 298
michael@0 299 cpmm.sendAsyncMessage("NFC:CheckP2PRegistration", {
michael@0 300 appId: appId,
michael@0 301 requestId: requestId
michael@0 302 });
michael@0 303 return request;
michael@0 304 },
michael@0 305
michael@0 306 notifyUserAcceptedP2P: function notifyUserAcceptedP2P(window, appId) {
michael@0 307 if (window == null) {
michael@0 308 throw Components.Exception("Can't get window object",
michael@0 309 Cr.NS_ERROR_UNEXPECTED);
michael@0 310 }
michael@0 311
michael@0 312 cpmm.sendAsyncMessage("NFC:NotifyUserAcceptedP2P", {
michael@0 313 appId: appId
michael@0 314 });
michael@0 315 },
michael@0 316
michael@0 317 startPoll: function startPoll(window) {
michael@0 318 if (window == null) {
michael@0 319 throw Components.Exception("Can't get window object",
michael@0 320 Cr.NS_ERROR_UNEXPECTED);
michael@0 321 }
michael@0 322
michael@0 323 let request = Services.DOMRequest.createRequest(window);
michael@0 324 let requestId = btoa(this.getRequestId(request));
michael@0 325 this._requestMap[requestId] = window;
michael@0 326
michael@0 327 cpmm.sendAsyncMessage("NFC:StartPoll",
michael@0 328 {requestId: requestId});
michael@0 329 return request;
michael@0 330 },
michael@0 331
michael@0 332 stopPoll: function stopPoll(window) {
michael@0 333 if (window == null) {
michael@0 334 throw Components.Exception("Can't get window object",
michael@0 335 Cr.NS_ERROR_UNEXPECTED);
michael@0 336 }
michael@0 337
michael@0 338 let request = Services.DOMRequest.createRequest(window);
michael@0 339 let requestId = btoa(this.getRequestId(request));
michael@0 340 this._requestMap[requestId] = window;
michael@0 341
michael@0 342 cpmm.sendAsyncMessage("NFC:StopPoll",
michael@0 343 {requestId: requestId});
michael@0 344 return request;
michael@0 345 },
michael@0 346
michael@0 347 powerOff: function powerOff(window) {
michael@0 348 if (window == null) {
michael@0 349 throw Components.Exception("Can't get window object",
michael@0 350 Cr.NS_ERROR_UNEXPECTED);
michael@0 351 }
michael@0 352
michael@0 353 let request = Services.DOMRequest.createRequest(window);
michael@0 354 let requestId = btoa(this.getRequestId(request));
michael@0 355 this._requestMap[requestId] = window;
michael@0 356
michael@0 357 cpmm.sendAsyncMessage("NFC:PowerOff",
michael@0 358 {requestId: requestId});
michael@0 359 return request;
michael@0 360 },
michael@0 361
michael@0 362 // nsIObserver
michael@0 363 observe: function observe(subject, topic, data) {
michael@0 364 if (topic == "xpcom-shutdown") {
michael@0 365 this.destroyDOMRequestHelper();
michael@0 366 Services.obs.removeObserver(this, "xpcom-shutdown");
michael@0 367 cpmm = null;
michael@0 368 }
michael@0 369 },
michael@0 370
michael@0 371 // nsIMessageListener
michael@0 372
michael@0 373 fireRequestSuccess: function fireRequestSuccess(requestId, result) {
michael@0 374 let request = this.takeRequest(requestId);
michael@0 375 if (!request) {
michael@0 376 debug("not firing success for id: " + requestId +
michael@0 377 ", result: " + JSON.stringify(result));
michael@0 378 return;
michael@0 379 }
michael@0 380
michael@0 381 debug("fire request success, id: " + requestId +
michael@0 382 ", result: " + JSON.stringify(result));
michael@0 383 Services.DOMRequest.fireSuccess(request, result);
michael@0 384 },
michael@0 385
michael@0 386 fireRequestError: function fireRequestError(requestId, error) {
michael@0 387 let request = this.takeRequest(requestId);
michael@0 388 if (!request) {
michael@0 389 debug("not firing error for id: " + requestId +
michael@0 390 ", error: " + JSON.stringify(error));
michael@0 391 return;
michael@0 392 }
michael@0 393
michael@0 394 debug("fire request error, id: " + requestId +
michael@0 395 ", result: " + JSON.stringify(error));
michael@0 396 Services.DOMRequest.fireError(request, error);
michael@0 397 },
michael@0 398
michael@0 399 receiveMessage: function receiveMessage(message) {
michael@0 400 debug("Message received: " + JSON.stringify(message));
michael@0 401 let result = message.json;
michael@0 402
michael@0 403 switch (message.name) {
michael@0 404 case "NFC:ReadNDEFResponse":
michael@0 405 this.handleReadNDEFResponse(result);
michael@0 406 break;
michael@0 407 case "NFC:GetDetailsNDEFResponse":
michael@0 408 this.handleGetDetailsNDEFResponse(result);
michael@0 409 break;
michael@0 410 case "NFC:ConnectResponse": // Fall through.
michael@0 411 case "NFC:CloseResponse":
michael@0 412 case "NFC:WriteNDEFResponse":
michael@0 413 case "NFC:MakeReadOnlyNDEFResponse":
michael@0 414 case "NFC:CheckP2PRegistrationResponse":
michael@0 415 case "NFC:NotifySendFileStatusResponse":
michael@0 416 case "NFC:ConfigResponse":
michael@0 417 if (result.status !== NFC.GECKO_NFC_ERROR_SUCCESS) {
michael@0 418 this.fireRequestError(atob(result.requestId), result.status);
michael@0 419 } else {
michael@0 420 this.fireRequestSuccess(atob(result.requestId), result);
michael@0 421 }
michael@0 422 break;
michael@0 423 case "NFC:PeerEvent":
michael@0 424 let callback = this.peerEventsCallbackMap[result.event];
michael@0 425 if (callback) {
michael@0 426 callback.peerNotification(result.event, result.sessionToken);
michael@0 427 } else {
michael@0 428 debug("PeerEvent: No valid callback registered for the event " +
michael@0 429 result.event);
michael@0 430 }
michael@0 431 break;
michael@0 432 }
michael@0 433 },
michael@0 434
michael@0 435 handleReadNDEFResponse: function handleReadNDEFResponse(result) {
michael@0 436 let requester = this._requestMap[result.requestId];
michael@0 437 if (!requester) {
michael@0 438 debug("Response Invalid requestId=" + result.requestId);
michael@0 439 return;
michael@0 440 }
michael@0 441 delete this._requestMap[result.requestId];
michael@0 442
michael@0 443 if (result.status !== NFC.GECKO_NFC_ERROR_SUCCESS) {
michael@0 444 this.fireRequestError(atob(result.requestId), result.status);
michael@0 445 return;
michael@0 446 }
michael@0 447
michael@0 448 let requestId = atob(result.requestId);
michael@0 449 let ndefMsg = [];
michael@0 450 let records = result.records;
michael@0 451 for (let i = 0; i < records.length; i++) {
michael@0 452 let record = records[i];
michael@0 453 ndefMsg.push(new requester.MozNDEFRecord(record.tnf,
michael@0 454 record.type,
michael@0 455 record.id,
michael@0 456 record.payload));
michael@0 457 }
michael@0 458 this.fireRequestSuccess(requestId, ndefMsg);
michael@0 459 },
michael@0 460
michael@0 461 handleGetDetailsNDEFResponse: function handleGetDetailsNDEFResponse(result) {
michael@0 462 if (result.status !== NFC.GECKO_NFC_ERROR_SUCCESS) {
michael@0 463 this.fireRequestError(atob(result.requestId), result.status);
michael@0 464 return;
michael@0 465 }
michael@0 466
michael@0 467 let requestId = atob(result.requestId);
michael@0 468 let result = new GetDetailsNDEFResponse(result);
michael@0 469 this.fireRequestSuccess(requestId, result);
michael@0 470 },
michael@0 471 };
michael@0 472
michael@0 473 if (NFC_ENABLED) {
michael@0 474 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NfcContentHelper]);
michael@0 475 }

mercurial