Bug 1114594 - Remove promptForSaveToFile in favor of promptForSaveToFileAsync. r=paolo
authorGanesh Sahukari <sahukariganesh2@gmail.com>
Tue, 27 Jan 2015 16:07:20 -0500
changeset 239346 a5099b806777051759c04f39ec433b970f7b4298
parent 239345 1e87184509fa934ed395517f95ee7907c7868e44
child 239347 31f70be9d69ab902a9cc3a5b6ddc695a1711fa74
push id497
push usermleibovic@mozilla.com
push dateWed, 28 Jan 2015 16:43:37 +0000
reviewerspaolo
bugs1114594
milestone38.0a1
Bug 1114594 - Remove promptForSaveToFile in favor of promptForSaveToFileAsync. r=paolo
b2g/components/HelperAppDialog.js
browser/metro/components/HelperAppDialog.js
mobile/android/components/HelperAppDialog.js
toolkit/components/downloads/test/unit/downloads_manifest.js
toolkit/components/jsdownloads/test/unit/head.js
toolkit/mozapps/downloads/nsHelperAppDlg.js
uriloader/exthandler/nsExternalHelperAppService.cpp
uriloader/exthandler/nsIHelperAppLauncherDialog.idl
uriloader/exthandler/tests/mochitest/test_unsafeBidiChars.xhtml
uriloader/exthandler/tests/unit_ipc/test_encoding.js
--- a/b2g/components/HelperAppDialog.js
+++ b/b2g/components/HelperAppDialog.js
@@ -28,24 +28,16 @@ HelperAppLauncherDialog.prototype = {
   classID: Components.ID("{710322af-e6ae-4b0c-b2c9-1474a87b077e}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
 
   show: function(aLauncher, aContext, aReason) {
     aLauncher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToDisk;
     aLauncher.saveToDisk(null, false);
   },
 
-  promptForSaveToFile: function(aLauncher,
-                                aContext,
-                                aDefaultFile,
-                                aSuggestedFileExt,
-                                aForcePrompt) {
-    throw Cr.NS_ERROR_NOT_AVAILABLE;
-  },
-
   promptForSaveToFileAsync: function(aLauncher,
                                      aContext,
                                      aDefaultFile,
                                      aSuggestedFileExt,
                                      aForcePrompt) {
     // Retrieve the user's default download directory.
     Task.spawn(function() {
       let file = null;
--- a/browser/metro/components/HelperAppDialog.js
+++ b/browser/metro/components/HelperAppDialog.js
@@ -133,20 +133,16 @@ HelperAppLauncherDialog.prototype = {
                                                     "save-download",
                                                     URI_GENERIC_ICON_DOWNLOAD,
                                                     notificationBox.PRIORITY_WARNING_HIGH,
                                                     buttons);
     let messageContainer = document.getAnonymousElementByAttribute(newBar, "anonid", "messageText");
     messageContainer.appendChild(fragment);
   },
 
-  promptForSaveToFile: function hald_promptForSaveToFile(aLauncher, aContext, aDefaultFile, aSuggestedFileExt, aForcePrompt) {
-    throw new Components.Exception("Async version must be used", Cr.NS_ERROR_NOT_AVAILABLE);
-  },
-
   promptForSaveToFileAsync: function hald_promptForSaveToFileAsync(aLauncher, aContext, aDefaultFile, aSuggestedFileExt, aForcePrompt) {
     let file = null;
     let prefs = Services.prefs;
 
     Task.spawn(function() {
       if (!aForcePrompt) {
         // Check to see if the user wishes to auto save to the default download
         // folder without prompting. Note that preference might not be set.
--- a/mobile/android/components/HelperAppDialog.js
+++ b/mobile/android/components/HelperAppDialog.js
@@ -231,21 +231,16 @@ HelperAppLauncherDialog.prototype = {
       return;
 
     if (app)
       Services.prefs.setCharPref(this._getPrefName(mime), app.packageName);
     else
       Services.prefs.clearUserPref(this._getPrefName(mime));
   },
 
-  promptForSaveToFile: function () {
-    throw new Components.Exception("Async version must be used",
-                                   Cr.NS_ERROR_NOT_AVAILABLE);
-  },
-
   promptForSaveToFileAsync: function (aLauncher, aContext, aDefaultFile,
                                       aSuggestedFileExt, aForcePrompt) {
     Task.spawn(function* () {
       let file = null;
       try {
         let preferredDir = yield Downloads.getPreferredDownloadsDirectory();
         file = this.validateLeafName(new FileUtils.File(preferredDir),
                                      aDefaultFile, aSuggestedFileExt);
--- a/toolkit/components/downloads/test/unit/downloads_manifest.js
+++ b/toolkit/components/downloads/test/unit/downloads_manifest.js
@@ -10,15 +10,13 @@ const Ci = Components.interfaces;
 
 function HelperAppDlg() { }
 HelperAppDlg.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
   classID: Components.ID("49456eda-4dc4-4d1a-b8e8-0b94749bf99e"),
   show: function (launcher, ctx, reason) {
     launcher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToDisk;
     launcher.launchWithApplication(null, false);
-  },
-
-  promptForSaveToFile: function (launcher, ctx, defaultFile, suggestedExtension, forcePrompt) { }
+  }
 }
 
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HelperAppDlg]);
--- a/toolkit/components/jsdownloads/test/unit/head.js
+++ b/toolkit/components/jsdownloads/test/unit/head.js
@@ -788,25 +788,16 @@ add_task(function test_common_initialize
   do_register_cleanup(() => registrar = null);
 
   // Make sure that downloads started using nsIExternalHelperAppService are
   // saved to disk without asking for a destination interactively.
   let mockFactory = {
     createInstance: function (aOuter, aIid) {
       return {
         QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
-        promptForSaveToFile: function (aLauncher, aWindowContext,
-                                       aDefaultFileName,
-                                       aSuggestedFileExtension,
-                                       aForcePrompt)
-        {
-          throw new Components.Exception(
-                             "Synchronous promptForSaveToFile not implemented.",
-                             Cr.NS_ERROR_NOT_AVAILABLE);
-        },
         promptForSaveToFileAsync: function (aLauncher, aWindowContext,
                                             aDefaultFileName,
                                             aSuggestedFileExtension,
                                             aForcePrompt)
         {
           // The dialog should create the empty placeholder file.
           let file = getTempFile(TEST_TARGET_FILE_NAME);
           file.create(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js
+++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js
@@ -190,32 +190,16 @@ nsUnknownContentTypeDialog.prototype = {
     let bundle =
       Services.strings.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
 
     Services.prompt.alert(this.dialog,
                    bundle.GetStringFromName("badPermissions.title"),
                    bundle.GetStringFromName("badPermissions"));
   },
 
-  // promptForSaveToFile:  Display file picker dialog and return selected file.
-  //                       This is called by the External Helper App Service
-  //                       after the ucth dialog calls |saveToDisk| with a null
-  //                       target filename (no target, therefore user must pick).
-  //
-  //                       Alternatively, if the user has selected to have all
-  //                       files download to a specific location, return that
-  //                       location and don't ask via the dialog.
-  //
-  // Note - this function is called without a dialog, so it cannot access any part
-  // of the dialog XUL as other functions on this object do.
-
-  promptForSaveToFile: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) {
-    throw new Components.Exception("Async version must be used", Components.results.NS_ERROR_NOT_AVAILABLE);
-  },
-
   promptForSaveToFileAsync: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) {
     var result = null;
 
     this.mLauncher = aLauncher;
 
     let prefs = Components.classes["@mozilla.org/preferences-service;1"]
                           .getService(Components.interfaces.nsIPrefBranch);
     let bundle =
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -2232,34 +2232,26 @@ void nsExternalAppHandler::RequestSaveDe
   // we want to explicitly unescape aDefaultFile b4 passing into the dialog. we can't unescape
   // it because the dialog is implemented by a JS component which doesn't have a window so no unescape routine is defined...
 
   // Now, be sure to keep |this| alive, and the dialog
   // If we don't do this, users that close the helper app dialog while the file
   // picker is up would cause Cancel() to be called, and the dialog would be
   // released, which would release this object too, which would crash.
   // See Bug 249143
-  nsIFile* fileToUse;
   nsRefPtr<nsExternalAppHandler> kungFuDeathGrip(this);
   nsCOMPtr<nsIHelperAppLauncherDialog> dlg(mDialog);
-  rv = mDialog->PromptForSaveToFile(this,
-                                    GetDialogParent(),
-                                    aDefaultFile.get(),
-                                    aFileExtension.get(),
-                                    mForceSave, &fileToUse);
-
-  if (rv == NS_ERROR_NOT_AVAILABLE) {
-    // we need to use the async version -> nsIHelperAppLauncherDialog.promptForSaveToFileAsync.
-    rv = mDialog->PromptForSaveToFileAsync(this, 
-                                           GetDialogParent(),
-                                           aDefaultFile.get(),
-                                           aFileExtension.get(),
-                                           mForceSave);
-  } else {
-    SaveDestinationAvailable(rv == NS_OK ? fileToUse : nullptr);
+
+  rv = mDialog->PromptForSaveToFileAsync(this,
+                                         GetDialogParent(),
+                                         aDefaultFile.get(),
+                                         aFileExtension.get(),
+                                         mForceSave);
+  if (NS_FAILED(rv)) {
+    Cancel(NS_BINDING_ABORTED);
   }
 }
 
 // SaveToDisk should only be called by the helper app dialog which allows
 // the user to say launch with application or save to disk. It doesn't actually
 // perform the save, it just prompts for the destination file name.
 NS_IMETHODIMP nsExternalAppHandler::SaveToDisk(nsIFile * aNewFileLocation, bool aRememberThisPreference)
 {
--- a/uriloader/exthandler/nsIHelperAppLauncherDialog.idl
+++ b/uriloader/exthandler/nsIHelperAppLauncherDialog.idl
@@ -16,17 +16,17 @@ interface nsIFile;
  * Usage:  Clients (of which there is one: the nsIExternalHelperAppService
  * implementation in mozilla/uriloader/exthandler) create an instance of
  * this interface (using the contract ID) and then call the show() method.
  *
  * The dialog is shown non-modally.  The implementation of the dialog
  * will access methods of the nsIHelperAppLauncher passed in to show()
  * in order to cause a "save to disk" or "open using" action.
  */
-[scriptable, uuid(3ae4dca8-ac91-4891-adcf-3fbebed6170e)]
+[scriptable, uuid(bfc739f3-8d75-4034-a6f8-1039a5996bad)]
 interface nsIHelperAppLauncherDialog : nsISupports {
   /**
    * This request is passed to the helper app dialog because Gecko can not
    * handle content of this type.
    */
   const unsigned long REASON_CANTHANDLE = 0;
 
   /**
@@ -53,42 +53,16 @@ interface nsIHelperAppLauncherDialog : n
    *        shown. Implementors should treat unknown reasons like
    *        REASON_CANTHANDLE.
    */
   void show(in nsIHelperAppLauncher aLauncher,
             in nsISupports aWindowContext,
             in unsigned long aReason);
 
   /**
-   * Invoke a save-to-file dialog instead of the full fledged helper app dialog.
-   * Returns the a nsIFile for the file name/location selected.
-   *
-   * @param aLauncher
-   *        A nsIHelperAppLauncher to be invoked when a file is selected.
-   * @param aWindowContext
-   *        Window associated with action.
-   * @param aDefaultFileName
-   *        Default file name to provide (can be null)
-   * @param aSuggestedFileExtension
-   *        Sugested file extension
-   * @param aForcePrompt
-   *        Set to true to force prompting the user for thet file
-   *        name/location, otherwise perferences may control if the user is
-   *        prompted.
-   *
-   * @throws NS_ERROR_NOT_AVAILABLE if the async version of this function
-   *                                should be used.
-   */
-  nsIFile promptForSaveToFile(in nsIHelperAppLauncher aLauncher,
-                              in nsISupports aWindowContext,
-                              in wstring aDefaultFileName,
-                              in wstring aSuggestedFileExtension,
-                              in boolean aForcePrompt);
-
-  /**
    * Async invoke a save-to-file dialog instead of the full fledged helper app
    * dialog. When the file is chosen (or the dialog is closed), the callback
    * in aLauncher (aLauncher.saveDestinationAvailable) is called with the
    * selected file.
    *
    * @param aLauncher
    *        A nsIHelperAppLauncher to be invoked when a file is selected.
    * @param aWindowContext
--- a/uriloader/exthandler/tests/mochitest/test_unsafeBidiChars.xhtml
+++ b/uriloader/exthandler/tests/mochitest/test_unsafeBidiChars.xhtml
@@ -79,19 +79,16 @@ function load() {
     REASON_TYPESNIFFED: 2,
     show: function(aLauncher, aWindowContext, aReason) {
       netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
       var test = gTests[gCounter];
       is(aLauncher.suggestedFileName, test.expected,
          "The filename should be correctly sanitized");
       gCallback();
     },
-    promptForSaveToFile: function(aLauncher, aWindowContext, aDefaultFileName, aSuggestedFileExtension, aForcePrompt) {
-      return null;
-    },
     QueryInterface: function(aIID) {
       netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
       if (aIID.equals(SpecialPowers.Ci.nsISupports) ||
           aIID.equals(SpecialPowers.Ci.nsIHelperAppLauncherDialog))
         return this;
       throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
     }
   };
--- a/uriloader/exthandler/tests/unit_ipc/test_encoding.js
+++ b/uriloader/exthandler/tests/unit_ipc/test_encoding.js
@@ -56,19 +56,17 @@ DownloadListener.init();
 
 function HelperAppDlg() { }
 HelperAppDlg.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
   contractID: "@mozilla.org/helperapplauncherdialog;1",
   show: function (launcher, ctx, reason, usePrivateUI) {
     launcher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToFile;
     launcher.launchWithApplication(null, false);
-  },
-
-  promptForSaveToFile: function (launcher, ctx, defaultFile, suggestedExtension, forcePrompt) { }
+  }
 }
 
 // Stolen from XPCOMUtils, since this handy function is not public there
 function getFactory(comp)
 {
   return {
     createInstance: function (outer, iid) {
       if (outer)