Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / |
michael@0 | 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | // This JS shim contains the callbacks to fire DOMRequest events for |
michael@0 | 8 | // navigator.pay API within the payment processor's scope. |
michael@0 | 9 | |
michael@0 | 10 | "use strict"; |
michael@0 | 11 | |
michael@0 | 12 | let { classes: Cc, interfaces: Ci, utils: Cu } = Components; |
michael@0 | 13 | Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
michael@0 | 14 | Cu.import("resource://gre/modules/Services.jsm"); |
michael@0 | 15 | |
michael@0 | 16 | const PREF_DEBUG = "dom.payment.debug"; |
michael@0 | 17 | |
michael@0 | 18 | let _debug; |
michael@0 | 19 | try { |
michael@0 | 20 | _debug = Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL |
michael@0 | 21 | && Services.prefs.getBoolPref(PREF_DEBUG); |
michael@0 | 22 | } catch(e){ |
michael@0 | 23 | _debug = false; |
michael@0 | 24 | } |
michael@0 | 25 | |
michael@0 | 26 | function LOG(s) { |
michael@0 | 27 | if (!_debug) { |
michael@0 | 28 | return; |
michael@0 | 29 | } |
michael@0 | 30 | dump("== Payment flow == " + s + "\n"); |
michael@0 | 31 | } |
michael@0 | 32 | |
michael@0 | 33 | function LOGE(s) { |
michael@0 | 34 | dump("== Payment flow ERROR == " + s + "\n"); |
michael@0 | 35 | } |
michael@0 | 36 | |
michael@0 | 37 | if (_debug) { |
michael@0 | 38 | LOG("Frame script injected"); |
michael@0 | 39 | } |
michael@0 | 40 | |
michael@0 | 41 | XPCOMUtils.defineLazyServiceGetter(this, "cpmm", |
michael@0 | 42 | "@mozilla.org/childprocessmessagemanager;1", |
michael@0 | 43 | "nsIMessageSender"); |
michael@0 | 44 | |
michael@0 | 45 | XPCOMUtils.defineLazyServiceGetter(this, "uuidgen", |
michael@0 | 46 | "@mozilla.org/uuid-generator;1", |
michael@0 | 47 | "nsIUUIDGenerator"); |
michael@0 | 48 | |
michael@0 | 49 | XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", |
michael@0 | 50 | "resource://gre/modules/SystemAppProxy.jsm"); |
michael@0 | 51 | |
michael@0 | 52 | #ifdef MOZ_B2G_RIL |
michael@0 | 53 | XPCOMUtils.defineLazyServiceGetter(this, "gRil", |
michael@0 | 54 | "@mozilla.org/ril;1", |
michael@0 | 55 | "nsIRadioInterfaceLayer"); |
michael@0 | 56 | |
michael@0 | 57 | XPCOMUtils.defineLazyServiceGetter(this, "iccProvider", |
michael@0 | 58 | "@mozilla.org/ril/content-helper;1", |
michael@0 | 59 | "nsIIccProvider"); |
michael@0 | 60 | |
michael@0 | 61 | XPCOMUtils.defineLazyServiceGetter(this, "smsService", |
michael@0 | 62 | "@mozilla.org/sms/smsservice;1", |
michael@0 | 63 | "nsISmsService"); |
michael@0 | 64 | |
michael@0 | 65 | XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", |
michael@0 | 66 | "@mozilla.org/settingsService;1", |
michael@0 | 67 | "nsISettingsService"); |
michael@0 | 68 | |
michael@0 | 69 | const kSilentSmsReceivedTopic = "silent-sms-received"; |
michael@0 | 70 | const kMozSettingsChangedObserverTopic = "mozsettings-changed"; |
michael@0 | 71 | |
michael@0 | 72 | const kRilDefaultDataServiceId = "ril.data.defaultServiceId"; |
michael@0 | 73 | const kRilDefaultPaymentServiceId = "ril.payment.defaultServiceId"; |
michael@0 | 74 | |
michael@0 | 75 | const MOBILEMESSAGECALLBACK_CID = |
michael@0 | 76 | Components.ID("{b484d8c9-6be4-4f94-ab60-c9c7ebcc853d}"); |
michael@0 | 77 | |
michael@0 | 78 | // In order to send messages through nsISmsService, we need to implement |
michael@0 | 79 | // nsIMobileMessageCallback, as the WebSMS API implementation is not usable |
michael@0 | 80 | // from JS. |
michael@0 | 81 | function SilentSmsRequest() { |
michael@0 | 82 | } |
michael@0 | 83 | |
michael@0 | 84 | SilentSmsRequest.prototype = { |
michael@0 | 85 | __exposedProps__: { |
michael@0 | 86 | onsuccess: "rw", |
michael@0 | 87 | onerror: "rw" |
michael@0 | 88 | }, |
michael@0 | 89 | |
michael@0 | 90 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileMessageCallback]), |
michael@0 | 91 | |
michael@0 | 92 | classID: MOBILEMESSAGECALLBACK_CID, |
michael@0 | 93 | |
michael@0 | 94 | set onsuccess(aSuccessCallback) { |
michael@0 | 95 | this._onsuccess = aSuccessCallback; |
michael@0 | 96 | }, |
michael@0 | 97 | |
michael@0 | 98 | set onerror(aErrorCallback) { |
michael@0 | 99 | this._onerror = aErrorCallback; |
michael@0 | 100 | }, |
michael@0 | 101 | |
michael@0 | 102 | notifyMessageSent: function notifyMessageSent(aMessage) { |
michael@0 | 103 | if (_debug) { |
michael@0 | 104 | LOG("Silent message successfully sent"); |
michael@0 | 105 | } |
michael@0 | 106 | this._onsuccess(aMessage); |
michael@0 | 107 | }, |
michael@0 | 108 | |
michael@0 | 109 | notifySendMessageFailed: function notifySendMessageFailed(aError) { |
michael@0 | 110 | LOGE("Error sending silent message " + aError); |
michael@0 | 111 | this._onerror(aError); |
michael@0 | 112 | } |
michael@0 | 113 | }; |
michael@0 | 114 | |
michael@0 | 115 | function PaymentSettings() { |
michael@0 | 116 | Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false); |
michael@0 | 117 | |
michael@0 | 118 | [kRilDefaultDataServiceId, kRilDefaultPaymentServiceId].forEach(setting => { |
michael@0 | 119 | gSettingsService.createLock().get(setting, this); |
michael@0 | 120 | }); |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | PaymentSettings.prototype = { |
michael@0 | 124 | QueryInterface: XPCOMUtils.generateQI([Ci.nsISettingsServiceCallback, |
michael@0 | 125 | Ci.nsIObserver]), |
michael@0 | 126 | |
michael@0 | 127 | dataServiceId: 0, |
michael@0 | 128 | _paymentServiceId: 0, |
michael@0 | 129 | |
michael@0 | 130 | get paymentServiceId() { |
michael@0 | 131 | return this._paymentServiceId; |
michael@0 | 132 | }, |
michael@0 | 133 | |
michael@0 | 134 | set paymentServiceId(serviceId) { |
michael@0 | 135 | // We allow the payment provider to set the service ID that will be used |
michael@0 | 136 | // for the payment process. |
michael@0 | 137 | // This service ID will be the one used by the silent SMS flow. |
michael@0 | 138 | // If the payment is done with an external SIM, the service ID must be set |
michael@0 | 139 | // to null. |
michael@0 | 140 | if (serviceId != null && serviceId >= gRil.numRadioInterfaces) { |
michael@0 | 141 | LOGE("Invalid service ID " + serviceId); |
michael@0 | 142 | return; |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | gSettingsService.createLock().set(kRilDefaultPaymentServiceId, |
michael@0 | 146 | serviceId, null); |
michael@0 | 147 | this._paymentServiceId = serviceId; |
michael@0 | 148 | }, |
michael@0 | 149 | |
michael@0 | 150 | setServiceId: function(aName, aValue) { |
michael@0 | 151 | switch (aName) { |
michael@0 | 152 | case kRilDefaultDataServiceId: |
michael@0 | 153 | this.dataServiceId = aValue; |
michael@0 | 154 | if (_debug) { |
michael@0 | 155 | LOG("dataServiceId " + this.dataServiceId); |
michael@0 | 156 | } |
michael@0 | 157 | break; |
michael@0 | 158 | case kRilDefaultPaymentServiceId: |
michael@0 | 159 | this._paymentServiceId = aValue; |
michael@0 | 160 | if (_debug) { |
michael@0 | 161 | LOG("paymentServiceId " + this._paymentServiceId); |
michael@0 | 162 | } |
michael@0 | 163 | break; |
michael@0 | 164 | } |
michael@0 | 165 | }, |
michael@0 | 166 | |
michael@0 | 167 | handle: function(aName, aValue) { |
michael@0 | 168 | if (aName != kRilDefaultDataServiceId) { |
michael@0 | 169 | return; |
michael@0 | 170 | } |
michael@0 | 171 | |
michael@0 | 172 | this.setServiceId(aName, aValue); |
michael@0 | 173 | }, |
michael@0 | 174 | |
michael@0 | 175 | observe: function(aSubject, aTopic, aData) { |
michael@0 | 176 | if (aTopic != kMozSettingsChangedObserverTopic) { |
michael@0 | 177 | return; |
michael@0 | 178 | } |
michael@0 | 179 | |
michael@0 | 180 | try { |
michael@0 | 181 | let setting = JSON.parse(aData); |
michael@0 | 182 | if (!setting.key || |
michael@0 | 183 | (setting.key !== kRilDefaultDataServiceId && |
michael@0 | 184 | setting.key !== kRilDefaultPaymentServiceId)) { |
michael@0 | 185 | return; |
michael@0 | 186 | } |
michael@0 | 187 | this.setServiceId(setting.key, setting.value); |
michael@0 | 188 | } catch (e) { |
michael@0 | 189 | LOGE(e); |
michael@0 | 190 | } |
michael@0 | 191 | }, |
michael@0 | 192 | |
michael@0 | 193 | cleanup: function() { |
michael@0 | 194 | Services.obs.removeObserver(this, kMozSettingsChangedObserverTopic); |
michael@0 | 195 | } |
michael@0 | 196 | }; |
michael@0 | 197 | #endif |
michael@0 | 198 | |
michael@0 | 199 | const kClosePaymentFlowEvent = "close-payment-flow-dialog"; |
michael@0 | 200 | |
michael@0 | 201 | let gRequestId; |
michael@0 | 202 | |
michael@0 | 203 | let PaymentProvider = { |
michael@0 | 204 | #ifdef MOZ_B2G_RIL |
michael@0 | 205 | __exposedProps__: { |
michael@0 | 206 | paymentSuccess: "r", |
michael@0 | 207 | paymentFailed: "r", |
michael@0 | 208 | paymentServiceId: "rw", |
michael@0 | 209 | iccInfo: "r", |
michael@0 | 210 | sendSilentSms: "r", |
michael@0 | 211 | observeSilentSms: "r", |
michael@0 | 212 | removeSilentSmsObserver: "r" |
michael@0 | 213 | }, |
michael@0 | 214 | #else |
michael@0 | 215 | __exposedProps__: { |
michael@0 | 216 | paymentSuccess: "r", |
michael@0 | 217 | paymentFailed: "r" |
michael@0 | 218 | }, |
michael@0 | 219 | #endif |
michael@0 | 220 | |
michael@0 | 221 | _init: function _init() { |
michael@0 | 222 | #ifdef MOZ_B2G_RIL |
michael@0 | 223 | this._settings = new PaymentSettings(); |
michael@0 | 224 | #endif |
michael@0 | 225 | }, |
michael@0 | 226 | |
michael@0 | 227 | _closePaymentFlowDialog: function _closePaymentFlowDialog(aCallback) { |
michael@0 | 228 | // After receiving the payment provider confirmation about the |
michael@0 | 229 | // successful or failed payment flow, we notify the UI to close the |
michael@0 | 230 | // payment flow dialog and return to the caller application. |
michael@0 | 231 | let id = kClosePaymentFlowEvent + "-" + uuidgen.generateUUID().toString(); |
michael@0 | 232 | |
michael@0 | 233 | let detail = { |
michael@0 | 234 | type: kClosePaymentFlowEvent, |
michael@0 | 235 | id: id, |
michael@0 | 236 | requestId: gRequestId |
michael@0 | 237 | }; |
michael@0 | 238 | |
michael@0 | 239 | // In order to avoid race conditions, we wait for the UI to notify that |
michael@0 | 240 | // it has successfully closed the payment flow and has recovered the |
michael@0 | 241 | // caller app, before notifying the parent process to fire the success |
michael@0 | 242 | // or error event over the DOMRequest. |
michael@0 | 243 | SystemAppProxy.addEventListener("mozContentEvent", |
michael@0 | 244 | function closePaymentFlowReturn(evt) { |
michael@0 | 245 | if (evt.detail.id == id && aCallback) { |
michael@0 | 246 | aCallback(); |
michael@0 | 247 | } |
michael@0 | 248 | |
michael@0 | 249 | SystemAppProxy.removeEventListener("mozContentEvent", |
michael@0 | 250 | closePaymentFlowReturn); |
michael@0 | 251 | |
michael@0 | 252 | let glue = Cc["@mozilla.org/payment/ui-glue;1"] |
michael@0 | 253 | .createInstance(Ci.nsIPaymentUIGlue); |
michael@0 | 254 | glue.cleanup(); |
michael@0 | 255 | }); |
michael@0 | 256 | |
michael@0 | 257 | SystemAppProxy.dispatchEvent(detail); |
michael@0 | 258 | |
michael@0 | 259 | #ifdef MOZ_B2G_RIL |
michael@0 | 260 | this._cleanUp(); |
michael@0 | 261 | #endif |
michael@0 | 262 | }, |
michael@0 | 263 | |
michael@0 | 264 | paymentSuccess: function paymentSuccess(aResult) { |
michael@0 | 265 | if (_debug) { |
michael@0 | 266 | LOG("paymentSuccess " + aResult); |
michael@0 | 267 | } |
michael@0 | 268 | |
michael@0 | 269 | PaymentProvider._closePaymentFlowDialog(function notifySuccess() { |
michael@0 | 270 | if (!gRequestId) { |
michael@0 | 271 | return; |
michael@0 | 272 | } |
michael@0 | 273 | cpmm.sendAsyncMessage("Payment:Success", { result: aResult, |
michael@0 | 274 | requestId: gRequestId }); |
michael@0 | 275 | }); |
michael@0 | 276 | }, |
michael@0 | 277 | |
michael@0 | 278 | paymentFailed: function paymentFailed(aErrorMsg) { |
michael@0 | 279 | LOGE("paymentFailed " + aErrorMsg); |
michael@0 | 280 | |
michael@0 | 281 | PaymentProvider._closePaymentFlowDialog(function notifyError() { |
michael@0 | 282 | if (!gRequestId) { |
michael@0 | 283 | return; |
michael@0 | 284 | } |
michael@0 | 285 | cpmm.sendAsyncMessage("Payment:Failed", { errorMsg: aErrorMsg, |
michael@0 | 286 | requestId: gRequestId }); |
michael@0 | 287 | }); |
michael@0 | 288 | }, |
michael@0 | 289 | |
michael@0 | 290 | #ifdef MOZ_B2G_RIL |
michael@0 | 291 | get paymentServiceId() { |
michael@0 | 292 | return this._settings.paymentServiceId; |
michael@0 | 293 | }, |
michael@0 | 294 | |
michael@0 | 295 | set paymentServiceId(serviceId) { |
michael@0 | 296 | this._settings.paymentServiceId = serviceId; |
michael@0 | 297 | }, |
michael@0 | 298 | |
michael@0 | 299 | // We expose to the payment provider the information of all the SIMs |
michael@0 | 300 | // available in the device. iccInfo is an object of this form: |
michael@0 | 301 | // { |
michael@0 | 302 | // "serviceId1": { |
michael@0 | 303 | // mcc: <string>, |
michael@0 | 304 | // mnc: <string>, |
michael@0 | 305 | // iccId: <string>, |
michael@0 | 306 | // dataPrimary: <boolean> |
michael@0 | 307 | // }, |
michael@0 | 308 | // "serviceIdN": {...} |
michael@0 | 309 | // } |
michael@0 | 310 | get iccInfo() { |
michael@0 | 311 | if (!this._iccInfo) { |
michael@0 | 312 | this._iccInfo = {}; |
michael@0 | 313 | for (let i = 0; i < gRil.numRadioInterfaces; i++) { |
michael@0 | 314 | let info = iccProvider.getIccInfo(i); |
michael@0 | 315 | if (!info) { |
michael@0 | 316 | LOGE("Tried to get the ICC info for an invalid service ID " + i); |
michael@0 | 317 | continue; |
michael@0 | 318 | } |
michael@0 | 319 | |
michael@0 | 320 | this._iccInfo[i] = { |
michael@0 | 321 | iccId: info.iccid, |
michael@0 | 322 | mcc: info.mcc, |
michael@0 | 323 | mnc: info.mnc, |
michael@0 | 324 | dataPrimary: i == this._settings.dataServiceId |
michael@0 | 325 | }; |
michael@0 | 326 | } |
michael@0 | 327 | } |
michael@0 | 328 | |
michael@0 | 329 | return Cu.cloneInto(this._iccInfo, content); |
michael@0 | 330 | }, |
michael@0 | 331 | |
michael@0 | 332 | _silentNumbers: null, |
michael@0 | 333 | _silentSmsObservers: null, |
michael@0 | 334 | |
michael@0 | 335 | sendSilentSms: function sendSilentSms(aNumber, aMessage) { |
michael@0 | 336 | if (_debug) { |
michael@0 | 337 | LOG("Sending silent message " + aNumber + " - " + aMessage); |
michael@0 | 338 | } |
michael@0 | 339 | |
michael@0 | 340 | let request = new SilentSmsRequest(); |
michael@0 | 341 | |
michael@0 | 342 | if (this._settings.paymentServiceId === null) { |
michael@0 | 343 | LOGE("No payment service ID set. Cannot send silent SMS"); |
michael@0 | 344 | let runnable = { |
michael@0 | 345 | run: function run() { |
michael@0 | 346 | request.notifySendMessageFailed("NO_PAYMENT_SERVICE_ID"); |
michael@0 | 347 | } |
michael@0 | 348 | }; |
michael@0 | 349 | Services.tm.currentThread.dispatch(runnable, |
michael@0 | 350 | Ci.nsIThread.DISPATCH_NORMAL); |
michael@0 | 351 | return request; |
michael@0 | 352 | } |
michael@0 | 353 | |
michael@0 | 354 | smsService.send(this._settings.paymentServiceId, aNumber, aMessage, true, |
michael@0 | 355 | request); |
michael@0 | 356 | return request; |
michael@0 | 357 | }, |
michael@0 | 358 | |
michael@0 | 359 | observeSilentSms: function observeSilentSms(aNumber, aCallback) { |
michael@0 | 360 | if (_debug) { |
michael@0 | 361 | LOG("observeSilentSms " + aNumber); |
michael@0 | 362 | } |
michael@0 | 363 | |
michael@0 | 364 | if (!this._silentSmsObservers) { |
michael@0 | 365 | this._silentSmsObservers = {}; |
michael@0 | 366 | this._silentNumbers = []; |
michael@0 | 367 | Services.obs.addObserver(this._onSilentSms.bind(this), |
michael@0 | 368 | kSilentSmsReceivedTopic, |
michael@0 | 369 | false); |
michael@0 | 370 | } |
michael@0 | 371 | |
michael@0 | 372 | if (!this._silentSmsObservers[aNumber]) { |
michael@0 | 373 | this._silentSmsObservers[aNumber] = []; |
michael@0 | 374 | this._silentNumbers.push(aNumber); |
michael@0 | 375 | smsService.addSilentNumber(aNumber); |
michael@0 | 376 | } |
michael@0 | 377 | |
michael@0 | 378 | if (this._silentSmsObservers[aNumber].indexOf(aCallback) == -1) { |
michael@0 | 379 | this._silentSmsObservers[aNumber].push(aCallback); |
michael@0 | 380 | } |
michael@0 | 381 | }, |
michael@0 | 382 | |
michael@0 | 383 | removeSilentSmsObserver: function removeSilentSmsObserver(aNumber, aCallback) { |
michael@0 | 384 | if (_debug) { |
michael@0 | 385 | LOG("removeSilentSmsObserver " + aNumber); |
michael@0 | 386 | } |
michael@0 | 387 | |
michael@0 | 388 | if (!this._silentSmsObservers || !this._silentSmsObservers[aNumber]) { |
michael@0 | 389 | if (_debug) { |
michael@0 | 390 | LOG("No observers for " + aNumber); |
michael@0 | 391 | } |
michael@0 | 392 | return; |
michael@0 | 393 | } |
michael@0 | 394 | |
michael@0 | 395 | let index = this._silentSmsObservers[aNumber].indexOf(aCallback); |
michael@0 | 396 | if (index != -1) { |
michael@0 | 397 | this._silentSmsObservers[aNumber].splice(index, 1); |
michael@0 | 398 | if (this._silentSmsObservers[aNumber].length == 0) { |
michael@0 | 399 | this._silentSmsObservers[aNumber] = null; |
michael@0 | 400 | this._silentNumbers.splice(this._silentNumbers.indexOf(aNumber), 1); |
michael@0 | 401 | smsService.removeSilentNumber(aNumber); |
michael@0 | 402 | } |
michael@0 | 403 | } else if (_debug) { |
michael@0 | 404 | LOG("No callback found for " + aNumber); |
michael@0 | 405 | } |
michael@0 | 406 | }, |
michael@0 | 407 | |
michael@0 | 408 | _onSilentSms: function _onSilentSms(aSubject, aTopic, aData) { |
michael@0 | 409 | if (_debug) { |
michael@0 | 410 | LOG("Got silent message! " + aSubject.sender + " - " + aSubject.body); |
michael@0 | 411 | } |
michael@0 | 412 | |
michael@0 | 413 | let number = aSubject.sender; |
michael@0 | 414 | if (!number || this._silentNumbers.indexOf(number) == -1) { |
michael@0 | 415 | if (_debug) { |
michael@0 | 416 | LOG("No observers for " + number); |
michael@0 | 417 | } |
michael@0 | 418 | return; |
michael@0 | 419 | } |
michael@0 | 420 | |
michael@0 | 421 | // If the service ID is null it means that the payment provider asked the |
michael@0 | 422 | // user for her MSISDN, so we are in a MT only SMS auth flow. In this case |
michael@0 | 423 | // we manually set the service ID to the one corresponding with the SIM |
michael@0 | 424 | // that received the SMS. |
michael@0 | 425 | if (this._settings.paymentServiceId === null) { |
michael@0 | 426 | let i = 0; |
michael@0 | 427 | while(i < gRil.numRadioInterfaces) { |
michael@0 | 428 | if (this.iccInfo[i].iccId === aSubject.iccId) { |
michael@0 | 429 | this._settings.paymentServiceId = i; |
michael@0 | 430 | break; |
michael@0 | 431 | } |
michael@0 | 432 | i++; |
michael@0 | 433 | } |
michael@0 | 434 | } |
michael@0 | 435 | |
michael@0 | 436 | this._silentSmsObservers[number].forEach(function(callback) { |
michael@0 | 437 | callback(aSubject); |
michael@0 | 438 | }); |
michael@0 | 439 | }, |
michael@0 | 440 | |
michael@0 | 441 | _cleanUp: function _cleanUp() { |
michael@0 | 442 | if (_debug) { |
michael@0 | 443 | LOG("Cleaning up!"); |
michael@0 | 444 | } |
michael@0 | 445 | |
michael@0 | 446 | if (!this._silentNumbers) { |
michael@0 | 447 | return; |
michael@0 | 448 | } |
michael@0 | 449 | |
michael@0 | 450 | while (this._silentNumbers.length) { |
michael@0 | 451 | let number = this._silentNumbers.pop(); |
michael@0 | 452 | smsService.removeSilentNumber(number); |
michael@0 | 453 | } |
michael@0 | 454 | this._silentNumbers = null; |
michael@0 | 455 | this._silentSmsObservers = null; |
michael@0 | 456 | this._settings.cleanup(); |
michael@0 | 457 | Services.obs.removeObserver(this._onSilentSms, kSilentSmsReceivedTopic); |
michael@0 | 458 | } |
michael@0 | 459 | #endif |
michael@0 | 460 | }; |
michael@0 | 461 | |
michael@0 | 462 | // We save the identifier of the DOM request, so we can dispatch the results |
michael@0 | 463 | // of the payment flow to the appropriate content process. |
michael@0 | 464 | addMessageListener("Payment:LoadShim", function receiveMessage(aMessage) { |
michael@0 | 465 | gRequestId = aMessage.json.requestId; |
michael@0 | 466 | PaymentProvider._init(); |
michael@0 | 467 | }); |
michael@0 | 468 | |
michael@0 | 469 | addEventListener("DOMWindowCreated", function(e) { |
michael@0 | 470 | content.wrappedJSObject.mozPaymentProvider = PaymentProvider; |
michael@0 | 471 | }); |
michael@0 | 472 | |
michael@0 | 473 | #ifdef MOZ_B2G_RIL |
michael@0 | 474 | // If the trusted dialog is not closed via paymentSuccess or paymentFailed |
michael@0 | 475 | // a mozContentEvent with type 'cancel' is sent from the UI. We need to listen |
michael@0 | 476 | // for this event to clean up the silent sms observers if any exists. |
michael@0 | 477 | SystemAppProxy.addEventListener("mozContentEvent", function(e) { |
michael@0 | 478 | if (e.detail.type === "cancel") { |
michael@0 | 479 | PaymentProvider._cleanUp(); |
michael@0 | 480 | } |
michael@0 | 481 | }); |
michael@0 | 482 | #endif |