b2g/components/PaymentGlue.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 "use strict";
michael@0 6
michael@0 7 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
michael@0 8
michael@0 9 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 10 Cu.import("resource://gre/modules/Services.jsm");
michael@0 11
michael@0 12 // JS shim that contains the callback functions to be triggered from the
michael@0 13 // payment provider's code in order to fire DOMRequest events.
michael@0 14 const kPaymentShimFile = "chrome://b2g/content/payment.js";
michael@0 15
michael@0 16 // Type of MozChromEvents to handle payment dialogs.
michael@0 17 const kOpenPaymentConfirmationEvent = "open-payment-confirmation-dialog";
michael@0 18 const kOpenPaymentFlowEvent = "open-payment-flow-dialog";
michael@0 19
michael@0 20 const PREF_DEBUG = "dom.payment.debug";
michael@0 21
michael@0 22 XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
michael@0 23 "@mozilla.org/uuid-generator;1",
michael@0 24 "nsIUUIDGenerator");
michael@0 25
michael@0 26 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
michael@0 27 "resource://gre/modules/SystemAppProxy.jsm");
michael@0 28
michael@0 29 function PaymentUI() {
michael@0 30 try {
michael@0 31 this._debug =
michael@0 32 Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
michael@0 33 && Services.prefs.getBoolPref(PREF_DEBUG);
michael@0 34 } catch(e) {
michael@0 35 this._debug = false;
michael@0 36 }
michael@0 37 }
michael@0 38
michael@0 39 PaymentUI.prototype = {
michael@0 40
michael@0 41 confirmPaymentRequest: function confirmPaymentRequest(aRequestId,
michael@0 42 aRequests,
michael@0 43 aSuccessCb,
michael@0 44 aErrorCb) {
michael@0 45 let _error = function _error(errorMsg) {
michael@0 46 if (aErrorCb) {
michael@0 47 aErrorCb.onresult(aRequestId, errorMsg);
michael@0 48 }
michael@0 49 };
michael@0 50
michael@0 51 // The UI should listen for mozChromeEvent 'open-payment-confirmation-dialog'
michael@0 52 // type in order to create and show the payment request confirmation frame
michael@0 53 // embeded within a trusted dialog.
michael@0 54 let id = kOpenPaymentConfirmationEvent + "-" + this.getRandomId();
michael@0 55 let detail = {
michael@0 56 type: kOpenPaymentConfirmationEvent,
michael@0 57 id: id,
michael@0 58 requestId: aRequestId,
michael@0 59 paymentRequests: aRequests
michael@0 60 };
michael@0 61
michael@0 62 // Once the user confirm the payment request and makes his choice, we get
michael@0 63 // back to the DOM part to get the appropriate payment flow information
michael@0 64 // based on the selected payment provider.
michael@0 65 this._handleSelection = (function _handleSelection(evt) {
michael@0 66 let msg = evt.detail;
michael@0 67 if (msg.id != id) {
michael@0 68 return;
michael@0 69 }
michael@0 70
michael@0 71 if (msg.userSelection && aSuccessCb) {
michael@0 72 aSuccessCb.onresult(aRequestId, msg.userSelection);
michael@0 73 } else if (msg.errorMsg) {
michael@0 74 _error(msg.errorMsg);
michael@0 75 }
michael@0 76
michael@0 77 SystemAppProxy.removeEventListener("mozContentEvent", this._handleSelection);
michael@0 78 this._handleSelection = null;
michael@0 79 }).bind(this);
michael@0 80 SystemAppProxy.addEventListener("mozContentEvent", this._handleSelection);
michael@0 81
michael@0 82 SystemAppProxy.dispatchEvent(detail);
michael@0 83 },
michael@0 84
michael@0 85 showPaymentFlow: function showPaymentFlow(aRequestId,
michael@0 86 aPaymentFlowInfo,
michael@0 87 aErrorCb) {
michael@0 88 let _error = function _error(errorMsg) {
michael@0 89 if (aErrorCb) {
michael@0 90 aErrorCb.onresult(aRequestId, errorMsg);
michael@0 91 }
michael@0 92 };
michael@0 93
michael@0 94 // We ask the UI to browse to the selected payment flow.
michael@0 95 let id = kOpenPaymentFlowEvent + "-" + this.getRandomId();
michael@0 96 let detail = {
michael@0 97 type: kOpenPaymentFlowEvent,
michael@0 98 id: id,
michael@0 99 requestId: aRequestId,
michael@0 100 uri: aPaymentFlowInfo.uri,
michael@0 101 method: aPaymentFlowInfo.requestMethod,
michael@0 102 jwt: aPaymentFlowInfo.jwt
michael@0 103 };
michael@0 104
michael@0 105 // At some point the UI would send the created iframe back so the
michael@0 106 // callbacks for firing DOMRequest events can be loaded on its
michael@0 107 // content.
michael@0 108 this._loadPaymentShim = (function _loadPaymentShim(evt) {
michael@0 109 let msg = evt.detail;
michael@0 110 if (msg.id != id) {
michael@0 111 return;
michael@0 112 }
michael@0 113
michael@0 114 if (msg.errorMsg) {
michael@0 115 SystemAppProxy.removeEventListener("mozContentEvent", this._loadPaymentShim);
michael@0 116 this._loadPaymentShim = null;
michael@0 117 _error("ERROR_LOADING_PAYMENT_SHIM: " + msg.errorMsg);
michael@0 118 return;
michael@0 119 }
michael@0 120
michael@0 121 if (!msg.frame) {
michael@0 122 SystemAppProxy.removeEventListener("mozContentEvent", this._loadPaymentShim);
michael@0 123 this._loadPaymentShim = null;
michael@0 124 _error("ERROR_LOADING_PAYMENT_SHIM");
michael@0 125 return;
michael@0 126 }
michael@0 127
michael@0 128 // Try to load the payment shim file containing the payment callbacks
michael@0 129 // in the content script.
michael@0 130 let frame = msg.frame;
michael@0 131 let frameLoader = frame.QueryInterface(Ci.nsIFrameLoaderOwner)
michael@0 132 .frameLoader;
michael@0 133 let mm = frameLoader.messageManager;
michael@0 134 try {
michael@0 135 mm.loadFrameScript(kPaymentShimFile, true, true);
michael@0 136 mm.sendAsyncMessage("Payment:LoadShim", { requestId: aRequestId });
michael@0 137 } catch (e) {
michael@0 138 if (this._debug) {
michael@0 139 this.LOG("Error loading " + kPaymentShimFile + " as a frame script: "
michael@0 140 + e);
michael@0 141 }
michael@0 142 _error("ERROR_LOADING_PAYMENT_SHIM");
michael@0 143 } finally {
michael@0 144 SystemAppProxy.removeEventListener("mozContentEvent", this._loadPaymentShim);
michael@0 145 this._loadPaymentShim = null;
michael@0 146 }
michael@0 147 }).bind(this);
michael@0 148 SystemAppProxy.addEventListener("mozContentEvent", this._loadPaymentShim);
michael@0 149
michael@0 150 // We also listen for UI notifications about a closed payment flow. The UI
michael@0 151 // should provide the reason of the closure within the 'errorMsg' parameter
michael@0 152 this._notifyPayFlowClosed = (function _notifyPayFlowClosed(evt) {
michael@0 153 let msg = evt.detail;
michael@0 154 if (msg.id != id) {
michael@0 155 return;
michael@0 156 }
michael@0 157
michael@0 158 if (msg.type != 'cancel') {
michael@0 159 return;
michael@0 160 }
michael@0 161
michael@0 162 if (msg.errorMsg) {
michael@0 163 _error(msg.errorMsg);
michael@0 164 }
michael@0 165 SystemAppProxy.removeEventListener("mozContentEvent",
michael@0 166 this._notifyPayFlowClosed);
michael@0 167 this._notifyPayFlowClosed = null;
michael@0 168 }).bind(this);
michael@0 169 SystemAppProxy.addEventListener("mozContentEvent",
michael@0 170 this._notifyPayFlowClosed);
michael@0 171
michael@0 172 SystemAppProxy.dispatchEvent(detail);
michael@0 173 },
michael@0 174
michael@0 175 cleanup: function cleanup() {
michael@0 176 if (this._handleSelection) {
michael@0 177 SystemAppProxy.removeEventListener("mozContentEvent", this._handleSelection);
michael@0 178 this._handleSelection = null;
michael@0 179 }
michael@0 180
michael@0 181 if (this._notifyPayFlowClosed) {
michael@0 182 SystemAppProxy.removeEventListener("mozContentEvent", this._notifyPayFlowClosed);
michael@0 183 this._notifyPayFlowClosed = null;
michael@0 184 }
michael@0 185
michael@0 186 if (this._loadPaymentShim) {
michael@0 187 SystemAppProxy.removeEventListener("mozContentEvent", this._loadPaymentShim);
michael@0 188 this._loadPaymentShim = null;
michael@0 189 }
michael@0 190 },
michael@0 191
michael@0 192 getRandomId: function getRandomId() {
michael@0 193 return uuidgen.generateUUID().toString();
michael@0 194 },
michael@0 195
michael@0 196 LOG: function LOG(s) {
michael@0 197 if (!this._debug) {
michael@0 198 return;
michael@0 199 }
michael@0 200 dump("-*- PaymentGlue: " + s + "\n");
michael@0 201 },
michael@0 202
michael@0 203 classID: Components.ID("{8b83eabc-7929-47f4-8b48-4dea8d887e4b}"),
michael@0 204
michael@0 205 QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIGlue])
michael@0 206 }
michael@0 207
michael@0 208 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentUI]);

mercurial