Bug 878848 - Use Prompt.jsm for NSS prompts. r=kats
authorWes Johnston <wjohnston@mozilla.com>
Wed, 12 Jun 2013 09:14:58 -0700
changeset 146312 9bc4ee218fc060fe0bf2b4d7eb543b8b2d557c73
parent 146311 a0f606080683118b006edef8be40787dd6c03b37
child 146313 59143d8cf13b3496d53b82063e2b4b3750db005d
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs878848
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 878848 - Use Prompt.jsm for NSS prompts. r=kats
mobile/android/components/NSSDialogService.js
mobile/android/modules/Prompt.jsm
--- a/mobile/android/components/NSSDialogService.js
+++ b/mobile/android/components/NSSDialogService.js
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cc = Components.classes;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Prompt.jsm");
 
 // -----------------------------------------------------------------------
 // NSS Dialog Service
 // -----------------------------------------------------------------------
 
 function dump(a) {
   Components.classes["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a);
 }
@@ -32,124 +33,136 @@ NSSDialogs.prototype = {
 
   formatString: function(aName, argList) {
     if (!this.bundle) {
       this.bundle = Services.strings.createBundle("chrome://browser/locale/pippki.properties");
     }
     return this.bundle.formatStringFromName(aName, argList, 1);
   },
 
-  showPrompt: function(aTitle, aText, aButtons, aInputs) {
-    let msg = {
-      type: "Prompt:Show",
+  getPrompt: function(aTitle, aText, aButtons) {
+    return new Prompt({
       title: aTitle,
       text: aText,
       buttons: aButtons,
-      inputs: aInputs
-    };
-    let data = Cc["@mozilla.org/android/bridge;1"].getService(Ci.nsIAndroidBridge).handleGeckoMessage(JSON.stringify(msg));
-    return JSON.parse(data);
+    });
+  },
+
+  showPrompt: function(aPrompt) {
+    let response = null;
+    aPrompt.show(function(data) {
+      response = data;
+    });
+
+    // Spin this thread while we wait for a result
+    let thread = Services.tm.currentThread;
+    while (response === null)
+      thread.processNextEvent(true);
+
+    return response;
   },
 
   confirmDownloadCACert: function(aCtx, aCert, aTrust) {
     while (true) {
-      let response = this.showPrompt(this.getString("downloadCert.title"),
-                                     this.getString("downloadCert.message1"),
-                                     [ this.getString("nssdialogs.ok.label"),
-                                       this.getString("downloadCert.viewCert.label"),
-                                       this.getString("nssdialogs.cancel.label")
-                                     ],
-                                     [ { type: "checkbox", id: "trustSSL", label: this.getString("downloadCert.trustSSL"), checked: false },
-                                       { type: "checkbox", id: "trustEmail", label: this.getString("downloadCert.trustEmail"), checked: false },
-                                       { type: "checkbox", id: "trustSign", label: this.getString("downloadCert.trustObjSign"), checked: false }
-                                     ]);
+      let prompt = this.getPrompt(this.getString("downloadCert.title"),
+                                  this.getString("downloadCert.message1"),
+                                  [ this.getString("nssdialogs.ok.label"),
+                                    this.getString("downloadCert.viewCert.label"),
+                                    this.getString("nssdialogs.cancel.label")
+                                  ]);
+
+      prompt.addCheckbox({ id: "trustSSL", label: this.getString("downloadCert.trustSSL"), checked: false })
+            .addCheckbox({ id: "trustEmail", label: this.getString("downloadCert.trustEmail"), checked: false })
+            .addCheckbox({ id: "trustSign", label: this.getString("downloadCert.trustObjSign"), checked: false });
+      let response = this.showPrompt(prompt);
+
+      // they hit the "view cert" button, so show the cert and try again
       if (response.button == 1) {
-        // they hit the "view cert" button, so show the cert and try again
         this.viewCert(aCtx, aCert);
         continue;
       } else if (response.button != 0) {
         return false;
       }
 
       aTrust.value = Ci.nsIX509CertDB.UNTRUSTED;
       if (response.trustSSL == "true") aTrust.value |= Ci.nsIX509CertDB.TRUSTED_SSL;
       if (response.trustEmail == "true") aTrust.value |= Ci.nsIX509CertDB.TRUSTED_EMAIL;
       if (response.trustSign == "true") aTrust.value |= Ci.nsIX509CertDB.TRUSTED_OBJSIGN;
       return true;
     }
   },
 
   notifyCACertExists: function(aCtx) {
-    this.showPrompt(this.getString("caCertExists.title"), this.getString("caCertExists.message"), [], []);
+    let p = this.getPrompt(this.getString("caCertExists.title"), this.getString("caCertExists.message"));
+    this.showPrompt(p);
   },
 
   setPKCS12FilePassword: function(aCtx, aPassword) {
     // this dialog is never shown in Fennec; in Desktop it is shown while backing up a personal
     // certificate to a file via Preferences->Advanced->Encryption->View Certificates->Your Certificates
     throw "Unimplemented";
   },
 
   getPKCS12FilePassword: function(aCtx, aPassword) {
-    let response = this.showPrompt(this.getString("pkcs12.getpassword.title"),
-                                   this.getString("pkcs12.getpassword.message"),
-                                   [ this.getString("nssdialogs.ok.label"),
-                                     this.getString("nssdialogs.cancel.label")
-                                   ],
-                                   [ { type: "password", id: "pw" } ]);
+    let prompt = this.getPrompt(this.getString("pkcs12.getpassword.title"),
+                                this.getString("pkcs12.getpassword.message"),
+                                [ this.getString("nssdialogs.ok.label"),
+                                  this.getString("nssdialogs.cancel.label")
+                                ]).addPassword({id: "pw"});
+    let response = this.showPrompt(prompt);
     if (response.button != 0) {
       return false;
     }
+
     aPassword.value = response.pw;
     return true;
   },
 
   certInfoSection: function(aHeading, aDataPairs, aTrailingNewline = true) {
     var str = "<big>" + this.getString(aHeading) + "</big><br/>";
     for (var i = 0; i < aDataPairs.length; i += 2) {
       str += this.getString(aDataPairs[i]) + ": " + aDataPairs[i+1] + "<br/>";
     }
     return str + (aTrailingNewline ? "<br/>" : "");
   },
 
   viewCert: function(aCtx, aCert) {
-    this.showPrompt(this.getString("certmgr.title"),
+    let p = this.getPrompt(this.getString("certmgr.title"),
                     "",
-                    [ this.getString("nssdialogs.ok.label") ],
-                    [ { type: "label", label:
-                        this.certInfoSection("certmgr.subjectinfo.label",
+                    [ this.getString("nssdialogs.ok.label") ])
+    p.addLabel({ label: this.certInfoSection("certmgr.subjectinfo.label",
                           ["certmgr.certdetail.cn", aCert.commonName,
                            "certmgr.certdetail.o", aCert.organization,
                            "certmgr.certdetail.ou", aCert.organizationalUnit,
-                           "certmgr.certdetail.serialnumber", aCert.serialNumber]) +
-                        this.certInfoSection("certmgr.issuerinfo.label",
+                           "certmgr.certdetail.serialnumber", aCert.serialNumber])})
+     .addLabel({ label: this.certInfoSection("certmgr.issuerinfo.label",
                           ["certmgr.certdetail.cn", aCert.issuerCommonName,
                            "certmgr.certdetail.o", aCert.issuerOrganization,
-                           "certmgr.certdetail.ou", aCert.issuerOrganizationUnit]) +
-                        this.certInfoSection("certmgr.validity.label",
+                           "certmgr.certdetail.ou", aCert.issuerOrganizationUnit])})
+     .addLabel({ label: this.certInfoSection("certmgr.validity.label",
                           ["certmgr.issued", aCert.validity.notBeforeLocalDay,
-                           "certmgr.expires", aCert.validity.notAfterLocalDay]) +
-                        this.certInfoSection("certmgr.fingerprints.label",
+                           "certmgr.expires", aCert.validity.notAfterLocalDay])})
+     .addLabel({ label: this.certInfoSection("certmgr.fingerprints.label",
                           ["certmgr.certdetail.sha1fingerprint", aCert.sha1Fingerprint,
-                           "certmgr.certdetail.md5fingerprint", aCert.md5Fingerprint], false) }
-                    ]);
+                           "certmgr.certdetail.md5fingerprint", aCert.md5Fingerprint], false) });
+    this.showPrompt(p);
   },
 
   crlImportStatusDialog: function(aCtx, aCrl) {
     // this dialog is never shown in Fennec; in Desktop it is shown after importing a CRL
     // via Preferences->Advanced->Encryption->Revocation Lists->Import.
     throw "Unimplemented";
   },
 
   viewCertDetails: function(details) {
-    this.showPrompt(this.getString("clientAuthAsk.message3"),
+    let p = this.getPrompt(this.getString("clientAuthAsk.message3"),
                     '',
-                    [ this.getString("nssdialogs.ok.label") ],
-                    [ { type: "label", label: details
-                      }
-                    ]);
+                    [ this.getString("nssdialogs.ok.label") ]);
+    p.addLabel({ label: details });
+    this.showPrompt(p);
   },
 
   ChooseCertificate: function(aCtx, cn, organization, issuer, certNickList, certDetailsList, count, selectedIndex, canceled) {
     let rememberSetting = true;
     var pref = Cc['@mozilla.org/preferences-service;1']
                .getService(Components.interfaces.nsIPrefService);
     if (pref) {
       pref = pref.getBranch(null);
@@ -163,26 +176,33 @@ NSSDialogs.prototype = {
     let organizationString = this.formatString("clientAuthAsk.organization",
                                                [organization]);
     let issuerString = this.formatString("clientAuthAsk.issuer",
                                          [issuer]);
     let serverRequestedDetails = cn + '<br/>' + organizationString + '<br/>' + issuerString;
 
     selectedIndex = 0;
     while (true) {
-      let response = this.showPrompt(this.getString("clientAuthAsk.title"),
+      let prompt = this.getPrompt(this.getString("clientAuthAsk.title"),
                                      this.getString("clientAuthAsk.message1"),
                                      [ this.getString("nssdialogs.ok.label"),
                                        this.getString("clientAuthAsk.viewCert.label"),
                                        this.getString("nssdialogs.cancel.label")
-                                     ],
-                                     [ { type: "label", id: "requestedDetails", label: serverRequestedDetails },
-                                       { type: "menulist", id: "nicknames", label: this.getString("clientAuthAsk.message2"), values: certNickList, selected: selectedIndex },
-                                       { type: "checkbox", id: "rememberBox", label: this.getString("clientAuthAsk.remember.label"), checked: rememberSetting },
-                                     ]);
+                                     ])
+      .addLabel({ id: "requestedDetails", label: serverRequestedDetails } )
+      .addMenuList({
+        id: "nicknames",
+        label: this.getString("clientAuthAsk.message2"),
+        values: certNickList, selected: selectedIndex
+      }).addCheckbox({
+        id: "rememberBox",
+        label: this.getString("clientAuthAsk.remember.label"),
+        checked: rememberSetting
+      });
+      let response = this.showPrompt(prompt);
       selectedIndex = response.nicknames;
       if (response.button == 1) {
         this.viewCertDetails(certDetailsList[selectedIndex]);
         continue;
       } else if (response.button == 0) {
         canceled.value = false;
         if (response.rememberBox == "true") {
           aCtx.QueryInterface(Ci.nsIClientAuthUserDecision).rememberClientAuthCertificate = true;
--- a/mobile/android/modules/Prompt.jsm
+++ b/mobile/android/modules/Prompt.jsm
@@ -82,16 +82,25 @@ Prompt.prototype = {
       id : aOptions.id
     });
   },
 
   addDatePicker: function(aOptions) {
     return this._addInput({
       type: aOptions.type || "date",
       value: aOptions.value,
+      id: aOptions.id
+    });
+  },
+
+  addLabel: function(aOptions) {
+    return this._addInput({
+      type: "label",
+      label: aOptions.label,
+      id: aOptions.id
     });
   },
 
   addMenulist: function(aOptions) {
     return this._addInput({
       type: "menulist",
       values: aOptions.values,
       id: aOptions.id