Files
palemoon27/dom/payment/PaymentProvider.js
T
roytam1 c6ee756140 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1190574 - make test.chain.replace and cohorts throw on unknown test name + fix broken tests. r=drno, r=jib (9288da531a)
- Bug 1190574 - added missing calls to release stored ICE candidates. r=jib (590e1f2769)
- Bug 1241948 - Update web-platform-tests expected data to revision 967dfa72eaa149af854c6c38cb64e28b4961a480, a=testonly (67bfe4dc02)
- Bug 1209744 - Implement canTrickleIceCandidates attribute, r=bwc,khuey (56f7db7415)
- Bug 1181768 - Make already-defined pc.getConfiguration() work. r=mt (d621edf192)
- Bug 1254839 - include file and line number in RTCPeerConnection warnings. r=bz (1f914d83b0)
- Bug 1243607: make webrtc bitrate prefs take precedence over automatic bitrate selection r=pkerr (655a6ebf1a)
- Bug 1242199: Add lower-limit WebRTC bandwidth pref for testing r=pkerr (40895a6821)
- Bug 1244913 - change SelectBandwidth to SelectBitrates. r=jesup (4952cb9143)
- Bug 1244913 - resolution-based bitrates for each simulcast layer, scaleResolutionDownBy, and working maxBitrate in unicast. r=bwc,jesup (cf40bb9c9f)
- Bug 1166832 - Add test to verify video (using capture stream) after renegotiation. r=bwc (adb0cd89cb)
- Bug 1250990 - Make RTCRtpEncodingParameters.scaleResolutionDownBy work with H.264 unicast. r=jesup (83eca85bb4)
- Bug 1237224: Check sending framesize is set before calculating max fps when max-mbps is negotiated r=pkerr (6910dbb65f)
- Bug 1198345 - Split moar Hello Telemetry values from general WebRTC. r=jesup (cc9b0c8059)
- Bug 1217677: increase UDP socket receive buffer for <= Win7. r=jesup, mcmanus (bd096afc64)
- Bug 1244638 - Part 3: Rename method from NotifyTimingUpdate to PostSpecifiedTimingUpdated. r=birtles (71fe98e0b2)
- Bug 1122236 - CSP: Implement block-all-mixed-content (r=tanvi,kate,mrbkap) (3fddc3166d)
- Bug 1229222 - add chromeutils for the creation of origin attributes with the correct default values. r=sicking (bf1e5673c0)
- Bug 1240651 - Annotate addonId into crash report (r=bholley) (4be5ef9e5e)
- Bug 1254906 - Change the annotation on JSPrincipals::dump's definition to match that of its declaration. r=bz (2e46a62057)
- Bug 1211590 - Inherits OriginAttributes from loading principal for GetChannelURIPrincipal. r=sicking (838147dbce)
- Bug 1251311. JS::DescribeScriptedCaller can't throw JS exceptions. Adjust some callers accordingly. r=khuey (2f3f111d74)
- Bug 1210703 - followup: fix test file used in caps and fix assertions to have actual/expected value in the right order, rs=bustage on a CLOSED TREE (548ddafc98)
- Bug 1208756 - Tests. r=billm (6b803253f2)
- Bug 1238160 - Test frame principal when toggling isolation. r=bz (a1954c14dd)
- Bug 1237141 - Make this test pass in e10s. r=felipe (32b8c1479f)
- var-let (1bb1fe779e)
- Bug 1207494 - Part 10: Remove use of expression closure from dom/json/. r=jst (668bf3efa8)
- Bug 1207494 - Part 9: Remove use of expression closure from dom/indexedDB/. r=khuey (8bf68b9afe)
- Bug 1043562 - Hide the Contacts API from the contexts that lack sufficient privileges, such as Firefox desktop and Android; r=smaug (dd78b59dda)
- Bug 1152114 - Ignore webapps with localId 0 (r=fabrice) (dbd208872b)
2024-03-05 00:49:35 +08:00

