mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 816564 - Silent SMS to Authenticate Device for Mobile Billing. Part 2: mozPaymentProvider. r=vicamo, fabrice
This commit is contained in:
parent
85874f9c69
commit
9453005d41
@ -9,10 +9,13 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
dump("======================= payment.js ======================= \n");
|
||||
let _DEBUG = false;
|
||||
function _debug(s) { dump("== Payment flow == " + s + "\n"); }
|
||||
_debug("Frame script injected");
|
||||
|
||||
let { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
@ -26,20 +29,77 @@ XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "mobileConnection",
|
||||
"@mozilla.org/ril/content-helper;1",
|
||||
"nsIMobileConnectionProvider");
|
||||
#endif
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "smsService",
|
||||
"@mozilla.org/sms/smsservice;1",
|
||||
"nsISmsService");
|
||||
|
||||
const kSilentSmsReceivedTopic = "silent-sms-received";
|
||||
|
||||
const MOBILEMESSAGECALLBACK_CID =
|
||||
Components.ID("{b484d8c9-6be4-4f94-ab60-c9c7ebcc853d}");
|
||||
|
||||
// In order to send messages through nsISmsService, we need to implement
|
||||
// nsIMobileMessageCallback, as the WebSMS API implementation is not usable
|
||||
// from JS.
|
||||
function SilentSmsRequest() {
|
||||
}
|
||||
SilentSmsRequest.prototype = {
|
||||
__exposedProps__: {
|
||||
onsuccess: 'rw',
|
||||
onerror: 'rw'
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileMessageCallback]),
|
||||
|
||||
classID: MOBILEMESSAGECALLBACK_CID,
|
||||
|
||||
set onsuccess(aSuccessCallback) {
|
||||
this._onsuccess = aSuccessCallback;
|
||||
},
|
||||
|
||||
set onerror(aErrorCallback) {
|
||||
this._onerror = aErrorCallback;
|
||||
},
|
||||
|
||||
notifyMessageSent: function notifyMessageSent(aMessage) {
|
||||
if (_DEBUG) {
|
||||
_debug("Silent message successfully sent");
|
||||
}
|
||||
this._onsuccess(aMessage);
|
||||
},
|
||||
|
||||
notifySendMessageFailed: function notifySendMessageFailed(aError) {
|
||||
if (_DEBUG) {
|
||||
_debug("Error sending silent message " + aError);
|
||||
}
|
||||
this._onerror(aError);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
const kClosePaymentFlowEvent = "close-payment-flow-dialog";
|
||||
|
||||
let _requestId;
|
||||
let gRequestId;
|
||||
|
||||
let gBrowser = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
|
||||
let PaymentProvider = {
|
||||
|
||||
#ifdef MOZ_B2G_RIL
|
||||
__exposedProps__: {
|
||||
paymentSuccess: 'r',
|
||||
paymentFailed: 'r',
|
||||
iccIds: 'r'
|
||||
iccIds: 'r',
|
||||
sendSilentSms: 'r',
|
||||
observeSilentSms: 'r',
|
||||
removeSilentSmsObserver: 'r'
|
||||
},
|
||||
#else
|
||||
__exposedProps__: {
|
||||
paymentSuccess: 'r',
|
||||
paymentFailed: 'r'
|
||||
},
|
||||
#endif
|
||||
|
||||
_closePaymentFlowDialog: function _closePaymentFlowDialog(aCallback) {
|
||||
// After receiving the payment provider confirmation about the
|
||||
@ -47,8 +107,7 @@ let PaymentProvider = {
|
||||
// payment flow dialog and return to the caller application.
|
||||
let id = kClosePaymentFlowEvent + "-" + uuidgen.generateUUID().toString();
|
||||
|
||||
let browser = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let content = browser.getContentWindow();
|
||||
let content = gBrowser.getContentWindow();
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
@ -56,7 +115,7 @@ let PaymentProvider = {
|
||||
let detail = {
|
||||
type: kClosePaymentFlowEvent,
|
||||
id: id,
|
||||
requestId: _requestId
|
||||
requestId: gRequestId
|
||||
};
|
||||
|
||||
// In order to avoid race conditions, we wait for the UI to notify that
|
||||
@ -77,49 +136,167 @@ let PaymentProvider = {
|
||||
glue.cleanup();
|
||||
});
|
||||
|
||||
browser.shell.sendChromeEvent(detail);
|
||||
gBrowser.shell.sendChromeEvent(detail);
|
||||
|
||||
#ifdef MOZ_B2G_RIL
|
||||
this._cleanUp();
|
||||
#endif
|
||||
},
|
||||
|
||||
paymentSuccess: function paymentSuccess(aResult) {
|
||||
if (_DEBUG) {
|
||||
_debug("paymentSuccess " + aResult);
|
||||
}
|
||||
|
||||
PaymentProvider._closePaymentFlowDialog(function notifySuccess() {
|
||||
if (!_requestId) {
|
||||
if (!gRequestId) {
|
||||
return;
|
||||
}
|
||||
cpmm.sendAsyncMessage("Payment:Success", { result: aResult,
|
||||
requestId: _requestId });
|
||||
requestId: gRequestId });
|
||||
});
|
||||
},
|
||||
|
||||
paymentFailed: function paymentFailed(aErrorMsg) {
|
||||
if (_DEBUG) {
|
||||
_debug("paymentFailed " + aErrorMsg);
|
||||
}
|
||||
|
||||
PaymentProvider._closePaymentFlowDialog(function notifyError() {
|
||||
if (!_requestId) {
|
||||
if (!gRequestId) {
|
||||
return;
|
||||
}
|
||||
cpmm.sendAsyncMessage("Payment:Failed", { errorMsg: aErrorMsg,
|
||||
requestId: _requestId });
|
||||
requestId: gRequestId });
|
||||
});
|
||||
},
|
||||
|
||||
get iccIds() {
|
||||
#ifdef MOZ_B2G_RIL
|
||||
get iccIds() {
|
||||
// Until bug 814629 is done, we only have support for a single SIM, so we
|
||||
// can only provide a single ICC ID. However, we return an array so the
|
||||
// payment provider facing API won't need to change once we support
|
||||
// multiple SIMs.
|
||||
return [mobileConnection.iccInfo.iccid];
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
},
|
||||
|
||||
_silentNumbers: null,
|
||||
_silentSmsObservers: null,
|
||||
|
||||
sendSilentSms: function sendSilentSms(aNumber, aMessage) {
|
||||
if (_DEBUG) {
|
||||
_debug("Sending silent message " + aNumber + " - " + aMessage);
|
||||
}
|
||||
|
||||
let request = new SilentSmsRequest();
|
||||
smsService.send(aNumber, aMessage, true, request);
|
||||
return request;
|
||||
},
|
||||
|
||||
observeSilentSms: function observeSilentSms(aNumber, aCallback) {
|
||||
if (_DEBUG) {
|
||||
_debug("observeSilentSms " + aNumber);
|
||||
}
|
||||
|
||||
if (!this._silentSmsObservers) {
|
||||
this._silentSmsObservers = {};
|
||||
this._silentNumbers = [];
|
||||
Services.obs.addObserver(this._onSilentSms.bind(this),
|
||||
kSilentSmsReceivedTopic,
|
||||
false);
|
||||
}
|
||||
|
||||
if (!this._silentSmsObservers[aNumber]) {
|
||||
this._silentSmsObservers[aNumber] = [];
|
||||
this._silentNumbers.push(aNumber);
|
||||
smsService.addSilentNumber(aNumber);
|
||||
}
|
||||
|
||||
if (this._silentSmsObservers[aNumber].indexOf(aCallback) == -1) {
|
||||
this._silentSmsObservers[aNumber].push(aCallback);
|
||||
}
|
||||
},
|
||||
|
||||
removeSilentSmsObserver: function removeSilentSmsObserver(aNumber, aCallback) {
|
||||
if (_DEBUG) {
|
||||
_debug("removeSilentSmsObserver " + aNumber);
|
||||
}
|
||||
|
||||
if (!this._silentSmsObservers || !this._silentSmsObservers[aNumber]) {
|
||||
if (_DEBUG) {
|
||||
_debug("No observers for " + aNumber);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let index = this._silentSmsObservers[aNumber].indexOf(aCallback);
|
||||
if (index != -1) {
|
||||
this._silentSmsObservers[aNumber].splice(index, 1);
|
||||
if (this._silentSmsObservers[aNumber].length == 0) {
|
||||
this._silentSmsObservers[aNumber] = null;
|
||||
this._silentNumbers.splice(this._silentNumbers.indexOf(aNumber), 1);
|
||||
smsService.removeSilentNumber(aNumber);
|
||||
}
|
||||
} else if (_DEBUG) {
|
||||
_debug("No callback found for " + aNumber);
|
||||
}
|
||||
},
|
||||
|
||||
_onSilentSms: function _onSilentSms(aSubject, aTopic, aData) {
|
||||
if (_DEBUG) {
|
||||
_debug("Got silent message! " + aSubject.sender + " - " + aSubject.body);
|
||||
}
|
||||
|
||||
let number = aSubject.sender;
|
||||
if (!number || this._silentNumbers.indexOf(number) == -1) {
|
||||
if (_DEBUG) {
|
||||
_debug("No observers for " + number);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._silentSmsObservers[number].forEach(function(callback) {
|
||||
callback(aSubject);
|
||||
});
|
||||
},
|
||||
|
||||
_cleanUp: function _cleanUp() {
|
||||
if (_DEBUG) {
|
||||
_debug("Cleaning up!");
|
||||
}
|
||||
|
||||
if (!this._silentNumbers) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (this._silentNumbers.length) {
|
||||
let number = this._silentNumbers.pop();
|
||||
smsService.removeSilentNumber(number);
|
||||
}
|
||||
this._silentNumbers = null;
|
||||
this._silentSmsObservers = null;
|
||||
Services.obs.removeObserver(this._onSilentSms, kSilentSmsReceivedTopic);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// We save the identifier of the DOM request, so we can dispatch the results
|
||||
// of the payment flow to the appropriate content process.
|
||||
addMessageListener("Payment:LoadShim", function receiveMessage(aMessage) {
|
||||
_requestId = aMessage.json.requestId;
|
||||
gRequestId = aMessage.json.requestId;
|
||||
});
|
||||
|
||||
addEventListener("DOMWindowCreated", function(e) {
|
||||
content.wrappedJSObject.mozPaymentProvider = PaymentProvider;
|
||||
});
|
||||
|
||||
#ifdef MOZ_B2G_RIL
|
||||
// If the trusted dialog is not closed via paymentSuccess or paymentFailed
|
||||
// a mozContentEvent with type 'cancel' is sent from the UI. We need to listen
|
||||
// for this event to clean up the silent sms observers if any exists.
|
||||
gBrowser.getContentWindow().addEventListener("mozContentEvent", function(e) {
|
||||
if (e.detail.type === "cancel") {
|
||||
PaymentProvider._cleanUp();
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user