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

     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/. */
     5 "use strict";
     7 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
     9 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    10 Cu.import("resource://gre/modules/Services.jsm");
    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";
    16 // Type of MozChromEvents to handle payment dialogs.
    17 const kOpenPaymentConfirmationEvent = "open-payment-confirmation-dialog";
    18 const kOpenPaymentFlowEvent = "open-payment-flow-dialog";
    20 const PREF_DEBUG = "dom.payment.debug";
    22 XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
    23                                    "@mozilla.org/uuid-generator;1",
    24                                    "nsIUUIDGenerator");
    26 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
    27                                   "resource://gre/modules/SystemAppProxy.jsm");
    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 }
    39 PaymentUI.prototype = {
    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     };
    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     };
    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       }
    71       if (msg.userSelection && aSuccessCb) {
    72         aSuccessCb.onresult(aRequestId, msg.userSelection);
    73       } else if (msg.errorMsg) {
    74         _error(msg.errorMsg);
    75       }
    77       SystemAppProxy.removeEventListener("mozContentEvent", this._handleSelection);
    78       this._handleSelection = null;
    79     }).bind(this);
    80     SystemAppProxy.addEventListener("mozContentEvent", this._handleSelection);
    82     SystemAppProxy.dispatchEvent(detail);
    83   },
    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     };
    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     };
   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       }
   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       }
   121       if (!msg.frame) {
   122         SystemAppProxy.removeEventListener("mozContentEvent", this._loadPaymentShim);
   123         this._loadPaymentShim = null;
   124         _error("ERROR_LOADING_PAYMENT_SHIM");
   125         return;
   126       }
   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);
   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       }
   158       if (msg.type != 'cancel') {
   159         return;
   160       }
   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);
   172     SystemAppProxy.dispatchEvent(detail);
   173   },
   175   cleanup: function cleanup() {
   176     if (this._handleSelection) {
   177       SystemAppProxy.removeEventListener("mozContentEvent", this._handleSelection);
   178       this._handleSelection = null;
   179     }
   181     if (this._notifyPayFlowClosed) {
   182       SystemAppProxy.removeEventListener("mozContentEvent", this._notifyPayFlowClosed);
   183       this._notifyPayFlowClosed = null;
   184     }
   186     if (this._loadPaymentShim) {
   187       SystemAppProxy.removeEventListener("mozContentEvent", this._loadPaymentShim);
   188       this._loadPaymentShim = null;
   189     }
   190   },
   192   getRandomId: function getRandomId() {
   193     return uuidgen.generateUUID().toString();
   194   },
   196   LOG: function LOG(s) {
   197     if (!this._debug) {
   198       return;
   199     }
   200     dump("-*- PaymentGlue: " + s + "\n");
   201   },
   203   classID: Components.ID("{8b83eabc-7929-47f4-8b48-4dea8d887e4b}"),
   205   QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIGlue])
   206 }
   208 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentUI]);

mercurial