mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 938993 - Support Multi-SIM for Payments. r=fabrice
This commit is contained in:
parent
8b14151b50
commit
ef48946890
@ -30,6 +30,10 @@ function LOG(s) {
|
||||
dump("== Payment flow == " + s + "\n");
|
||||
}
|
||||
|
||||
function LOGE(s) {
|
||||
dump("== Payment flow ERROR == " + s + "\n");
|
||||
}
|
||||
|
||||
if (_debug) {
|
||||
LOG("Frame script injected");
|
||||
}
|
||||
@ -43,6 +47,12 @@ XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
|
||||
"nsIUUIDGenerator");
|
||||
|
||||
#ifdef MOZ_B2G_RIL
|
||||
Cu.import('resource://gre/modules/ObjectWrapper.jsm');
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gRil",
|
||||
"@mozilla.org/ril;1",
|
||||
"nsIRadioInterfaceLayer");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "iccProvider",
|
||||
"@mozilla.org/ril/content-helper;1",
|
||||
"nsIIccProvider");
|
||||
@ -59,6 +69,7 @@ const kSilentSmsReceivedTopic = "silent-sms-received";
|
||||
const kMozSettingsChangedObserverTopic = "mozsettings-changed";
|
||||
|
||||
const kRilDefaultDataServiceId = "ril.data.defaultServiceId";
|
||||
const kRilDefaultPaymentServiceId = "ril.payment.defaultServiceId";
|
||||
|
||||
const MOBILEMESSAGECALLBACK_CID =
|
||||
Components.ID("{b484d8c9-6be4-4f94-ab60-c9c7ebcc853d}");
|
||||
@ -71,8 +82,8 @@ function SilentSmsRequest() {
|
||||
|
||||
SilentSmsRequest.prototype = {
|
||||
__exposedProps__: {
|
||||
onsuccess: 'rw',
|
||||
onerror: 'rw'
|
||||
onsuccess: "rw",
|
||||
onerror: "rw"
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileMessageCallback]),
|
||||
@ -95,33 +106,69 @@ SilentSmsRequest.prototype = {
|
||||
},
|
||||
|
||||
notifySendMessageFailed: function notifySendMessageFailed(aError) {
|
||||
if (_debug) {
|
||||
LOG("Error sending silent message " + aError);
|
||||
}
|
||||
LOGE("Error sending silent message " + aError);
|
||||
this._onerror(aError);
|
||||
}
|
||||
};
|
||||
|
||||
function PaymentSettings() {
|
||||
this.dataServiceId = 0;
|
||||
Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false);
|
||||
gSettingsService.createLock().get(kRilDefaultDataServiceId, this);
|
||||
|
||||
[kRilDefaultDataServiceId, kRilDefaultPaymentServiceId].forEach(setting => {
|
||||
gSettingsService.createLock().get(setting, this);
|
||||
});
|
||||
}
|
||||
|
||||
PaymentSettings.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISettingsServiceCallback,
|
||||
Ci.nsIObserver]),
|
||||
|
||||
dataServiceId: 0,
|
||||
_paymentServiceId: 0,
|
||||
|
||||
get paymentServiceId() {
|
||||
return this._paymentServiceId;
|
||||
},
|
||||
|
||||
set paymentServiceId(serviceId) {
|
||||
// We allow the payment provider to set the service ID that will be used
|
||||
// for the payment process.
|
||||
// This service ID will be the one used by the silent SMS flow.
|
||||
// If the payment is done with an external SIM, the service ID must be set
|
||||
// to null.
|
||||
if (serviceId != null && serviceId >= gRil.numRadioInterfaces) {
|
||||
LOGE("Invalid service ID " + serviceId);
|
||||
return;
|
||||
}
|
||||
|
||||
gSettingsService.createLock().set(kRilDefaultPaymentServiceId,
|
||||
serviceId, null);
|
||||
this._paymentServiceId = serviceId;
|
||||
},
|
||||
|
||||
setServiceId: function(aName, aValue) {
|
||||
switch (aName) {
|
||||
case kRilDefaultDataServiceId:
|
||||
this.dataServiceId = aValue;
|
||||
if (_debug) {
|
||||
LOG("dataServiceId " + this.dataServiceId);
|
||||
}
|
||||
break;
|
||||
case kRilDefaultPaymentServiceId:
|
||||
this._paymentServiceId = aValue;
|
||||
if (_debug) {
|
||||
LOG("paymentServiceId " + this._paymentServiceId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handle: function(aName, aValue) {
|
||||
if (aName != kRilDefaultDataServiceId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dataServiceId = aValue;
|
||||
|
||||
if (_debug) {
|
||||
LOG("dataServiceId " + this.dataServiceId);
|
||||
}
|
||||
this.setServiceId(aName, aValue);
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
@ -131,21 +178,15 @@ PaymentSettings.prototype = {
|
||||
|
||||
try {
|
||||
let setting = JSON.parse(aData);
|
||||
if (!setting.key || setting.key !== kRilDefaultDataServiceId) {
|
||||
if (!setting.key ||
|
||||
(setting.key !== kRilDefaultDataServiceId &&
|
||||
setting.key !== kRilDefaultPaymentServiceId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dataServiceId = setting.value;
|
||||
|
||||
if (_debug) {
|
||||
LOG("dataServiceId " + setting.value);
|
||||
}
|
||||
this.setServiceId(setting.key, setting.value);
|
||||
} catch (e) {
|
||||
if (_debug) {
|
||||
LOG(e);
|
||||
}
|
||||
LOGE(e);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
cleanup: function() {
|
||||
@ -163,19 +204,18 @@ let gBrowser = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let PaymentProvider = {
|
||||
#ifdef MOZ_B2G_RIL
|
||||
__exposedProps__: {
|
||||
paymentSuccess: 'r',
|
||||
paymentFailed: 'r',
|
||||
iccIds: 'r',
|
||||
mcc: 'r',
|
||||
mnc: 'r',
|
||||
sendSilentSms: 'r',
|
||||
observeSilentSms: 'r',
|
||||
removeSilentSmsObserver: 'r'
|
||||
paymentSuccess: "r",
|
||||
paymentFailed: "r",
|
||||
paymentServiceId: "rw",
|
||||
iccInfo: "r",
|
||||
sendSilentSms: "r",
|
||||
observeSilentSms: "r",
|
||||
removeSilentSmsObserver: "r"
|
||||
},
|
||||
#else
|
||||
__exposedProps__: {
|
||||
paymentSuccess: 'r',
|
||||
paymentFailed: 'r'
|
||||
paymentSuccess: "r",
|
||||
paymentFailed: "r"
|
||||
},
|
||||
#endif
|
||||
|
||||
@ -242,9 +282,7 @@ let PaymentProvider = {
|
||||
},
|
||||
|
||||
paymentFailed: function paymentFailed(aErrorMsg) {
|
||||
if (_debug) {
|
||||
LOG("paymentFailed " + aErrorMsg);
|
||||
}
|
||||
LOGE("paymentFailed " + aErrorMsg);
|
||||
|
||||
PaymentProvider._closePaymentFlowDialog(function notifyError() {
|
||||
if (!gRequestId) {
|
||||
@ -256,22 +294,45 @@ let PaymentProvider = {
|
||||
},
|
||||
|
||||
#ifdef MOZ_B2G_RIL
|
||||
// Bug 938993. Support Multi-SIM for Payments.
|
||||
get paymentServiceId() {
|
||||
return this._settings.paymentServiceId;
|
||||
},
|
||||
|
||||
set paymentServiceId(serviceId) {
|
||||
this._settings.paymentServiceId = serviceId;
|
||||
},
|
||||
|
||||
// We expose to the payment provider the information of all the SIMs
|
||||
// available in the device. iccInfo is an object of this form:
|
||||
// {
|
||||
// "serviceId1": {
|
||||
// mcc: <string>,
|
||||
// mnc: <string>,
|
||||
// iccId: <string>,
|
||||
// dataPrimary: <boolean>
|
||||
// },
|
||||
// "serviceIdN": {...}
|
||||
// }
|
||||
get iccInfo() {
|
||||
delete this.iccInfo;
|
||||
return this.iccInfo = iccProvider.getIccInfo(this._settings.dataServiceId);
|
||||
},
|
||||
if (!this._iccInfo) {
|
||||
this._iccInfo = {};
|
||||
for (let i = 0; i < gRil.numRadioInterfaces; i++) {
|
||||
let info = iccProvider.getIccInfo(i);
|
||||
if (!info) {
|
||||
LOGE("Tried to get the ICC info for an invalid service ID " + i);
|
||||
continue;
|
||||
}
|
||||
|
||||
get iccIds() {
|
||||
return [this.iccInfo.iccid];
|
||||
},
|
||||
this._iccInfo[i] = {
|
||||
iccId: info.iccid,
|
||||
mcc: info.mcc,
|
||||
mnc: info.mnc,
|
||||
dataPrimary: i == this._settings.dataServiceId
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
get mcc() {
|
||||
return [this.iccInfo.mcc];
|
||||
},
|
||||
|
||||
get mnc() {
|
||||
return [this.iccInfo.mnc];
|
||||
return ObjectWrapper.wrap(this._iccInfo, content);
|
||||
},
|
||||
|
||||
_silentNumbers: null,
|
||||
@ -283,7 +344,21 @@ let PaymentProvider = {
|
||||
}
|
||||
|
||||
let request = new SilentSmsRequest();
|
||||
smsService.send(aNumber, aMessage, true, request);
|
||||
|
||||
if (this._settings.paymentServiceId === null) {
|
||||
LOGE("No payment service ID set. Cannot send silent SMS");
|
||||
let runnable = {
|
||||
run: function run() {
|
||||
request.notifySendMessageFailed("NO_PAYMENT_SERVICE_ID");
|
||||
}
|
||||
};
|
||||
Services.tm.currentThread.dispatch(runnable,
|
||||
Ci.nsIThread.DISPATCH_NORMAL);
|
||||
return request;
|
||||
}
|
||||
|
||||
smsService.send(this._settings.paymentServiceId, aNumber, aMessage, true,
|
||||
request);
|
||||
return request;
|
||||
},
|
||||
|
||||
@ -349,6 +424,21 @@ let PaymentProvider = {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the service ID is null it means that the payment provider asked the
|
||||
// user for her MSISDN, so we are in a MT only SMS auth flow. In this case
|
||||
// we manually set the service ID to the one corresponding with the SIM
|
||||
// that received the SMS.
|
||||
if (this._settings.paymentServiceId === null) {
|
||||
let i = 0;
|
||||
while(i < gRil.numRadioInterfaces) {
|
||||
if (this.iccInfo[i].iccId === aSubject.iccId) {
|
||||
this._settings.paymentServiceId = i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
this._silentSmsObservers[number].forEach(function(callback) {
|
||||
callback(aSubject);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user