307 lines
9.2 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
const PREF_DEBUG = "dom.payment.debug";
var _debug;
try {
_debug = Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
&& Services.prefs.getBoolPref(PREF_DEBUG);
} catch(e) {
_debug = false;
}
function DEBUG(s) {
if (!_debug) {
return;
}
dump("== Payment Provider == " + s + "\n");
}
function DEBUG_E(s) {
dump("== Payment Provider ERROR == " + s + "\n");
}
const kPaymentFlowCancelled = "payment-flow-cancelled";
function PaymentProvider() {
}
PaymentProvider.prototype = {
init: function(aWindow) {
let docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
this._requestId = docshell.paymentRequestId;
this._oncancelObserver = this.oncancel.bind(this);
Services.obs.addObserver(this._oncancelObserver,
kPaymentFlowCancelled,
false);
this._strategy = Cc["@mozilla.org/payment/provider-strategy;1"]
.createInstance(Ci.nsIPaymentProviderStrategy);
this._window = aWindow;
},
paymentSuccess: function(aResult) {
_debug && DEBUG("paymentSuccess " + aResult);
let glue = Cc["@mozilla.org/payment/ui-glue;1"]
.createInstance(Ci.nsIPaymentUIGlue);
glue.closePaymentFlow(this._requestId).then(() => {
if (!this._requestId) {
return;
}
cpmm.sendAsyncMessage("Payment:Success", { result: aResult,
requestId: this._requestId });
});
},
paymentFailed: function(aError) {
_debug && DEBUG("paymentFailed " + aError);
let glue = Cc["@mozilla.org/payment/ui-glue;1"]
.createInstance(Ci.nsIPaymentUIGlue);
glue.closePaymentFlow(this._requestId).then(() => {
if (!this._requestId) {
return;
}
cpmm.sendAsyncMessage("Payment:Failed", { errorMsg: aError,
requestId: this._requestId });
});
},
get paymentServiceId() {
return this._strategy.paymentServiceId;
},
set paymentServiceId(aServiceId) {
this._strategy.paymentServiceId = aServiceId;
},
/**
* 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() {
return this._strategy.iccInfo;
},
oncancel: function() {
_debug && DEBUG("Cleaning up!");
this._strategy.cleanup();
Services.obs.removeObserver(this._oncancelObserver, kPaymentFlowCancelled);
if (this._cleanup) {
this._cleanup();
}
},
classID: Components.ID("{82144756-72ab-45b7-8621-f3dad431dd2f}"),
contractID: "@mozilla.org/payment/provider;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsIObserver,
Ci.nsIDOMGlobalPropertyInitializer])
};
#if defined(MOZ_B2G_RIL) || defined(MOZ_WIDGET_ANDROID)
XPCOMUtils.defineLazyServiceGetter(this, "smsService",
"@mozilla.org/sms/smsservice;1",
"nsISmsService");
const kSilentSmsReceivedTopic = "silent-sms-received";
// In order to send messages through nsISmsService, we need to implement
// nsIMobileMessageCallback, as the WebSMS API implementation is not usable
// from JS.
function SilentSmsRequest(aDOMRequest) {
this.request = aDOMRequest;
}
SilentSmsRequest.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileMessageCallback]),
classID: Components.ID("{1d58889c-5660-4cca-a8fd-97ef63e5d3b2}"),
notifyMessageSent: function notifyMessageSent(aMessage) {
_debug && DEBUG("Silent message successfully sent");
Services.DOMRequest.fireSuccessAsync(this.request, aMessage);
},
notifySendMessageFailed: function notifySendMessageFailed(aError) {
DEBUG_E("Error sending silent message " + aError);
Services.DOMRequest.fireErrorAsync(this.request, aError);
}
};
PaymentProvider.prototype._silentNumbers = null;
PaymentProvider.prototype._silentSmsObservers = null;
PaymentProvider.prototype.sendSilentSms = function(aNumber, aMessage) {
_debug && DEBUG("Sending silent message " + aNumber + " - " + aMessage);
let request = Services.DOMRequest.createRequest(this._window);
if (this._strategy.paymentServiceId === null) {
DEBUG_E("No payment service ID set. Cannot send silent SMS");
Services.DOMRequest.fireErrorAsync(request,
"NO_PAYMENT_SERVICE_ID");
return request;
}
let smsRequest = new SilentSmsRequest(request);
smsService.send(this._strategy.paymentServiceId, aNumber, aMessage, true,
smsRequest);
return request;
};
PaymentProvider.prototype.observeSilentSms = function(aNumber, aCallback) {
_debug && DEBUG("observeSilentSms " + aNumber);
if (!this._silentSmsObservers) {
this._silentSmsObservers = {};
this._silentNumbers = [];
this._onSilentSmsObserver = this._onSilentSms.bind(this);
Services.obs.addObserver(this._onSilentSmsObserver,
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);
}
return;
};
PaymentProvider.prototype.removeSilentSmsObserver = function(aNumber, aCallback) {
_debug && DEBUG("removeSilentSmsObserver " + aNumber);
if (!this._silentSmsObservers || !this._silentSmsObservers[aNumber]) {
_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);
}
return;
};
PaymentProvider.prototype._onSilentSms = function(aSubject, aTopic, aData) {
if (!aSubject || !(aSubject instanceof Ci.nsISmsMessage)) {
_debug && DEBUG("Invalid subject when receiving silent message!");
return;
}
let message = aSubject.QueryInterface(Ci.nsISmsMessage);
_debug && DEBUG("Got silent message! " + message.sender + " - " + message.body);
let number = message.sender;
if (!number || this._silentNumbers.indexOf(number) == -1) {
_debug && DEBUG("No observers for " + number);
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._strategy.paymentServiceId === null) {
let i = 0;
while(i < gRil.numRadioInterfaces) {
if (this.iccInfo[i].iccId === message.iccId) {
this._strategy.paymentServiceId = i;
break;
}
i++;
}
}
this._silentSmsObservers[number].forEach(function(callback) {
callback({
iccId: message.iccId,
sender: message.sender,
body: message.body,
timestamp: message.timestamp,
sentTimestamp: message.sentTimestamp
});
});
};
PaymentProvider.prototype._cleanup = function() {
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._onSilentSmsObserver,
kSilentSmsReceivedTopic);
};
#else
PaymentProvider.prototype.sendSilentSms = function(aNumber, aMessage) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
};
PaymentProvider.prototype.observeSilentSms = function(aNumber, aCallback) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
};
PaymentProvider.prototype.removeSilentSmsObserver = function(aNumber, aCallback) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
};
#endif
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentProvider]);