b2g/components/PaymentGlue.js

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

mercurial