Backed out 2 changesets (bug 1334975, bug 1335539) for merge conflicts a=backout
authorWes Kocher <wkocher@mozilla.com>
Thu, 02 Mar 2017 14:57:21 -0800
changeset 374668 63c4e77cfe90e90d35d85e1a4821015823c4ecee
parent 374667 d50d68150aba3350501d2cc4df8233fa021a08e5
child 374669 b23d6277acca34a4b1be9a4c24efd3b999e47ec3
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1334975, 1335539
milestone54.0a1
backs out429ff39f3d28b195fb5ee1467cd8126bab3d89b8
eea959a93ce48bc477b32e752d89a5c685f1eef0
Backed out 2 changesets (bug 1334975, bug 1335539) for merge conflicts a=backout Backed out changeset 429ff39f3d28 (bug 1335539) Backed out changeset eea959a93ce4 (bug 1334975) MozReview-Commit-ID: GlvA0B0vHRT
browser/base/content/test/general/browser_save_link-perwindowpb.js
browser/base/content/test/general/browser_save_link_when_window_navigates.js
browser/base/content/test/general/browser_save_private_link_perwindowpb.js
browser/base/content/test/general/browser_save_video.js
browser/base/content/test/general/browser_save_video_frame.js
browser/base/content/test/webextensions/browser_permissions_local_file.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js
devtools/client/aboutdebugging/components/addons/controls.js
devtools/client/aboutdebugging/test/browser_addons_install.js
devtools/client/aboutdebugging/test/head.js
devtools/client/canvasdebugger/snapshotslist.js
devtools/client/jsonview/main.js
devtools/client/jsonview/utils.js
devtools/client/netmonitor/har/har-exporter.js
devtools/client/netmonitor/har/har-utils.js
devtools/client/performance/performance-view.js
devtools/client/webide/content/newapp.js
devtools/client/webide/content/simulator.js
devtools/client/webide/modules/project-list.js
devtools/client/webide/modules/utils.js
devtools/client/webide/test/test_simulators.html
dom/base/nsDOMWindowUtils.cpp
dom/base/test/mochitest.ini
dom/base/test/test_bug793311.html
dom/file/FileBlobImpl.h
dom/file/FileCreatorHelper.cpp
dom/file/FileCreatorHelper.h
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/ipc/tests/test_bug1086684.html
dom/webidl/File.webidl
layout/forms/test/test_bug536567_perwindowpb.html
layout/tools/layout-debug/ui/content/layoutdebug.js
mobile/android/components/FilePicker.js
security/manager/pki/resources/content/certManager.js
testing/specialpowers/content/MockFilePicker.jsm
toolkit/components/apppicker/content/appPicker.js
toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html
toolkit/components/filepicker/nsFilePicker.js
toolkit/components/printing/content/printdialog.js
toolkit/components/tooltiptext/tests/browser_input_file_tooltips.js
toolkit/content/tests/browser/browser_save_resend_postdata.js
toolkit/mozapps/downloads/nsHelperAppDlg.js
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/setting.xml
toolkit/mozapps/extensions/test/browser/browser_bug567127.js
toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
toolkit/mozapps/extensions/test/browser/browser_inlinesettings_info.js
toolkit/mozapps/handling/content/dialog.js
widget/nsIFilePicker.idl
--- a/browser/base/content/test/general/browser_save_link-perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_link-perwindowpb.js
@@ -35,17 +35,17 @@ function triggerSave(aWindow, aCallback)
     var destFile = destDir.clone();
 
     MockFilePicker.displayDirectory = destDir;
     MockFilePicker.showCallback = function(fp) {
       info("showCallback");
       fileName = fp.defaultString;
       info("fileName: " + fileName);
       destFile.append(fileName);
-      MockFilePicker.setFiles([destFile]);
+      MockFilePicker.returnFiles = [destFile];
       MockFilePicker.filterIndex = 1; // kSaveAsType_URL
       info("done showCallback");
     };
 
     mockTransferCallback = function(downloadSuccess) {
       info("mockTransferCallback");
       onTransferComplete(aWindow, downloadSuccess, destDir);
       destDir.remove(true);
--- a/browser/base/content/test/general/browser_save_link_when_window_navigates.js
+++ b/browser/base/content/test/general/browser_save_link_when_window_navigates.js
@@ -40,17 +40,17 @@ function triggerSave(aWindow, aCallback)
   var destFile = destDir.clone();
 
   MockFilePicker.displayDirectory = destDir;
   MockFilePicker.showCallback = function(fp) {
     info("showCallback");
     fileName = fp.defaultString;
     info("fileName: " + fileName);
     destFile.append(fileName);
-    MockFilePicker.setFiles([destFile]);
+    MockFilePicker.returnFiles = [destFile];
     MockFilePicker.filterIndex = 1; // kSaveAsType_URL
     info("done showCallback");
   };
 
   mockTransferCallback = function(downloadSuccess) {
     info("mockTransferCallback");
     onTransferComplete(aWindow, downloadSuccess, destDir);
     destDir.remove(true);
--- a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
@@ -53,17 +53,17 @@ function promiseImageDownloaded() {
     // Create the folder the image will be saved into.
     var destDir = createTemporarySaveDirectory();
     var destFile = destDir.clone();
 
     MockFilePicker.displayDirectory = destDir;
     MockFilePicker.showCallback = function(fp) {
       fileName = fp.defaultString;
       destFile.append(fileName);
-      MockFilePicker.setFiles([destFile]);
+      MockFilePicker.returnFiles = [destFile];
       MockFilePicker.filterIndex = 1; // kSaveAsType_URL
     };
 
     mockTransferCallback = onTransferComplete;
     mockTransferRegisterer.register();
 
     registerCleanupFunction(function() {
       mockTransferCallback = null;
--- a/browser/base/content/test/general/browser_save_video.js
+++ b/browser/base/content/test/general/browser_save_video.js
@@ -29,17 +29,17 @@ add_task(function* () {
   // Create the folder the video will be saved into.
   var destDir = createTemporarySaveDirectory();
   var destFile = destDir.clone();
 
   MockFilePicker.displayDirectory = destDir;
   MockFilePicker.showCallback = function(fp) {
     fileName = fp.defaultString;
     destFile.append(fileName);
-    MockFilePicker.setFiles([destFile]);
+    MockFilePicker.returnFiles = [destFile];
     MockFilePicker.filterIndex = 1; // kSaveAsType_URL
   };
 
   let transferCompletePromise = new Promise((resolve) => {
     function onTransferComplete(downloadSuccess) {
       ok(downloadSuccess, "Video file should have been downloaded successfully");
 
       is(fileName, "web-video1-expectedName.ogv",
--- a/browser/base/content/test/general/browser_save_video_frame.js
+++ b/browser/base/content/test/general/browser_save_video_frame.js
@@ -80,17 +80,17 @@ add_task(function*() {
 
   // Create the folder the video will be saved into.
   let destDir = createTemporarySaveDirectory();
   let destFile = destDir.clone();
 
   MockFilePicker.displayDirectory = destDir;
   MockFilePicker.showCallback = function(fp) {
     destFile.append(fp.defaultString);
-    MockFilePicker.setFiles([destFile]);
+    MockFilePicker.returnFiles = [destFile];
     MockFilePicker.filterIndex = 1; // kSaveAsType_URL
   };
 
   mockTransferRegisterer.register();
 
   // Make sure that we clean these things up when we're done.
   registerCleanupFunction(function() {
     mockTransferRegisterer.unregister();
--- a/browser/base/content/test/webextensions/browser_permissions_local_file.js
+++ b/browser/base/content/test/webextensions/browser_permissions_local_file.js
@@ -5,19 +5,19 @@ async function installFile(filename) {
                                      .getService(Ci.nsIChromeRegistry);
   let chromeUrl = Services.io.newURI(gTestPath);
   let fileUrl = ChromeRegistry.convertChromeURL(chromeUrl);
   let file = fileUrl.QueryInterface(Ci.nsIFileURL).file;
   file.leafName = filename;
 
   let MockFilePicker = SpecialPowers.MockFilePicker;
   MockFilePicker.init(window);
-  MockFilePicker.setFiles([file]);
-  MockFilePicker.afterOpenCallback = MockFilePicker.cleanup;
+  MockFilePicker.returnFiles = [file];
 
   await BrowserOpenAddonsMgr("addons://list/extension");
   let contentWin = gBrowser.selectedTab.linkedBrowser.contentWindow;
 
   // Do the install...
   contentWin.gViewController.doCommand("cmd_installFromFile");
+  MockFilePicker.cleanup();
 }
 
 add_task(() => testInstallMethod(installFile));
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir.js
@@ -50,17 +50,17 @@ function test() {
                            aGlobalLastDir, aCallback) {
     // Check lastDir preference.
     is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aDisplayDir.path,
        "LastDir should be the expected display dir");
     // Check gDownloadLastDir value.
     is(gDownloadLastDir.file.path, aDisplayDir.path,
        "gDownloadLastDir should be the expected display dir");
 
-    MockFilePicker.setFiles([aFile]);
+    MockFilePicker.returnFiles = [aFile];
     MockFilePicker.displayDirectory = null;
 
     launcher.saveDestinationAvailable = function(file) {
       ok(!!file, "promptForSaveToFile correctly returned a file");
 
       // File picker should start with expected display dir.
       is(MockFilePicker.displayDirectory.path, aDisplayDir.path,
         "File picker should start with browser.download.lastDir");
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js
@@ -57,17 +57,17 @@ function test() {
                            aGlobalLastDir, aCallback) {
     // Check lastDir preference.
     is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aDisplayDir.path,
        "LastDir should be the expected display dir");
     // Check gDownloadLastDir value.
     is(gDownloadLastDir.file.path, aDisplayDir.path,
        "gDownloadLastDir should be the expected display dir");
 
-    MockFilePicker.setFiles([aFile]);
+    MockFilePicker.returnFiles = [aFile];
     MockFilePicker.displayDirectory = null;
     aWin.promiseTargetFile(params).then(function() {
       // File picker should start with expected display dir.
       is(MockFilePicker.displayDirectory.path, aDisplayDir.path,
          "File picker should start with browser.download.lastDir");
       // browser.download.lastDir should be modified on not private windows
       is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aLastDir.path,
          "LastDir should be the expected last dir");
--- a/devtools/client/aboutdebugging/components/addons/controls.js
+++ b/devtools/client/aboutdebugging/components/addons/controls.js
@@ -42,33 +42,32 @@ module.exports = createClass({
   },
 
   loadAddonFromFile() {
     this.setState({ installError: null });
     let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
     fp.init(window,
       Strings.GetStringFromName("selectAddonFromFile2"),
       Ci.nsIFilePicker.modeOpen);
-    fp.open(res => {
-      if (res == Ci.nsIFilePicker.returnCancel || !fp.file) {
-        return;
-      }
-      let file = fp.file;
-      // AddonManager.installTemporaryAddon accepts either
-      // addon directory or final xpi file.
-      if (!file.isDirectory() && !file.leafName.endsWith(".xpi")) {
-        file = file.parent;
-      }
+    let res = fp.show();
+    if (res == Ci.nsIFilePicker.returnCancel || !fp.file) {
+      return;
+    }
+    let file = fp.file;
+    // AddonManager.installTemporaryAddon accepts either
+    // addon directory or final xpi file.
+    if (!file.isDirectory() && !file.leafName.endsWith(".xpi")) {
+      file = file.parent;
+    }
 
-      AddonManager.installTemporaryAddon(file)
-        .catch(e => {
-          console.error(e);
-          this.setState({ installError: e.message });
-        });
-    });
+    AddonManager.installTemporaryAddon(file)
+      .catch(e => {
+        console.error(e);
+        this.setState({ installError: e.message });
+      });
   },
 
   render() {
     let { debugDisabled } = this.props;
 
     return dom.div({ className: "addons-top" },
       dom.div({ className: "addons-controls" },
         dom.div({ className: "addons-options toggle-container-with-text" },
--- a/devtools/client/aboutdebugging/test/browser_addons_install.js
+++ b/devtools/client/aboutdebugging/test/browser_addons_install.js
@@ -18,29 +18,29 @@ add_task(function* () {
 
   // Install the add-on, and verify that it disappears in the about:debugging UI
   yield uninstallAddon({document, id: ADDON_ID, name: ADDON_NAME});
 
   yield closeAboutDebugging(tab);
 });
 
 add_task(function* () {
-  let { tab, document, window } = yield openAboutDebugging("addons");
+  let { tab, document } = yield openAboutDebugging("addons");
   yield waitForInitialAddonList(document);
 
   // Start an observer that looks for the install error before
   // actually doing the install
   let top = document.querySelector(".addons-top");
   let promise = waitForMutation(top, { childList: true });
 
   // Mock the file picker to select a test addon
   let MockFilePicker = SpecialPowers.MockFilePicker;
-  MockFilePicker.init(window);
+  MockFilePicker.init(null);
   let file = getSupportsFile("addons/bad/manifest.json");
-  MockFilePicker.setFiles([file.file]);
+  MockFilePicker.returnFiles = [file.file];
 
   // Trigger the file picker by clicking on the button
   document.getElementById("load-addon-from-file").click();
 
   // Now wait for the install error to appear.
   yield promise;
 
   // And check that it really is there.
--- a/devtools/client/aboutdebugging/test/head.js
+++ b/devtools/client/aboutdebugging/test/head.js
@@ -30,23 +30,22 @@ function* openAboutDebugging(page, win) 
   let url = "about:debugging";
   if (page) {
     url += "#" + page;
   }
 
   let tab = yield addTab(url, { window: win });
   let browser = tab.linkedBrowser;
   let document = browser.contentDocument;
-  let window = browser.contentWindow;
 
   if (!document.querySelector(".app")) {
     yield waitForMutation(document.body, { childList: true });
   }
 
-  return { tab, document, window };
+  return { tab, document };
 }
 
 /**
  * Change url hash for current about:debugging tab, return a promise after
  * new content is loaded.
  * @param  {DOMDocument}  document   container document from current tab
  * @param  {String}       hash       hash for about:debugging
  * @return {Promise}
@@ -109,19 +108,19 @@ function getServiceWorkerList(document) 
 function getTabList(document) {
   return document.querySelector("#tabs .target-list") ||
     document.querySelector("#tabs.targets");
 }
 
 function* installAddon({document, path, name, isWebExtension}) {
   // Mock the file picker to select a test addon
   let MockFilePicker = SpecialPowers.MockFilePicker;
-  MockFilePicker.init(window);
+  MockFilePicker.init(null);
   let file = getSupportsFile(path);
-  MockFilePicker.setFiles([file.file]);
+  MockFilePicker.returnFiles = [file.file];
 
   let addonList = getAddonList(document);
   let addonListMutation = waitForMutation(addonList, { childList: true });
 
   let onAddonInstalled;
 
   if (isWebExtension) {
     onAddonInstalled = new Promise(done => {
--- a/devtools/client/canvasdebugger/snapshotslist.js
+++ b/devtools/client/canvasdebugger/snapshotslist.js
@@ -352,50 +352,48 @@ var SnapshotsListView = Heritage.extend(
    * The click listener for the "import" button in this container.
    */
   _onImportButtonClick: function () {
     let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
     fp.init(window, L10N.getStr("snapshotsList.saveDialogTitle"), Ci.nsIFilePicker.modeOpen);
     fp.appendFilter(L10N.getStr("snapshotsList.saveDialogJSONFilter"), "*.json");
     fp.appendFilter(L10N.getStr("snapshotsList.saveDialogAllFilter"), "*.*");
 
-    fp.open(rv => {
-      if (rv != Ci.nsIFilePicker.returnOK) {
+    if (fp.show() != Ci.nsIFilePicker.returnOK) {
+      return;
+    }
+
+    let channel = NetUtil.newChannel({
+      uri: NetUtil.newURI(fp.file), loadUsingSystemPrincipal: true});
+    channel.contentType = "text/plain";
+
+    NetUtil.asyncFetch(channel, (inputStream, status) => {
+      if (!Components.isSuccessCode(status)) {
+        console.error("Could not import recorded animation frame snapshot file.");
+        return;
+      }
+      try {
+        let string = NetUtil.readInputStreamToString(inputStream, inputStream.available());
+        var data = JSON.parse(string);
+      } catch (e) {
+        console.error("Could not read animation frame snapshot file.");
+        return;
+      }
+      if (data.fileType != CALLS_LIST_SERIALIZER_IDENTIFIER) {
+        console.error("Unrecognized animation frame snapshot file.");
         return;
       }
 
-      let channel = NetUtil.newChannel({
-        uri: NetUtil.newURI(fp.file), loadUsingSystemPrincipal: true});
-      channel.contentType = "text/plain";
+      // Add a `isLoadedFromDisk` flag on everything to avoid sending invalid
+      // requests to the backend, since we're not dealing with actors anymore.
+      let snapshotItem = this.addSnapshot();
+      snapshotItem.isLoadedFromDisk = true;
+      data.calls.forEach(e => e.isLoadedFromDisk = true);
 
-      NetUtil.asyncFetch(channel, (inputStream, status) => {
-        if (!Components.isSuccessCode(status)) {
-          console.error("Could not import recorded animation frame snapshot file.");
-          return;
-        }
-        try {
-          let string = NetUtil.readInputStreamToString(inputStream, inputStream.available());
-          var data = JSON.parse(string);
-        } catch (e) {
-          console.error("Could not read animation frame snapshot file.");
-          return;
-        }
-        if (data.fileType != CALLS_LIST_SERIALIZER_IDENTIFIER) {
-          console.error("Unrecognized animation frame snapshot file.");
-          return;
-        }
-
-        // Add a `isLoadedFromDisk` flag on everything to avoid sending invalid
-        // requests to the backend, since we're not dealing with actors anymore.
-        let snapshotItem = this.addSnapshot();
-        snapshotItem.isLoadedFromDisk = true;
-        data.calls.forEach(e => e.isLoadedFromDisk = true);
-
-        this.customizeSnapshot(snapshotItem, data.calls, data);
-      });
+      this.customizeSnapshot(snapshotItem, data.calls, data);
     });
   },
 
   /**
    * The click listener for the "save" button of each item in this container.
    */
   _onSaveButtonClick: function (e) {
     let snapshotItem = this.getItemForElement(e.target);
--- a/devtools/client/jsonview/main.js
+++ b/devtools/client/jsonview/main.js
@@ -45,18 +45,18 @@ var JsonView = {
 
   // Message handlers for events from child processes
 
   /**
    * Save JSON to a file needs to be implemented here
    * in the parent process.
    */
   onSave: function (message) {
-    JsonViewUtils.getTargetFile(file => {
-      if (file) {
-        JsonViewUtils.saveToFile(file, message.data);
-      }
-    });
+    let value = message.data;
+    let file = JsonViewUtils.getTargetFile();
+    if (file) {
+      JsonViewUtils.saveToFile(file, value);
+    }
   }
 };
 
 // Exports from this module
 module.exports.JsonView = JsonView;
--- a/devtools/client/jsonview/utils.js
+++ b/devtools/client/jsonview/utils.js
@@ -18,34 +18,31 @@ const OPEN_FLAGS = {
   TRUNCATE: parseInt("0x20", 16),
   EXCL: parseInt("0x80", 16)
 };
 
 /**
  * Open File Save As dialog and let the user to pick proper file location.
  */
 exports.getTargetFile = function () {
-  return new Promise(resolve => {
-    let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+  let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
 
-    let win = getMostRecentBrowserWindow();
-    fp.init(win, null, Ci.nsIFilePicker.modeSave);
-    fp.appendFilter("JSON Files", "*.json; *.jsonp;");
-    fp.appendFilters(Ci.nsIFilePicker.filterText);
-    fp.appendFilters(Ci.nsIFilePicker.filterAll);
-    fp.filterIndex = 0;
+  let win = getMostRecentBrowserWindow();
+  fp.init(win, null, Ci.nsIFilePicker.modeSave);
+  fp.appendFilter("JSON Files", "*.json; *.jsonp;");
+  fp.appendFilters(Ci.nsIFilePicker.filterText);
+  fp.appendFilters(Ci.nsIFilePicker.filterAll);
+  fp.filterIndex = 0;
 
-    fp.open(rv => {
-      if (rv == Ci.nsIFilePicker.returnOK || rv == Ci.nsIFilePicker.returnReplace) {
-        resolve(fp.file);
-      } else {
-        resolve(null);
-      }
-    });
-  });
+  let rv = fp.show();
+  if (rv == Ci.nsIFilePicker.returnOK || rv == Ci.nsIFilePicker.returnReplace) {
+    return fp.file;
+  }
+
+  return null;
 };
 
 /**
  * Save JSON to a file
  */
 exports.saveToFile = function (file, jsonString) {
   let foStream = Cc["@mozilla.org/network/file-output-stream;1"]
     .createInstance(Ci.nsIFileOutputStream);
--- a/devtools/client/netmonitor/har/har-exporter.js
+++ b/devtools/client/netmonitor/har/har-exporter.js
@@ -65,32 +65,32 @@ const HarExporter = {
     // Set default options related to save operation.
     options.defaultFileName = Services.prefs.getCharPref(
       "devtools.netmonitor.har.defaultFileName");
     options.compress = Services.prefs.getBoolPref(
       "devtools.netmonitor.har.compress");
 
     // Get target file for exported data. Bail out, if the user
     // presses cancel.
-    return HarUtils.getTargetFile(options.defaultFileName, options.jsonp,
-      options.compress).then(file => {
-        if (!file) {
-          return null;
-        }
+    let file = HarUtils.getTargetFile(options.defaultFileName,
+      options.jsonp, options.compress);
 
-        trace.log("HarExporter.save; " + options.defaultFileName, options);
+    if (!file) {
+      return Promise.resolve();
+    }
 
-        return this.fetchHarData(options).then(jsonString => {
-          if (!HarUtils.saveToFile(file, jsonString, options.compress)) {
-            let msg = "Failed to save HAR file at: " + options.defaultFileName;
-            console.error(msg);
-          }
-          return jsonString;
-        });
-      });
+    trace.log("HarExporter.save; " + options.defaultFileName, options);
+
+    return this.fetchHarData(options).then(jsonString => {
+      if (!HarUtils.saveToFile(file, jsonString, options.compress)) {
+        let msg = "Failed to save HAR file at: " + options.defaultFileName;
+        console.error(msg);
+      }
+      return jsonString;
+    });
   },
 
   /**
    * Copy HAR string into the clipboard.
    *
    * @param Object options
    *        Configuration object, see save() for detailed description.
    */
--- a/devtools/client/netmonitor/har/har-utils.js
+++ b/devtools/client/netmonitor/har/har-utils.js
@@ -51,35 +51,34 @@ function formatDate(date) {
 /**
  * Helper API for HAR export features.
  */
 var HarUtils = {
   /**
    * Open File Save As dialog and let the user pick the proper file
    * location for generated HAR log.
    */
-  getTargetFile: function (fileName, jsonp, compress, cb) {
+  getTargetFile: function (fileName, jsonp, compress) {
     let browser = getMostRecentBrowserWindow();
 
     let fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
     fp.init(browser, null, nsIFilePicker.modeSave);
     fp.appendFilter(
       "HTTP Archive Files", "*.har; *.harp; *.json; *.jsonp; *.zip");
     fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText);
     fp.filterIndex = 1;
 
     fp.defaultString = this.getHarFileName(fileName, jsonp, compress);
 
-    fp.open(rv => {
-      if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
-        cb(fp.file);
-      } else {
-        cb(null);
-      }
-    });
+    let rv = fp.show();
+    if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
+      return fp.file;
+    }
+
+    return null;
   },
 
   getHarFileName: function (defaultFileName, jsonp, compress) {
     let extension = jsonp ? ".harp" : ".har";
 
     let now = new Date();
     let name = defaultFileName.replace(/%date/g, formatDate(now));
     name = name.replace(/\:/gm, "-", "");
--- a/devtools/client/performance/performance-view.js
+++ b/devtools/client/performance/performance-view.js
@@ -354,21 +354,19 @@ var PerformanceView = {
    */
   _onImportButtonClick: function (e) {
     let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
     fp.init(window, L10N.getStr("recordingsList.importDialogTitle"),
             Ci.nsIFilePicker.modeOpen);
     fp.appendFilter(L10N.getStr("recordingsList.saveDialogJSONFilter"), "*.json");
     fp.appendFilter(L10N.getStr("recordingsList.saveDialogAllFilter"), "*.*");
 
-    fp.open(rv => {
-      if (rv == Ci.nsIFilePicker.returnOK) {
-        this.emit(EVENTS.UI_IMPORT_RECORDING, fp.file);
-      }
-    });
+    if (fp.show() == Ci.nsIFilePicker.returnOK) {
+      this.emit(EVENTS.UI_IMPORT_RECORDING, fp.file);
+    }
   },
 
   /**
    * Fired when a recording is selected. Used to toggle the profiler view state.
    */
   _onRecordingSelected: function (_, recording) {
     if (!recording) {
       this.setState("empty");
--- a/devtools/client/webide/content/newapp.js
+++ b/devtools/client/webide/content/newapp.js
@@ -105,73 +105,70 @@ function doOK() {
   }
 
   let templatelistNode = document.querySelector("#templatelist");
   if (templatelistNode.selectedIndex < 0) {
     console.error("No template selected");
     return false;
   }
 
+  let folder;
+
   /* Chrome mochitest support */
-  let promise = new Promise((resolve, reject) => {
-    let testOptions = window.arguments[0].testOptions;
-    if (testOptions) {
-      resolve(testOptions.folder);
-    } else {
-      let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
-      fp.init(window, "Select directory where to create app directory", Ci.nsIFilePicker.modeGetFolder);
-      fp.open(res => {
-        if (res == Ci.nsIFilePicker.returnCancel) {
-          console.error("No directory selected");
-          reject(null);
-        } else {
-          resolve(fp.file);
-        }
-      });
+  let testOptions = window.arguments[0].testOptions;
+  if (testOptions) {
+    folder = testOptions.folder;
+  } else {
+    let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+    fp.init(window, "Select directory where to create app directory", Ci.nsIFilePicker.modeGetFolder);
+    let res = fp.show();
+    if (res == Ci.nsIFilePicker.returnCancel) {
+      console.error("No directory selected");
+      return false;
     }
-  });
+    folder = fp.file;
+  }
+
+  // Create subfolder with fs-friendly name of project
+  let subfolder = projectName.replace(/[\\/:*?"<>|]/g, "").toLowerCase();
+  let win = Services.wm.getMostRecentWindow("devtools:webide");
+  folder.append(subfolder);
+
+  try {
+    folder.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
+  } catch (e) {
+    win.UI.reportError("error_folderCreationFailed");
+    window.close();
+    return false;
+  }
+
+  // Download boilerplate zip
+  let template = gTemplateList[templatelistNode.selectedIndex];
+  let source = template.file;
+  let target = folder.clone();
+  target.append(subfolder + ".zip");
 
   let bail = (e) => {
     console.error(e);
     window.close();
   };
 
-  promise.then(folder => {
-    // Create subfolder with fs-friendly name of project
-    let subfolder = projectName.replace(/[\\/:*?"<>|]/g, "").toLowerCase();
-    let win = Services.wm.getMostRecentWindow("devtools:webide");
-    folder.append(subfolder);
-
-    try {
-      folder.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
-    } catch (e) {
-      win.UI.reportError("error_folderCreationFailed");
-      window.close();
-      return;
-    }
-
-    // Download boilerplate zip
-    let template = gTemplateList[templatelistNode.selectedIndex];
-    let source = template.file;
-    let target = folder.clone();
-    target.append(subfolder + ".zip");
-    Downloads.fetch(source, target).then(() => {
-      ZipUtils.extractFiles(target, folder);
-      target.remove(false);
-      AppProjects.addPackaged(folder).then((project) => {
-        window.arguments[0].location = project.location;
-        AppManager.validateAndUpdateProject(project).then(() => {
-          if (project.manifest) {
-            project.manifest.name = projectName;
-            AppManager.writeManifest(project).then(() => {
-              AppManager.validateAndUpdateProject(project).then(
-                () => {window.close();}, bail);
-            }, bail);
-          } else {
-            bail("Manifest not found");
-          }
-        }, bail);
+  Downloads.fetch(source, target).then(() => {
+    ZipUtils.extractFiles(target, folder);
+    target.remove(false);
+    AppProjects.addPackaged(folder).then((project) => {
+      window.arguments[0].location = project.location;
+      AppManager.validateAndUpdateProject(project).then(() => {
+        if (project.manifest) {
+          project.manifest.name = projectName;
+          AppManager.writeManifest(project).then(() => {
+            AppManager.validateAndUpdateProject(project).then(
+              () => {window.close();}, bail);
+          }, bail);
+        } else {
+          bail("Manifest not found");
+        }
       }, bail);
     }, bail);
   }, bail);
 
   return false;
 }
--- a/devtools/client/webide/content/simulator.js
+++ b/devtools/client/webide/content/simulator.js
@@ -284,41 +284,39 @@ var SimulatorEditor = {
     let input = event.target;
     switch (input.name) {
       case "name":
         simulator.options.name = input.value;
         break;
       case "version":
         switch (input.value) {
           case "pick":
-            utils.getCustomBinary(window).then(file => {
-              if (file) {
-                this.version = file.path;
-              }
-              // Whatever happens, don't stay on the "pick" option.
-              this.updateVersionSelector();
-            });
+            let file = utils.getCustomBinary(window);
+            if (file) {
+              this.version = file.path;
+            }
+            // Whatever happens, don't stay on the "pick" option.
+            this.updateVersionSelector();
             break;
           case "custom":
             this.version = input[input.selectedIndex].textContent;
             break;
           default:
             this.version = input.value;
         }
         break;
       case "profile":
         switch (input.value) {
           case "pick":
-            utils.getCustomProfile(window).then(directory => {
-              if (directory) {
-                this.profile = directory.path;
-              }
-              // Whatever happens, don't stay on the "pick" option.
-              this.updateProfileSelector();
-            });
+            let directory = utils.getCustomProfile(window);
+            if (directory) {
+              this.profile = directory.path;
+            }
+            // Whatever happens, don't stay on the "pick" option.
+            this.updateProfileSelector();
             break;
           case "custom":
             this.profile = input[input.selectedIndex].textContent;
             break;
           default:
             this.profile = input.value;
         }
         break;
--- a/devtools/client/webide/modules/project-list.js
+++ b/devtools/client/webide/modules/project-list.js
@@ -87,17 +87,17 @@ ProjectList.prototype = {
       self._telemetry.actionOccurred("webideNewProject");
     }), "creating new app");
   },
 
   importPackagedApp: function (location) {
     let parentWindow = this._parentWindow;
     let UI = this._UI;
     return UI.busyUntil(Task.spawn(function* () {
-      let directory = yield utils.getPackagedDirectory(parentWindow, location);
+      let directory = utils.getPackagedDirectory(parentWindow, location);
 
       if (!directory) {
         // User cancelled directory selection
         return;
       }
 
       yield UI.importAndSelectApp(directory);
     }), "importing packaged app");
--- a/devtools/client/webide/modules/utils.js
+++ b/devtools/client/webide/modules/utils.js
@@ -10,30 +10,25 @@ const Strings = Services.strings.createB
 function doesFileExist(location) {
   let file = new FileUtils.File(location);
   return file.exists();
 }
 exports.doesFileExist = doesFileExist;
 
 function _getFile(location, ...pickerParams) {
   if (location) {
-    return Promise.resolve(new FileUtils.File(location));
+    return new FileUtils.File(location);
   }
   let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
   fp.init(...pickerParams);
-
-  return new Promise(resolve => {
-    fp.open(res => {
-      if (res == Ci.nsIFilePicker.returnCancel) {
-        resolve(null);
-      } else {
-        resolve(fp.file);
-      }
-    });
-  });
+  let res = fp.show();
+  if (res == Ci.nsIFilePicker.returnCancel) {
+    return null;
+  }
+  return fp.file;
 }
 
 function getCustomBinary(window, location) {
   return _getFile(location, window, Strings.GetStringFromName("selectCustomBinary_title"), Ci.nsIFilePicker.modeOpen);
 }
 exports.getCustomBinary = getCustomBinary;
 
 function getCustomProfile(window, location) {
--- a/devtools/client/webide/test/test_simulators.html
+++ b/devtools/client/webide/test/test_simulators.html
@@ -185,28 +185,28 @@
 
           yield set(form.version, sim20.addonID);
 
           ok(!form.version.classList.contains("custom"), "Version selector is not customized after addon change");
           is(form.name.value, customName + "2.0", "Simulator name was updated to new version");
 
           // Pick custom binary, but act like the user aborted the file picker.
 
-          MockFilePicker.setFiles([]);
+          MockFilePicker.returnFiles = [];
           yield set(form.version, "pick");
 
           is(form.version.value, sim20.addonID, "Version selector reverted to last valid choice after customization abort");
           ok(!form.version.classList.contains("custom"), "Version selector is not customized after customization abort");
 
           // Pick custom binary, and actually follow through. (success, verify value = "custom" and textContent = custom path)
 
-          yield MockFilePicker.useAnyFile();
+          MockFilePicker.useAnyFile();
           yield set(form.version, "pick");
 
-          let fakeBinary = MockFilePicker.file;
+          let fakeBinary = MockFilePicker.returnFiles[0];
 
           ok(form.version.value == "custom", "Version selector was set to a new custom binary");
           ok(form.version.classList.contains("custom"), "Version selector is now customized");
           is(form.version.selectedOptions[0].textContent, fakeBinary.path, "Custom option textContent is correct");
 
           yield set(form.version, sim10.addonID);
 
           ok(form.version.classList.contains("custom"), "Version selector remains customized after change back to addon");
@@ -216,25 +216,25 @@
 
           ok(form.version.value == "custom", "Version selector is back to custom");
 
           // Test `profile`.
 
           is(form.profile.value, "default", "Default simulator profile");
           ok(!form.profile.classList.contains("custom"), "Profile selector is not customized");
 
-          MockFilePicker.setFiles([]);
+          MockFilePicker.returnFiles = [];
           yield set(form.profile, "pick");
 
           is(form.profile.value, "default", "Profile selector reverted to last valid choice after customization abort");
           ok(!form.profile.classList.contains("custom"), "Profile selector is not customized after customization abort");
 
           let fakeProfile = FileUtils.getDir("TmpD", []);
 
-          MockFilePicker.setFiles([ fakeProfile ]);
+          MockFilePicker.returnFiles = [ fakeProfile ];
           yield set(form.profile, "pick");
 
           ok(form.profile.value == "custom", "Profile selector was set to a new custom directory");
           ok(form.profile.classList.contains("custom"), "Profile selector is now customized");
           is(form.profile.selectedOptions[0].textContent, fakeProfile.path, "Custom option textContent is correct");
 
           yield set(form.profile, "default");
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2805,16 +2805,37 @@ nsDOMWindowUtils::GetContainerElement(ns
 
   nsCOMPtr<nsIDOMElement> element =
     do_QueryInterface(window->GetFrameElementInternal());
 
   element.forget(aResult);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile,
+                              nsISupports **aDOMFile)
+{
+  if (!aFile) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
+  NS_ENSURE_STATE(window);
+
+  nsPIDOMWindowInner* innerWindow = window->GetCurrentInnerWindow();
+  if (!innerWindow) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIDOMBlob> blob = File::CreateFromFile(innerWindow, aFile);
+  blob.forget(aDOMFile);
+  return NS_OK;
+}
+
 #ifdef DEBUG
 static bool
 CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
 {
   gfx::Matrix transform;
   if (!aLayer->GetTransform().Is2D(&transform) ||
       transform.HasNonIntegerTranslation())
     return false;
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -527,16 +527,17 @@ skip-if = toolkit == 'android' #bug 6870
 [test_bug750096.html]
 [test_bug753278.html]
 [test_bug761120.html]
 [test_bug769117.html]
 [test_bug782342.html]
 [test_bug787778.html]
 [test_bug789315.html]
 [test_bug789856.html]
+[test_bug793311.html]
 [test_bug804395.html]
 [test_bug809003.html]
 [test_bug810494.html]
 [test_bug811701.html]
 [test_bug811701.xhtml]
 [test_bug813919.html]
 [test_bug814576.html]
 [test_bug819051.html]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_bug793311.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=793311
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 793311</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug {793311} **/
+  SimpleTest.waitForExplicitFinish();
+
+  try {
+    SpecialPowers.DOMWindowUtils.wrapDOMFile(null);
+    ok(false, "wrapDOMFile(null) throws an exception");
+  } catch(e) {
+    ok(true, "wrapDOMFile(null) throws an exception");
+  }
+  SimpleTest.finish();
+
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=793311">Mozilla Bug 793311</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/dom/file/FileBlobImpl.h
+++ b/dom/file/FileBlobImpl.h
@@ -45,26 +45,16 @@ public:
                                  ErrorResult& aRv) override;
 
   virtual bool IsDirectory() const override;
 
   // We always have size and date for this kind of blob.
   virtual bool IsSizeUnknown() const override { return false; }
   virtual bool IsDateUnknown() const override { return false; }
 
-  void SetName(const nsAString& aName)
-  {
-    mName = aName;
-  }
-
-  void SetType(const nsAString& aType)
-  {
-    mContentType = aType;
-  }
-
 protected:
   virtual ~FileBlobImpl() = default;
 
 private:
   // Create slice
   FileBlobImpl(const FileBlobImpl* aOther, uint64_t aStart,
                uint64_t aLength, const nsAString& aContentType);
 
--- a/dom/file/FileCreatorHelper.cpp
+++ b/dom/file/FileCreatorHelper.cpp
@@ -77,18 +77,17 @@ FileCreatorHelper::CreateFileInternal(ns
   int64_t lastModified = 0;
   if (aBag.mLastModified.WasPassed()) {
     lastModifiedPassed = true;
     lastModified = aBag.mLastModified.Value();
   }
 
   RefPtr<BlobImpl> blobImpl;
   aRv = CreateBlobImpl(aFile, aBag.mType, aBag.mName, lastModifiedPassed,
-                       lastModified, aBag.mExistenceCheck, aIsFromNsIFile,
-                       getter_AddRefs(blobImpl));
+                       lastModified, aIsFromNsIFile, getter_AddRefs(blobImpl));
   if (aRv.Failed()) {
      return nullptr;
   }
 
   RefPtr<File> file = File::Create(aWindow, blobImpl);
   return file.forget();
 }
 
@@ -126,18 +125,17 @@ FileCreatorHelper::SendRequest(nsIFile* 
 
   nsAutoString path;
   aRv = aFile->GetPath(path);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   cc->FileCreationRequest(uuid, this, path, aBag.mType, aBag.mName,
-                          aBag.mLastModified, aBag.mExistenceCheck,
-                          aIsFromNsIFile);
+                          aBag.mLastModified, aIsFromNsIFile);
 }
 
 void
 FileCreatorHelper::ResponseReceived(BlobImpl* aBlobImpl, nsresult aRv)
 {
   if (NS_FAILED(aRv)) {
     mPromise->MaybeReject(aRv);
     return;
@@ -148,59 +146,38 @@ FileCreatorHelper::ResponseReceived(Blob
 }
 
 /* static */ nsresult
 FileCreatorHelper::CreateBlobImplForIPC(const nsAString& aPath,
                                         const nsAString& aType,
                                         const nsAString& aName,
                                         bool aLastModifiedPassed,
                                         int64_t aLastModified,
-                                        bool aExistenceCheck,
                                         bool aIsFromNsIFile,
                                         BlobImpl** aBlobImpl)
 {
   nsCOMPtr<nsIFile> file;
   nsresult rv = NS_NewLocalFile(aPath, true, getter_AddRefs(file));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return CreateBlobImpl(file, aType, aName, aLastModifiedPassed, aLastModified,
-                        aExistenceCheck, aIsFromNsIFile, aBlobImpl);
+                        aIsFromNsIFile, aBlobImpl);
 }
 
 /* static */ nsresult
 FileCreatorHelper::CreateBlobImpl(nsIFile* aFile,
                                   const nsAString& aType,
                                   const nsAString& aName,
                                   bool aLastModifiedPassed,
                                   int64_t aLastModified,
-                                  bool aExistenceCheck,
                                   bool aIsFromNsIFile,
                                   BlobImpl** aBlobImpl)
 {
-  if (!aExistenceCheck) {
-    RefPtr<FileBlobImpl> impl = new FileBlobImpl(aFile);
-
-    if (!aName.IsEmpty()) {
-      impl->SetName(aName);
-    }
-
-    if (!aType.IsEmpty()) {
-      impl->SetType(aType);
-    }
-
-    if (aLastModifiedPassed) {
-      impl->SetLastModified(aLastModified);
-    }
-
-    impl.forget(aBlobImpl);
-    return NS_OK;
-  }
-
   RefPtr<MultipartBlobImpl> impl = new MultipartBlobImpl(EmptyString());
   nsresult rv =
     impl->InitializeChromeFile(aFile, aType, aName, aLastModifiedPassed,
                                aLastModified, aIsFromNsIFile);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
--- a/dom/file/FileCreatorHelper.h
+++ b/dom/file/FileCreatorHelper.h
@@ -46,17 +46,16 @@ public:
 
   // For IPC only
   static nsresult
   CreateBlobImplForIPC(const nsAString& aPath,
                        const nsAString& aType,
                        const nsAString& aName,
                        bool aLastModifiedPassed,
                        int64_t aLastModified,
-                       bool aExistenceCheck,
                        bool aIsFromNsIFile,
                        BlobImpl** aBlobImpl);
 
 private:
   static already_AddRefed<File>
   CreateFileInternal(nsPIDOMWindowInner* aWindow,
                      nsIFile* aFile,
                      const ChromeFilePropertyBag& aBag,
@@ -64,17 +63,16 @@ private:
                      ErrorResult& aRv);
 
   static nsresult
   CreateBlobImpl(nsIFile* aFile,
                  const nsAString& aType,
                  const nsAString& aName,
                  bool aLastModifiedPassed,
                  int64_t aLastModified,
-                 bool aExistenceCheck,
                  bool aIsFromNsIFile,
                  BlobImpl** aBlobImpl);
 
   FileCreatorHelper(Promise* aPromise, nsPIDOMWindowInner* aWindow);
   ~FileCreatorHelper();
 
   void
   SendRequest(nsIFile* aFile, const ChromeFilePropertyBag& aBag,
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -1559,16 +1559,22 @@ interface nsIDOMWindowUtils : nsISupport
    * property.
    */
   double computeAnimationDistance(in nsIDOMElement element,
                                   in AString property,
                                   in AString value1,
                                   in AString value2);
 
   /**
+   * Wrap an nsIFile in an DOM File
+   * Returns a File object.
+   */
+  nsISupports wrapDOMFile(in nsIFile aFile);
+
+  /**
    * Get the type of the currently focused html input, if any.
    */
   readonly attribute string focusedInputType;
 
   /**
    * Find the view ID for a given element. This is the reverse of
    * findElementWithViewId().
    */
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -3170,32 +3170,30 @@ ContentChild::GetConstructedEventTarget(
 }
 
 void
 ContentChild::FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
                                   const nsAString& aFullPath,
                                   const nsAString& aType,
                                   const nsAString& aName,
                                   const Optional<int64_t>& aLastModified,
-                                  bool aExistenceCheck,
                                   bool aIsFromNsIFile)
 {
   MOZ_ASSERT(aHelper);
 
   bool lastModifiedPassed = false;
   int64_t lastModified = 0;
   if (aLastModified.WasPassed()) {
     lastModifiedPassed = true;
     lastModified = aLastModified.Value();
   }
 
   Unused << SendFileCreationRequest(aUUID, nsString(aFullPath), nsString(aType),
                                     nsString(aName), lastModifiedPassed,
-                                    lastModified, aExistenceCheck,
-                                    aIsFromNsIFile);
+                                    lastModified, aIsFromNsIFile);
   mFileCreationPending.Put(aUUID, aHelper);
 }
 
 mozilla::ipc::IPCResult
 ContentChild::RecvFileCreationResponse(const nsID& aUUID,
                                        const FileCreationResult& aResult)
 {
   FileCreatorHelper* helper = mFileCreationPending.GetWeak(aUUID);
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -628,17 +628,17 @@ public:
                                              base::ProcessId aOtherPid);
 
   // This method is used by FileCreatorHelper for the creation of a BlobImpl.
   void
   FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
                       const nsAString& aFullPath, const nsAString& aType,
                       const nsAString& aName,
                       const Optional<int64_t>& aLastModified,
-                      bool aExistenceCheck, bool aIsFromNsIFile);
+                      bool aIsFromNsIFile);
 
 private:
   static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
   void StartForceKillTimer();
 
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   virtual void ProcessingError(Result aCode, const char* aReason) override;
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5140,25 +5140,23 @@ ContentParent::RecvClassifyLocal(const U
 
 mozilla::ipc::IPCResult
 ContentParent::RecvFileCreationRequest(const nsID& aID,
                                        const nsString& aFullPath,
                                        const nsString& aType,
                                        const nsString& aName,
                                        const bool& aLastModifiedPassed,
                                        const int64_t& aLastModified,
-                                       const bool& aExistenceCheck,
                                        const bool& aIsFromNsIFile)
 {
   RefPtr<BlobImpl> blobImpl;
   nsresult rv =
     FileCreatorHelper::CreateBlobImplForIPC(aFullPath, aType, aName,
                                             aLastModifiedPassed,
-                                            aLastModified, aExistenceCheck,
-                                            aIsFromNsIFile,
+                                            aLastModified, aIsFromNsIFile,
                                             getter_AddRefs(blobImpl));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
       return IPC_FAIL_NO_REASON(this);
     }
 
     return IPC_OK();
   }
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -1107,17 +1107,16 @@ private:
 
   virtual mozilla::ipc::IPCResult RecvDeleteGetFilesRequest(const nsID& aID) override;
 
   virtual mozilla::ipc::IPCResult
   RecvFileCreationRequest(const nsID& aID, const nsString& aFullPath,
                           const nsString& aType, const nsString& aName,
                           const bool& aLastModifiedPassed,
                           const int64_t& aLastModified,
-                          const bool& aExistenceCheck,
                           const bool& aIsFromNsIFile) override;
 
   virtual mozilla::ipc::IPCResult RecvAccumulateChildHistograms(
     InfallibleTArray<Accumulation>&& aAccumulations) override;
   virtual mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistograms(
     InfallibleTArray<KeyedAccumulation>&& aAccumulations) override;
   virtual mozilla::ipc::IPCResult RecvUpdateChildScalars(
     InfallibleTArray<ScalarAction>&& aScalarActions) override;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -1172,18 +1172,17 @@ parent:
      */
      async NotifyLowMemory();
 
      async GetFilesRequest(nsID aID, nsString aDirectory, bool aRecursiveFlag);
      async DeleteGetFilesRequest(nsID aID);
 
      async FileCreationRequest(nsID aID, nsString aFullPath, nsString aType,
                                nsString aName, bool lastModifiedPassed,
-                               int64_t lastModified, bool aExistenceCheck,
-                               bool aIsFromNsIFile);
+                               int64_t lastModified, bool aIsFromNsIFile);
 
      async StoreAndBroadcastBlobURLRegistration(nsCString url, PBlob blob,
                                                 Principal principal);
 
      async UnstoreAndBroadcastBlobURLUnregistration(nsCString url);
 
      async BroadcastLocalStorageChange(nsString documentURI,
                                        nsString key,
--- a/dom/ipc/tests/test_bug1086684.html
+++ b/dom/ipc/tests/test_bug1086684.html
@@ -20,17 +20,17 @@
     function childFrameScript() {
       "use strict";
 
       let { MockFilePicker } =
         Components.utils.import("chrome://specialpowers/content/MockFilePicker.jsm", {});
 
       function parentReady(message) {
         MockFilePicker.init(content);
-        MockFilePicker.setFiles([message.data.file]);
+        MockFilePicker.returnFiles = [message.data.file];
         MockFilePicker.returnValue = MockFilePicker.returnOK;
 
         let input = content.document.getElementById("f");
         input.addEventListener("change", () => {
           MockFilePicker.cleanup();
           let value = input.value;
           message.target.sendAsyncMessage("testBug1086684:childDone", { value });
         });
--- a/dom/webidl/File.webidl
+++ b/dom/webidl/File.webidl
@@ -21,17 +21,16 @@ interface File : Blob {
 
 dictionary FilePropertyBag {
   DOMString type = "";
   long long lastModified;
 };
 
 dictionary ChromeFilePropertyBag : FilePropertyBag {
   DOMString name = "";
-  boolean existenceCheck = true;
 };
 
 // Mozilla extensions
 partial interface File {
   [GetterThrows, Deprecated="FileLastModifiedDate"]
   readonly attribute Date lastModifiedDate;
 
   [BinaryName="relativePath", Func="mozilla::dom::Directory::WebkitBlinkDirectoryPickerEnabled"]
--- a/layout/forms/test/test_bug536567_perwindowpb.html
+++ b/layout/forms/test/test_bug536567_perwindowpb.html
@@ -111,17 +111,17 @@ function runTest() {
     runTest();
   } else if (test == "clear history") {
     Services.obs.notifyObservers(null, "browser:purge-session-history", "");
     testIndex++;
     runTest();
   } else {
     var file = dirs[test[2]].clone();
     file.append("file.file");
-    MockFilePicker.setFiles([file]);
+    MockFilePicker.returnFiles = [file];
     content.setAttribute('src', domains[test[0]] + '/chrome/layout/forms/test/bug536567_subframe.html');
   }
 }
 
 function endTest() {
   for(var i = 0; i < dirs.length - 1; i++) {
     dirs[i].remove(true);
   }
--- a/layout/tools/layout-debug/ui/content/layoutdebug.js
+++ b/layout/tools/layout-debug/ui/content/layoutdebug.js
@@ -162,22 +162,20 @@ function toggle(menuitem)
 
 function openFile()
 {
   var nsIFilePicker = Components.interfaces.nsIFilePicker;
   var fp = Components.classes["@mozilla.org/filepicker;1"]
         .createInstance(nsIFilePicker);
   fp.init(window, "Select a File", nsIFilePicker.modeOpen);
   fp.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterAll);
-  fp.open(rv => {
-    if (rv == nsIFilePicker.returnOK && fp.fileURL.spec &&
-        fp.fileURL.spec.length > 0) {
-      gBrowser.loadURI(fp.fileURL.spec);
-    }
-  });
+  if (fp.show() == nsIFilePicker.returnOK && fp.fileURL.spec &&
+                fp.fileURL.spec.length > 0) {
+    gBrowser.loadURI(fp.fileURL.spec);
+  }
 }
 const LDB_RDFNS = "http://mozilla.org/newlayout/LDB-rdf#";
 const NC_RDFNS = "http://home.netscape.com/NC-rdf#";
 
 function RTestIndexList() {
   this.init();
 }
 
@@ -261,29 +259,27 @@ RTestIndexList.prototype = {
 
       var fp = Components.classes[NS_FILEPICKER_CONTRACTID].
                    createInstance(nsIFilePicker);
 
       // XXX l10n (but this is just for 5 developers, so no problem)
       fp.init(window, "New Regression Test List", nsIFilePicker.modeOpen);
       fp.appendFilters(nsIFilePicker.filterAll);
       fp.defaultString = "rtest.lst";
-      fp.open(rv => {
-        if (rv != nsIFilePicker.returnOK) {
-          return;
-        }
+      if (fp.show() != nsIFilePicker.returnOK)
+        return;
 
-        var file = fp.file.persistentDescriptor;
-        var resource = this.mRDFService.GetResource(file);
-        var literal = this.mRDFService.GetLiteral(file);
-        this.mDataSource.Assert(this.mLDB_Root, this.mNC_Child, resource, true);
-        this.mDataSource.Assert(resource, this.mNC_Name, literal, true);
+      var file = fp.file.persistentDescriptor;
+      var resource = this.mRDFService.GetResource(file);
+      var literal = this.mRDFService.GetLiteral(file);
+      this.mDataSource.Assert(this.mLDB_Root, this.mNC_Child, resource, true);
+      this.mDataSource.Assert(resource, this.mNC_Name, literal, true);
 
-        this.save();
-      });
+      this.save();
+
     },
 
   remove : function(file)
     {
       var resource = this.mRDFService.GetResource(file);
       var literal = this.mRDFService.GetLiteral(file);
       this.mDataSource.Unassert(this.mLDB_Root, this.mNC_Child, resource);
       this.mDataSource.Unassert(resource, this.mNC_Name, literal);
--- a/mobile/android/components/FilePicker.js
+++ b/mobile/android/components/FilePicker.js
@@ -224,23 +224,25 @@ FilePicker.prototype = {
       this._filePath = file || null;
       this._promptActive = false;
 
       if (!file) {
         return;
       }
 
       if (this._domWin) {
-        return this._domWin.File.createFromNsIFile(this.file, { existenceCheck: false });
+        let utils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+        this._domFile = utils.wrapDOMFile(this.file);
+        return;
       }
 
-      return File.createFromNsIFile(this.file, { existenceCheck: false });
-    }).then(domFile => {
-      this._domFile = domFile;
-    }, () => {
+      return File.createFromNsIFile(this.file).then(domFile => {
+        this._domFile = domFile;
+      });
+    }).catch(() => {
     }).then(() => {
       if (this._callback) {
         this._callback.done(this._filePath ?
           Ci.nsIFilePicker.returnOK : Ci.nsIFilePicker.returnCancel);
       }
       delete this._callback;
     });
   },
--- a/security/manager/pki/resources/content/certManager.js
+++ b/security/manager/pki/resources/content/certManager.js
@@ -327,21 +327,20 @@ function backupCerts()
   var bundle = document.getElementById("pippki_bundle");
   var fp = Components.classes[nsFilePicker].createInstance(nsIFilePicker);
   fp.init(window,
           bundle.getString("chooseP12BackupFileDialog"),
           nsIFilePicker.modeSave);
   fp.appendFilter(bundle.getString("file_browse_PKCS12_spec"),
                   "*.p12");
   fp.appendFilters(nsIFilePicker.filterAll);
-  fp.open(rv => {
-    if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
-      certdb.exportPKCS12File(fp.file, selected_certs.length, selected_certs);
-    }
-  });
+  var rv = fp.show();
+  if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
+    certdb.exportPKCS12File(fp.file, selected_certs.length, selected_certs);
+  }
 }
 
 function backupAllCerts()
 {
   // Select all rows, then call doBackup()
   var items = userTreeView.selection.selectAll();
   backupCerts();
 }
@@ -363,21 +362,17 @@ function restoreCerts()
   fp.init(window,
           bundle.getString("chooseP12RestoreFileDialog2"),
           nsIFilePicker.modeOpen);
   fp.appendFilter(bundle.getString("file_browse_PKCS12_spec"),
                   "*.p12; *.pfx");
   fp.appendFilter(bundle.getString("file_browse_Certificate_spec"),
                   gCertFileTypes);
   fp.appendFilters(nsIFilePicker.filterAll);
-  fp.open(rv => {
-    if (rv != nsIFilePicker.returnOK) {
-      return;
-    }
-
+  if (fp.show() == nsIFilePicker.returnOK) {
     // If this is an X509 user certificate, import it as one.
 
     var isX509FileType = false;
     var fileTypesList = gCertFileTypes.slice(1).split("; *");
     for (var type of fileTypesList) {
       if (fp.file.path.endsWith(type)) {
         isX509FileType = true;
         break;
@@ -407,17 +402,17 @@ function restoreCerts()
     }
 
     var certcache = certdb.getCerts();
     userTreeView.loadCertsFromCache(certcache, nsIX509Cert.USER_CERT);
     userTreeView.selection.clearSelection();
     caTreeView.loadCertsFromCache(certcache, nsIX509Cert.CA_CERT);
     caTreeView.selection.clearSelection();
     enableBackupAllButton();
-  });
+  }
 }
 
 function exportCerts()
 {
   getSelectedCerts();
 
   for (let cert of selected_certs) {
     exportToFile(window, cert);
@@ -485,23 +480,21 @@ function addCACerts()
   var bundle = document.getElementById("pippki_bundle");
   var fp = Components.classes[nsFilePicker].createInstance(nsIFilePicker);
   fp.init(window,
           bundle.getString("importCACertsPrompt"),
           nsIFilePicker.modeOpen);
   fp.appendFilter(bundle.getString("file_browse_Certificate_spec"),
                   gCertFileTypes);
   fp.appendFilters(nsIFilePicker.filterAll);
-  fp.open(rv => {
-    if (rv == nsIFilePicker.returnOK) {
-      certdb.importCertsFromFile(fp.file, nsIX509Cert.CA_CERT);
-      caTreeView.loadCerts(nsIX509Cert.CA_CERT);
-      caTreeView.selection.clearSelection();
-    }
-  });
+  if (fp.show() == nsIFilePicker.returnOK) {
+    certdb.importCertsFromFile(fp.file, nsIX509Cert.CA_CERT);
+    caTreeView.loadCerts(nsIX509Cert.CA_CERT);
+    caTreeView.selection.clearSelection();
+  }
 }
 
 function onSmartCardChange()
 {
   var certcache = certdb.getCerts();
   // We've change the state of the smart cards inserted or removed
   // that means the available certs may have changed. Update the display
   userTreeView.loadCertsFromCache(certcache, nsIX509Cert.USER_CERT);
@@ -521,26 +514,24 @@ function addEmailCert()
   var bundle = document.getElementById("pippki_bundle");
   var fp = Components.classes[nsFilePicker].createInstance(nsIFilePicker);
   fp.init(window,
           bundle.getString("importEmailCertPrompt"),
           nsIFilePicker.modeOpen);
   fp.appendFilter(bundle.getString("file_browse_Certificate_spec"),
                   gCertFileTypes);
   fp.appendFilters(nsIFilePicker.filterAll);
-  fp.open(rv => {
-    if (rv == nsIFilePicker.returnOK) {
-      certdb.importCertsFromFile(fp.file, nsIX509Cert.EMAIL_CERT);
-      var certcache = certdb.getCerts();
-      emailTreeView.loadCertsFromCache(certcache, nsIX509Cert.EMAIL_CERT);
-      emailTreeView.selection.clearSelection();
-      caTreeView.loadCertsFromCache(certcache, nsIX509Cert.CA_CERT);
-      caTreeView.selection.clearSelection();
-    }
-  });
+  if (fp.show() == nsIFilePicker.returnOK) {
+    certdb.importCertsFromFile(fp.file, nsIX509Cert.EMAIL_CERT);
+    var certcache = certdb.getCerts();
+    emailTreeView.loadCertsFromCache(certcache, nsIX509Cert.EMAIL_CERT);
+    emailTreeView.selection.clearSelection();
+    caTreeView.loadCertsFromCache(certcache, nsIX509Cert.CA_CERT);
+    caTreeView.selection.clearSelection();
+  }
 }
 
 function addException()
 {
   window.openDialog("chrome://pippki/content/exceptionDialog.xul", "",
                     "chrome,centerscreen,modal");
   var certcache = certdb.getCerts();
   serverTreeView.loadCertsFromCache(certcache, nsIX509Cert.SERVER_CERT);
--- a/testing/specialpowers/content/MockFilePicker.jsm
+++ b/testing/specialpowers/content/MockFilePicker.jsm
@@ -48,17 +48,16 @@ this.MockFilePicker = {
   filterXML: Ci.nsIFilePicker.filterXML,
   filterXUL: Ci.nsIFilePicker.filterXUL,
   filterApps: Ci.nsIFilePicker.filterApps,
   filterAllowURLs: Ci.nsIFilePicker.filterAllowURLs,
   filterAudio: Ci.nsIFilePicker.filterAudio,
   filterVideo: Ci.nsIFilePicker.filterVideo,
 
   window: null,
-  pendingPromises: [],
 
   init: function(window) {
     this.window = window;
 
     this.reset();
     this.factory = newFactory(window);
     if (!registrar.isCIDRegistered(newClassID)) {
       oldClassID = registrar.contractIDToCID(CONTRACT_ID);
@@ -69,95 +68,59 @@ this.MockFilePicker = {
   },
 
   reset: function() {
     this.appendFilterCallback = null;
     this.appendFiltersCallback = null;
     this.displayDirectory = null;
     this.filterIndex = 0;
     this.mode = null;
-    this.returnData = [];
+    this.returnFiles = [];
     this.returnValue = null;
     this.showCallback = null;
-    this.afterOpenCallback = null;
     this.shown = false;
     this.showing = false;
   },
 
   cleanup: function() {
     var previousFactory = this.factory;
     this.reset();
     this.factory = null;
     if (oldFactory) {
       registrar.unregisterFactory(newClassID, previousFactory);
       registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
     }
   },
 
-  internalFileData(obj) {
-    return {
-      nsIFile: "nsIFile" in obj ? obj.nsIFile : null,
-      domFile: "domFile" in obj ? obj.domFile : null,
-      domDirectory: "domDirectory" in obj ? obj.domDirectory : null,
-    };
-  },
-
   useAnyFile: function() {
     var file = FileUtils.getDir("TmpD", [], false);
     file.append("testfile");
     file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o644);
-    let promise = this.window.File.createFromNsIFile(file)
-                  .then(domFile => domFile, () => null)
-                  // domFile can be null.
-                  .then(domFile => {
-                    this.returnData = [this.internalFileData({ nsIFile: file, domFile: domFile })];
-                  }).then(() => file);
-
-    this.pendingPromises = [promise];
-
-    // We return a promise in order to support some existing mochitests.
-    return promise;
+    this.returnFiles = [file];
   },
 
   useBlobFile: function() {
     var blob = new this.window.Blob([]);
     var file = new this.window.File([blob], 'helloworld.txt', { type: 'plain/text' });
-    this.returnData = [this.internalFileData({ domFile: file })];
-    this.pendingPromises = [];
+    this.returnFiles = [file];
   },
 
   useDirectory: function(aPath) {
     var directory = new this.window.Directory(aPath);
-    this.returnData = [this.internalFileData({ domDirectory: directory })];
-    this.pendingPromises = [];
+    this.returnFiles = [directory];
   },
 
-  setFiles(files) {
-    this.returnData = [];
-    this.pendingPromises = [];
-
-    for (let file of files) {
-      if (file instanceof this.window.File) {
-        this.returnData.push(this.internalFileData({ domFile: file }));
-      } else {
-        let promise = this.window.File.createFromNsIFile(file, { existenceCheck: false });
+  isNsIFile: function(aFile) {
+    let ret = false;
+    try {
+      if (aFile.QueryInterface(Ci.nsIFile))
+        ret = true;
+    } catch(e) {}
 
-        promise.then(domFile => {
-          this.returnData.push(this.internalFileData({ nsIFile: file, domFile: domFile }));
-        });
-        this.pendingPromises.push(promise);
-      }
-    }
-  },
-
-  getNsIFile() {
-    if (this.returnData.length >= 1) {
-      return this.returnData[0].nsIFile;
-    }
-    return null;
+    return ret;
   }
 };
 
 function MockFilePickerInstance(window) {
   this.window = window;
 };
 MockFilePickerInstance.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
@@ -175,134 +138,98 @@ MockFilePickerInstance.prototype = {
       MockFilePicker.appendFiltersCallback(this, aFilterMask);
   },
   defaultString: "",
   defaultExtension: "",
   parent: null,
   filterIndex: 0,
   displayDirectory: null,
   get file() {
-    if (MockFilePicker.returnData.length >= 1) {
-      return MockFilePicker.returnData[0].nsIFile;
+    if (MockFilePicker.returnFiles.length >= 1 &&
+        // window.File does not implement nsIFile
+        MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
+      return MockFilePicker.returnFiles[0];
     }
 
     return null;
   },
 
   // We don't support directories here.
   get domFileOrDirectory()  {
-    if (MockFilePicker.returnData.length < 1) {
-      return null;
-    }
+    if (MockFilePicker.returnFiles.length >= 1) {
+      // window.File does not implement nsIFile
+      if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
+        return MockFilePicker.returnFiles[0];
+      }
 
-    if (MockFilePicker.returnData[0].domFile) {
-      return MockFilePicker.returnData[0].domFile;
+      let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
+                             .getInterface(Ci.nsIDOMWindowUtils);
+      return utils.wrapDOMFile(MockFilePicker.returnFiles[0]);
     }
-
-    if (MockFilePicker.returnData[0].domDirectory) {
-      return MockFilePicker.returnData[0].domDirectory;
-    }
-
     return null;
   },
   get fileURL() {
-    if (MockFilePicker.returnData.length >= 1 &&
-        MockFilePicker.returnData[0].nsIFile) {
-      return Services.io.newFileURI(MockFilePicker.returnData[0].nsIFile);
+    if (MockFilePicker.returnFiles.length >= 1 &&
+        // window.File does not implement nsIFile
+        MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
+      return Services.io.newFileURI(MockFilePicker.returnFiles[0]);
     }
 
     return null;
   },
   get files() {
     return {
       index: 0,
       QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
       hasMoreElements: function() {
-        return this.index < MockFilePicker.returnData.length;
+        return this.index < MockFilePicker.returnFiles.length;
       },
       getNext: function() {
-        if (!MockFilePicker.returnData[this.index].nsIFile) {
+        // window.File does not implement nsIFile
+        if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
           return null;
         }
-        return MockFilePicker.returnData[this.index++].nsIFile;
+        return MockFilePicker.returnFiles[this.index++];
       }
     };
   },
   get domFileOrDirectoryEnumerator()  {
     let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIDOMWindowUtils);
     return {
       index: 0,
       QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
       hasMoreElements: function() {
-        return this.index < MockFilePicker.returnData.length;
+        return this.index < MockFilePicker.returnFiles.length;
       },
       getNext: function() {
         // window.File does not implement nsIFile
-        if (MockFilePicker.returnData[this.index].domFile) {
-          return MockFilePicker.returnData[this.index++].domFile;
+        if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
+          return MockFilePicker.returnFiles[this.index++];
         }
-
-        if (MockFilePicker.returnData[this.index].domDirectory) {
-          return MockFilePicker.returnData[this.index++].domDirectory;
-        }
-
-        return null;
+        return utils.wrapDOMFile(MockFilePicker.returnFiles[this.index++]);
       }
     };
   },
   show: function() {
-    throw "This is not implemented";
+    MockFilePicker.displayDirectory = this.displayDirectory;
+    MockFilePicker.shown = true;
+    if (typeof MockFilePicker.showCallback == "function") {
+      var returnValue = MockFilePicker.showCallback(this);
+      if (typeof returnValue != "undefined")
+        return returnValue;
+    }
+    return MockFilePicker.returnValue;
   },
   open: function(aFilePickerShownCallback) {
     MockFilePicker.showing = true;
-    this.window.setTimeout(() => {
-      // Maybe all the pending promises are already resolved, but we want to be sure.
-      Promise.all(MockFilePicker.pendingPromises).then(() => {
-        return Ci.nsIFilePicker.returnOK;
-      }, () => {
-        return Ci.nsIFilePicker.returnCancel;
-      }).then(result => {
-        // Nothing else has to be done.
-        MockFilePicker.pendingPromises = [];
-
-        if (result == Ci.nsIFilePicker.returnCancel) {
-          return result;
-        }
-
-        MockFilePicker.displayDirectory = this.displayDirectory;
-        MockFilePicker.shown = true;
-        if (typeof MockFilePicker.showCallback == "function") {
-          try {
-            var returnValue = MockFilePicker.showCallback(this);
-            if (typeof returnValue != "undefined") {
-              return returnValue;
-            }
-          } catch(ex) {
-            return Ci.nsIFilePicker.returnCancel;
-          }
-        }
-
-        return MockFilePicker.returnValue;
-      }).then(result => {
-        // Some additional result file can be set by the callback. Let's
-        // resolve the pending promises again.
-        return Promise.all(MockFilePicker.pendingPromises).then(() => {
-          return result;
-        }, () => {
-          return Ci.nsIFilePicker.returnCancel;
-        });
-      }).then(result => {
-        MockFilePicker.pendingPromises = [];
-
-        if (aFilePickerShownCallback) {
-          aFilePickerShownCallback.done(result);
-        }
-
-        if (typeof MockFilePicker.afterOpenCallback == "function") {
-          this.window.setTimeout(() => {
-            MockFilePicker.afterOpenCallback(this);
-          }, 0);
-        }
-      });
-    });
+    this.window.setTimeout(function() {
+      let result = Components.interfaces.nsIFilePicker.returnCancel;
+      try {
+        result = this.show();
+      } catch(ex) {
+      }
+      if (aFilePickerShownCallback) {
+        aFilePickerShownCallback.done(result);
+      }
+    }.bind(this), 0);
   }
 };
--- a/toolkit/components/apppicker/content/appPicker.js
+++ b/toolkit/components/apppicker/content/appPicker.js
@@ -188,25 +188,23 @@ AppPicker.prototype =
       } else if (AppConstants.platform == "macosx") {
         startLocation = "LocApp"; // Local Applications
       } else {
         startLocation = "Home";
       }
       fp.displayDirectory =
         fileLoc.get(startLocation, Components.interfaces.nsILocalFile);
 
-      fp.open(rv => {
-          if (rv == nsIFilePicker.returnOK && fp.file) {
-              var localHandlerApp =
-                Components.classes["@mozilla.org/uriloader/local-handler-app;1"].
-                createInstance(Components.interfaces.nsILocalHandlerApp);
-              localHandlerApp.executable = fp.file;
+      if (fp.show() == nsIFilePicker.returnOK && fp.file) {
+          var localHandlerApp =
+            Components.classes["@mozilla.org/uriloader/local-handler-app;1"].
+            createInstance(Components.interfaces.nsILocalHandlerApp);
+          localHandlerApp.executable = fp.file;
 
-              this._incomingParams.handlerApp = localHandlerApp;
-              window.close();
-          }
-      });
+          this._incomingParams.handlerApp = localHandlerApp;
+          window.close();
+      }
       return true;
     }
 }
 
 // Global object
 var g_dialog = new AppPicker();
--- a/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html
+++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html
@@ -14,43 +14,42 @@
 
 add_task(function* test_downloads_saveAs() {
   function background() {
     const url = URL.createObjectURL(new Blob(["file content"]));
     browser.test.onMessage.addListener(async () => {
       try {
         let id = await browser.downloads.download({url, saveAs: true});
         browser.downloads.onChanged.addListener(delta => {
-          if (delta.id == id && delta.state.current === "complete") {
+          if (delta.state.current === "complete") {
             browser.test.sendMessage("done", {ok: true, id});
           }
         });
       } catch ({message}) {
         browser.test.sendMessage("done", {ok: false, message});
       }
     });
     browser.test.sendMessage("ready");
   }
 
   const {MockFilePicker} = SpecialPowers;
   const manifest = {background, manifest: {permissions: ["downloads"]}};
   const extension = ExtensionTestUtils.loadExtension(manifest);
 
   MockFilePicker.init(window);
-  const file = yield MockFilePicker.useAnyFile();
+  MockFilePicker.useAnyFile();
+  const [file] = MockFilePicker.returnFiles;
 
   yield extension.startup();
   yield extension.awaitMessage("ready");
 
   extension.sendMessage("download");
   let result = yield extension.awaitMessage("done");
 
   ok(result.ok, "downloads.download() works with saveAs");
-
-  ok(file.exists(), "the file exists.");
   is(file.fileSize, 12, "downloaded file is the correct size");
   file.remove(false);
 
   // Test the user canceling the save dialog.
   MockFilePicker.returnValue = MockFilePicker.returnCancel;
 
   extension.sendMessage("download");
   result = yield extension.awaitMessage("done");
--- a/toolkit/components/filepicker/nsFilePicker.js
+++ b/toolkit/components/filepicker/nsFilePicker.js
@@ -99,16 +99,45 @@ nsFilePicker.prototype = {
     return enumerator ? enumerator.mFiles[0] : null;
   },
 
   /* readonly attribute nsISimpleEnumerator domFileOrDirectoryEnumerator; */
   get domFileOrDirectoryEnumerator() {
     if (!this.mFilesEnumerator) {
       return null;
     }
+
+    if (!this.mDOMFilesEnumerator) {
+      this.mDOMFilesEnumerator = {
+        QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISimpleEnumerator]),
+
+        mFiles: [],
+        mIndex: 0,
+
+        hasMoreElements() {
+          return (this.mIndex < this.mFiles.length);
+        },
+
+        getNext() {
+          if (this.mIndex >= this.mFiles.length) {
+            throw Components.results.NS_ERROR_FAILURE;
+          }
+          return this.mFiles[this.mIndex++];
+        }
+      };
+
+      var utils = this.mParentWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                                    .getInterface(Components.interfaces.nsIDOMWindowUtils);
+
+      for (var i = 0; i < this.mFilesEnumerator.mFiles.length; ++i) {
+        var file = utils.wrapDOMFile(this.mFilesEnumerator.mFiles[i]);
+        this.mDOMFilesEnumerator.mFiles.push(file);
+      }
+    }
+
     return this.mDOMFilesEnumerator;
   },
 
   /* readonly attribute nsIURI fileURL; */
   get fileURL() {
     if (this.mFileURL)
       return this.mFileURL;
 
@@ -196,64 +225,26 @@ nsFilePicker.prototype = {
   appendFilter(title, extensions) {
     this.mFilterTitles.push(title);
     this.mFilters.push(extensions);
   },
 
   open(aFilePickerShownCallback) {
     var tm = Components.classes["@mozilla.org/thread-manager;1"]
                        .getService(Components.interfaces.nsIThreadManager);
-    tm.mainThread.dispatch(() => {
+    tm.mainThread.dispatch(function() {
       let result = Components.interfaces.nsIFilePicker.returnCancel;
       try {
         result = this.show();
       } catch (ex) {
       }
-
-      let promises = [];
-
-      // Let's create the DOMFileEnumerator right now because it requires some
-      // async operation.
-      if (this.mFilesEnumerator) {
-        this.mDOMFilesEnumerator = {
-          QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISimpleEnumerator]),
-
-          mFiles: [],
-          mIndex: 0,
-
-          hasMoreElements() {
-            return (this.mIndex < this.mFiles.length);
-          },
-
-          getNext() {
-            if (this.mIndex >= this.mFiles.length) {
-              throw Components.results.NS_ERROR_FAILURE;
-            }
-            return this.mFiles[this.mIndex++];
-          }
-        };
-
-        for (let i = 0; i < this.mFilesEnumerator.mFiles.length; ++i) {
-          if (this.mFilesEnumerator.mFiles[i].exists()) {
-            let promise =
-              this.mParentWindow.File.createFromNsIFile(
-                this.mFilesEnumerator.mFiles[i]).then(file => {
-                  this.mDOMFilesEnumerator.mFiles.push(file);
-                });
-            promises.push(promise);
-          }
-        }
+      if (aFilePickerShownCallback) {
+        aFilePickerShownCallback.done(result);
       }
-
-      Promise.all(promises).then(() => {
-        if (aFilePickerShownCallback) {
-          aFilePickerShownCallback.done(result);
-        }
-      });
-    }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+    }.bind(this), Components.interfaces.nsIThread.DISPATCH_NORMAL);
   },
 
   show() {
     var o = {};
     o.title = this.mTitle;
     o.mode = this.mMode;
     o.displayDirectory = this.mDisplayDirectory;
     o.defaultString = this.mDefaultString;
--- a/toolkit/components/printing/content/printdialog.js
+++ b/toolkit/components/printing/content/printdialog.js
@@ -297,97 +297,84 @@ function onLoad() {
   // default return value is "cancel"
   paramBlock.SetInt(0, 0);
 
   loadDialog();
 }
 
 // ---------------------------------------------------
 function onAccept() {
-  let promise;
-
-  if (gPrintSettings == null) {
-    promise = Promise.resolve();
-  } else {
+  if (gPrintSettings != null) {
     var print_howToEnableUI = gPrintSetInterface.kFrameEnableNone;
 
     // save these out so they can be picked up by the device spec
     gPrintSettings.printerName = dialog.printerList.value;
     print_howToEnableUI        = gPrintSettings.howToEnableFrameUI;
     gPrintSettings.printToFile = dialog.fileCheck.checked;
 
-    if (gPrintSettings.printToFile) {
-      promise = chooseFile();
-    } else {
-      promise = Promise.resolve();
-    }
+    if (gPrintSettings.printToFile && !chooseFile())
+      return false;
 
-    promise = promise.then(() => {
-      if (dialog.allpagesRadio.selected) {
-        gPrintSettings.printRange = gPrintSetInterface.kRangeAllPages;
-      } else if (dialog.rangeRadio.selected) {
-        gPrintSettings.printRange = gPrintSetInterface.kRangeSpecifiedPageRange;
-      } else if (dialog.selectionRadio.selected) {
-        gPrintSettings.printRange = gPrintSetInterface.kRangeSelection;
-      }
-      gPrintSettings.startPageRange = dialog.frompageInput.value;
-      gPrintSettings.endPageRange   = dialog.topageInput.value;
-      gPrintSettings.numCopies      = dialog.numCopiesInput.value;
+    if (dialog.allpagesRadio.selected) {
+      gPrintSettings.printRange = gPrintSetInterface.kRangeAllPages;
+    } else if (dialog.rangeRadio.selected) {
+      gPrintSettings.printRange = gPrintSetInterface.kRangeSpecifiedPageRange;
+    } else if (dialog.selectionRadio.selected) {
+      gPrintSettings.printRange = gPrintSetInterface.kRangeSelection;
+    }
+    gPrintSettings.startPageRange = dialog.frompageInput.value;
+    gPrintSettings.endPageRange   = dialog.topageInput.value;
+    gPrintSettings.numCopies      = dialog.numCopiesInput.value;
 
-      var frametype = gPrintSetInterface.kNoFrames;
-      if (print_howToEnableUI != gPrintSetInterface.kFrameEnableNone) {
-        if (dialog.aslaidoutRadio.selected) {
-          frametype = gPrintSetInterface.kFramesAsIs;
-        } else if (dialog.selectedframeRadio.selected) {
-          frametype = gPrintSetInterface.kSelectedFrame;
-        } else if (dialog.eachframesepRadio.selected) {
-          frametype = gPrintSetInterface.kEachFrameSep;
-        } else {
-          frametype = gPrintSetInterface.kSelectedFrame;
-        }
+    var frametype = gPrintSetInterface.kNoFrames;
+    if (print_howToEnableUI != gPrintSetInterface.kFrameEnableNone) {
+      if (dialog.aslaidoutRadio.selected) {
+        frametype = gPrintSetInterface.kFramesAsIs;
+      } else if (dialog.selectedframeRadio.selected) {
+        frametype = gPrintSetInterface.kSelectedFrame;
+      } else if (dialog.eachframesepRadio.selected) {
+        frametype = gPrintSetInterface.kEachFrameSep;
+      } else {
+        frametype = gPrintSetInterface.kSelectedFrame;
       }
-      gPrintSettings.printFrameType = frametype;
-      if (doDebug) {
-        dump("onAccept*********************************************\n");
-        dump("frametype      " + frametype + "\n");
-        dump("numCopies      " + gPrintSettings.numCopies + "\n");
-        dump("printRange     " + gPrintSettings.printRange + "\n");
-        dump("printerName    " + gPrintSettings.printerName + "\n");
-        dump("startPageRange " + gPrintSettings.startPageRange + "\n");
-        dump("endPageRange   " + gPrintSettings.endPageRange + "\n");
-        dump("printToFile    " + gPrintSettings.printToFile + "\n");
-      }
-    });
+    }
+    gPrintSettings.printFrameType = frametype;
+    if (doDebug) {
+      dump("onAccept*********************************************\n");
+      dump("frametype      " + frametype + "\n");
+      dump("numCopies      " + gPrintSettings.numCopies + "\n");
+      dump("printRange     " + gPrintSettings.printRange + "\n");
+      dump("printerName    " + gPrintSettings.printerName + "\n");
+      dump("startPageRange " + gPrintSettings.startPageRange + "\n");
+      dump("endPageRange   " + gPrintSettings.endPageRange + "\n");
+      dump("printToFile    " + gPrintSettings.printToFile + "\n");
+    }
   }
 
-  promise.then(() => {
-    var saveToPrefs = false;
+  var saveToPrefs = false;
 
-    saveToPrefs = gPrefs.getBoolPref("print.save_print_settings");
+  saveToPrefs = gPrefs.getBoolPref("print.save_print_settings");
 
-    if (saveToPrefs && printService != null) {
-      var flags = gPrintSetInterface.kInitSavePaperSize |
-                  gPrintSetInterface.kInitSaveEdges |
-                  gPrintSetInterface.kInitSaveInColor |
-                  gPrintSetInterface.kInitSaveShrinkToFit |
-                  gPrintSetInterface.kInitSaveScaling;
-      printService.savePrintSettingsToPrefs(gPrintSettings, true, flags);
-    }
+  if (saveToPrefs && printService != null) {
+    var flags = gPrintSetInterface.kInitSavePaperSize |
+                gPrintSetInterface.kInitSaveEdges |
+                gPrintSetInterface.kInitSaveInColor |
+                gPrintSetInterface.kInitSaveShrinkToFit |
+                gPrintSetInterface.kInitSaveScaling;
+    printService.savePrintSettingsToPrefs(gPrintSettings, true, flags);
+  }
 
-    // set return value to "print"
-    if (paramBlock) {
-      paramBlock.SetInt(0, 1);
-    } else {
-      dump("*** FATAL ERROR: No paramBlock\n");
-    }
+  // set return value to "print"
+  if (paramBlock) {
+    paramBlock.SetInt(0, 1);
+  } else {
+    dump("*** FATAL ERROR: No paramBlock\n");
+  }
 
-    window.close();
-  });
-
-  return false;
+  return true;
 }
 
 // ---------------------------------------------------
 function onCancel() {
   // set return value to "cancel"
   if (paramBlock) {
     paramBlock.SetInt(0, 0);
   } else {
@@ -395,22 +382,24 @@ function onCancel() {
   }
 
   return true;
 }
 
 // ---------------------------------------------------
 const nsIFilePicker = Components.interfaces.nsIFilePicker;
 function chooseFile() {
-  return new Promise(resolve => {
+  try {
     var fp = Components.classes["@mozilla.org/filepicker;1"]
                        .createInstance(nsIFilePicker);
     fp.init(window, dialog.fpDialog.getAttribute("label"), nsIFilePicker.modeSave);
     fp.appendFilters(nsIFilePicker.filterAll);
-    fp.open(rv => {
-      if (rv != Components.interfaces.nsIFilePicker.returnCancel &&
-          fp.file && fp.file.path) {
-        gPrintSettings.toFileName = fp.file.path;
-        resolve(null);
-      }
-    });
-  });
+    if (fp.show() != Components.interfaces.nsIFilePicker.returnCancel &&
+        fp.file && fp.file.path) {
+      gPrintSettings.toFileName = fp.file.path;
+      return true;
+    }
+  } catch (ex) {
+    dump(ex);
+  }
+
+  return false;
 }
--- a/toolkit/components/tooltiptext/tests/browser_input_file_tooltips.js
+++ b/toolkit/components/tooltiptext/tests/browser_input_file_tooltips.js
@@ -58,31 +58,32 @@ function* do_test(test) {
   });
 
   if (test.value) {
     info("Creating mock filepicker to select files");
     let MockFilePicker = SpecialPowers.MockFilePicker;
     MockFilePicker.init(window);
     MockFilePicker.returnValue = MockFilePicker.returnOK;
     MockFilePicker.displayDirectory = FileUtils.getDir("TmpD", [], false);
-    MockFilePicker.setFiles([tempFile]);
-    MockFilePicker.afterOpenCallback = MockFilePicker.cleanup;
+    MockFilePicker.returnFiles = [tempFile];
 
     try {
       // Open the File Picker dialog (MockFilePicker) to select
       // the files for the test.
       yield BrowserTestUtils.synthesizeMouseAtCenter("#test_input", {}, tab.linkedBrowser);
       info("Waiting for the input to have the requisite files");
       yield ContentTask.spawn(tab.linkedBrowser, {}, function*() {
         let input = content.document.querySelector("#test_input");
         yield ContentTaskUtils.waitForCondition(() => input.files.length,
           "The input should have at least one file selected");
         info(`The input has ${input.files.length} file(s) selected.`);
       });
-    } catch (e) {}
+    } finally {
+      MockFilePicker.cleanup();
+    }
   } else {
     info("No real file selection required.");
   }
 
   let awaitTooltipOpen = new Promise(resolve => {
     let tooltipId = Services.appinfo.browserTabsRemoteAutostart ?
                       "remoteBrowserTooltip" :
                       "aHTMLTooltip";
--- a/toolkit/content/tests/browser/browser_save_resend_postdata.js
+++ b/toolkit/content/tests/browser/browser_save_resend_postdata.js
@@ -48,17 +48,17 @@ function test() {
 
   function handleInnerSubmit() {
     gBrowser.removeEventListener("DOMContentLoaded", handleInnerSubmit);
 
     // Create the folder the page will be saved into.
     var destDir = createTemporarySaveDirectory();
     var file = destDir.clone();
     file.append("no_default_file_name");
-    MockFilePicker.setFiles([file]);
+    MockFilePicker.returnFiles = [file];
     MockFilePicker.showCallback = function(fp) {
       MockFilePicker.filterIndex = 1; // kSaveAsType_URL
     };
 
     mockTransferCallback = onTransferComplete;
     mockTransferRegisterer.register();
 
     registerCleanupFunction(function() {
@@ -75,17 +75,17 @@ function test() {
                  docToSave.referrer ? makeURI(docToSave.referrer) : null,
                  docToSave, false, null);
   }
 
   function onTransferComplete(downloadSuccess) {
     ok(downloadSuccess, "The inner frame should have been downloaded successfully");
 
     // Read the entire saved file.
-    var file = MockFilePicker.getNsIFile();
+    var file = MockFilePicker.returnFiles[0];
     var fileContents = readShortFile(file);
 
     // Check if outer POST data is found (bug 471962).
     is(fileContents.indexOf("inputfield=outer"), -1,
        "The saved inner frame does not contain outer POST data");
 
     // Check if inner POST data is found (bug 485196).
     isnot(fileContents.indexOf("inputfield=inner"), -1,
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js
+++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js
@@ -311,65 +311,63 @@ nsUnknownContentTypeDialog.prototype = {
       // return a valid directory path, so we can safely default to it.
       let preferredDir = yield Downloads.getPreferredDownloadsDirectory();
       picker.displayDirectory = new FileUtils.File(preferredDir);
 
       gDownloadLastDir.getFileAsync(aLauncher.source, function LastDirCallback(lastDir) {
         if (lastDir && isUsableDirectory(lastDir))
           picker.displayDirectory = lastDir;
 
-        picker.open(returnValue => {
-          if (returnValue == nsIFilePicker.returnCancel) {
-            // null result means user cancelled.
-            aLauncher.saveDestinationAvailable(null);
-            return;
+        if (picker.show() == nsIFilePicker.returnCancel) {
+          // null result means user cancelled.
+          aLauncher.saveDestinationAvailable(null);
+          return;
+        }
+
+        // Be sure to save the directory the user chose through the Save As...
+        // dialog  as the new browser.download.dir since the old one
+        // didn't exist.
+        result = picker.file;
+
+        if (result) {
+          try {
+            // Remove the file so that it's not there when we ensure non-existence later;
+            // this is safe because for the file to exist, the user would have had to
+            // confirm that he wanted the file overwritten.
+            // Only remove file if final name exists
+            if (result.exists() && this.getFinalLeafName(result.leafName) == result.leafName)
+              result.remove(false);
+          }
+          catch (ex) {
+            // As it turns out, the failure to remove the file, for example due to
+            // permission error, will be handled below eventually somehow.
           }
 
-          // Be sure to save the directory the user chose through the Save As...
-          // dialog  as the new browser.download.dir since the old one
-          // didn't exist.
-          result = picker.file;
+          var newDir = result.parent.QueryInterface(Components.interfaces.nsILocalFile);
+
+          // Do not store the last save directory as a pref inside the private browsing mode
+          gDownloadLastDir.setFile(aLauncher.source, newDir);
 
-          if (result) {
-            try {
-              // Remove the file so that it's not there when we ensure non-existence later;
-              // this is safe because for the file to exist, the user would have had to
-              // confirm that he wanted the file overwritten.
-              // Only remove file if final name exists
-              if (result.exists() && this.getFinalLeafName(result.leafName) == result.leafName)
-                result.remove(false);
-            }
-            catch (ex) {
-              // As it turns out, the failure to remove the file, for example due to
-              // permission error, will be handled below eventually somehow.
+          try {
+            result = this.validateLeafName(newDir, result.leafName, null);
+          }
+          catch (ex) {
+            // When the chosen download directory is write-protected,
+            // display an informative error message.
+            // In all cases, download will be stopped.
+
+            if (ex.result == Components.results.NS_ERROR_FILE_ACCESS_DENIED) {
+              this.displayBadPermissionAlert();
+              aLauncher.saveDestinationAvailable(null);
+              return;
             }
 
-            var newDir = result.parent.QueryInterface(Components.interfaces.nsILocalFile);
-
-            // Do not store the last save directory as a pref inside the private browsing mode
-            gDownloadLastDir.setFile(aLauncher.source, newDir);
-
-            try {
-              result = this.validateLeafName(newDir, result.leafName, null);
-            }
-            catch (ex) {
-              // When the chosen download directory is write-protected,
-              // display an informative error message.
-              // In all cases, download will be stopped.
-
-              if (ex.result == Components.results.NS_ERROR_FILE_ACCESS_DENIED) {
-                this.displayBadPermissionAlert();
-                aLauncher.saveDestinationAvailable(null);
-                return;
-              }
-
-            }
           }
-          aLauncher.saveDestinationAvailable(result);
-        });
+        }
+        aLauncher.saveDestinationAvailable(result);
       }.bind(this));
     }.bind(this)).then(null, Components.utils.reportError);
   },
 
   getFinalLeafName: function (aLeafName, aFileExt)
   {
     // Remove any leading periods, since we don't want to save hidden files
     // automatically.
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -1406,29 +1406,27 @@ var gViewController = {
                 gStrings.ext.GetStringFromName("installFromFile.dialogTitle"),
                 nsIFilePicker.modeOpenMultiple);
         try {
           fp.appendFilter(gStrings.ext.GetStringFromName("installFromFile.filterName"),
                           "*.xpi;*.jar;*.zip");
           fp.appendFilters(nsIFilePicker.filterAll);
         } catch (e) { }
 
-        fp.open(result => {
-          if (result != nsIFilePicker.returnOK)
-            return;
-
-          let browser = getBrowserElement();
-          let files = fp.files;
-          while (files.hasMoreElements()) {
-            let file = files.getNext();
-            AddonManager.getInstallForFile(file, install => {
-              AddonManager.installAddonFromAOM(browser, document.documentURI, install);
-            });
-          }
-        });
+        if (fp.show() != nsIFilePicker.returnOK)
+          return;
+
+        let browser = getBrowserElement();
+        let files = fp.files;
+        while (files.hasMoreElements()) {
+          let file = files.getNext();
+          AddonManager.getInstallForFile(file, install => {
+            AddonManager.installAddonFromAOM(browser, document.documentURI, install);
+          });
+        }
       }
     },
 
     cmd_debugAddons: {
       isEnabled() {
         return true;
       },
       doCommand() {
--- a/toolkit/mozapps/extensions/content/setting.xml
+++ b/toolkit/mozapps/extensions/content/setting.xml
@@ -369,22 +369,20 @@
               let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
               file.initWithPath(this.value);
               filePicker.displayDirectory = this.type == "file" ? file.parent : file;
               if (this.type == "file") {
                 filePicker.defaultString = file.leafName;
               }
             } catch (e) {}
           }
-          filePicker.open(rv => {
-            if (rv != Ci.nsIFilePicker.returnCancel && filePicker.file) {
-              this.value = filePicker.file.path;
-              this.inputChanged();
-            }
-          });
+          if (filePicker.show() != Ci.nsIFilePicker.returnCancel) {
+            this.value = filePicker.file.path;
+            this.inputChanged();
+          }
         ]]>
         </body>
       </method>
 
       <method name="valueFromPreference">
         <body>
         <![CDATA[
           this.value = Preferences.get(this.pref, "");
--- a/toolkit/mozapps/extensions/test/browser/browser_bug567127.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_bug567127.js
@@ -86,17 +86,17 @@ function checkInstallConfirmation(...url
 
 add_task(function* test_install_from_file() {
   gManagerWindow = yield open_manager("addons://list/extension");
 
   var filePaths = [
                    get_addon_file_url("browser_bug567127_1.xpi"),
                    get_addon_file_url("browser_bug567127_2.xpi")
                   ];
-  MockFilePicker.setFiles(filePaths.map(aPath => aPath.file));
+  MockFilePicker.returnFiles = filePaths.map(aPath => aPath.file);
 
   // Set handler that executes the core test after the window opens,
   // and resolves the promise when the window closes
   let pInstallURIClosed = checkInstallConfirmation(...filePaths.map(path => path.spec));
 
   gManagerWindow.gViewController.doCommand("cmd_installFromFile");
 
   yield pInstallURIClosed;
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
@@ -272,94 +272,74 @@ add_test(function() {
     input.focus();
     EventUtils.synthesizeKey("VK_RIGHT", {}, gManagerWindow);
     EventUtils.synthesizeKey("VK_RIGHT", {}, gManagerWindow);
     EventUtils.synthesizeKey("VK_RETURN", {}, gManagerWindow);
     input.hidePopup();
     is(input.color, "#FF9900", "Color picker should have updated value");
     is(Services.prefs.getCharPref("extensions.inlinesettings1.color"), "#FF9900", "Color pref should have been updated");
 
-    ok(!settings[6].hasAttribute("first-row"), "Not the first row");
-    var button = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "button");
-    input = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "input");
-    is(input.value, "", "Label value should be empty");
-    is(input.tooltipText, "", "Label tooltip should be empty");
-
-    var testFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
-    testFile.append("\u2622");
-    var curProcD = Services.dirsvc.get("CurProcD", Ci.nsIFile);
+    try {
+      ok(!settings[6].hasAttribute("first-row"), "Not the first row");
+      var button = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "button");
+      input = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "input");
+      is(input.value, "", "Label value should be empty");
+      is(input.tooltipText, "", "Label tooltip should be empty");
 
-    MockFilePicker.setFiles([testFile]);
-    MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
+      var testFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
+      testFile.append("\u2622");
+      var curProcD = Services.dirsvc.get("CurProcD", Ci.nsIFile);
 
-    let promise = new Promise(resolve => {
-      MockFilePicker.afterOpenCallback = resolve;
+      MockFilePicker.returnFiles = [testFile];
+      MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
       EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
-    });
-
-    promise.then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeOpen, "File picker mode should be open file");
       is(input.value, testFile.path, "Label value should match file chosen");
       is(input.tooltipText, testFile.path, "Label tooltip should match file chosen");
       is(Preferences.get("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should match file chosen");
 
-      MockFilePicker.setFiles([curProcD]);
+      MockFilePicker.returnFiles = [curProcD];
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnCancel;
-
-      return new Promise(resolve => {
-        MockFilePicker.afterOpenCallback = resolve;
-        EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
-      });
-    }).then(() => {
+      EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeOpen, "File picker mode should be open file");
       is(input.value, testFile.path, "Label value should not have changed");
       is(input.tooltipText, testFile.path, "Label tooltip should not have changed");
       is(Preferences.get("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should not have changed");
 
       ok(!settings[7].hasAttribute("first-row"), "Not the first row");
       button = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "button");
       input = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "input");
       is(input.value, "", "Label value should be empty");
       is(input.tooltipText, "", "Label tooltip should be empty");
 
-      MockFilePicker.setFiles([testFile]);
+      MockFilePicker.returnFiles = [testFile];
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
-
-      return new Promise(resolve => {
-        MockFilePicker.afterOpenCallback = resolve;
-        EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
-      });
-    }).then(() => {
+      EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeGetFolder, "File picker mode should be directory");
       is(input.value, testFile.path, "Label value should match file chosen");
       is(input.tooltipText, testFile.path, "Label tooltip should match file chosen");
       is(Preferences.get("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should match file chosen");
 
-      MockFilePicker.setFiles([curProcD]);
+      MockFilePicker.returnFiles = [curProcD];
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnCancel;
-
-      return new Promise(resolve => {
-        MockFilePicker.afterOpenCallback = resolve;
-        EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
-      });
-    }).then(() => {
+      EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeGetFolder, "File picker mode should be directory");
       is(input.value, testFile.path, "Label value should not have changed");
       is(input.tooltipText, testFile.path, "Label tooltip should not have changed");
       is(Preferences.get("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should not have changed");
 
       var unsizedInput = gManagerWindow.document.getAnonymousElementByAttribute(settings[2], "anonid", "input");
       var sizedInput = gManagerWindow.document.getAnonymousElementByAttribute(settings[8], "anonid", "input");
       is(unsizedInput.clientWidth > sizedInput.clientWidth, true, "Input with size attribute should be smaller than input without");
-    }).then(() => {
+    } finally {
       button = gManagerWindow.document.getElementById("detail-prefs-btn");
       is_element_hidden(button, "Preferences button should not be visible");
 
       gCategoryUtilities.openType("extension", run_next_test);
-    });
+    }
   });
 });
 
 // Tests for the setting.xml bindings introduced after Mozilla 7
 add_test(function() {
   observer.checkHidden("inlinesettings1@tests.mozilla.org");
 
   var addon = get_addon_element(gManagerWindow, "inlinesettings3@tests.mozilla.org");
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings_info.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings_info.js
@@ -264,93 +264,74 @@ add_test(function() {
     input.focus();
     EventUtils.synthesizeKey("VK_RIGHT", {}, gManagerWindow);
     EventUtils.synthesizeKey("VK_RIGHT", {}, gManagerWindow);
     EventUtils.synthesizeKey("VK_RETURN", {}, gManagerWindow);
     input.hidePopup();
     is(input.color, "#FF9900", "Color picker should have updated value");
     is(Services.prefs.getCharPref("extensions.inlinesettings1.color"), "#FF9900", "Color pref should have been updated");
 
-    ok(!settings[6].hasAttribute("first-row"), "Not the first row");
-    var button = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "button");
+    try {
+      ok(!settings[6].hasAttribute("first-row"), "Not the first row");
+      var button = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "button");
 
-    // Workaround for bug 1155324 - we need to ensure that the button is scrolled into view.
-    button.scrollIntoView();
-
-    input = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "input");
-    is(input.value, "", "Label value should be empty");
-    is(input.tooltipText, "", "Label tooltip should be empty");
+      // Workaround for bug 1155324 - we need to ensure that the button is scrolled into view.
+      button.scrollIntoView();
 
-    var profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
-    var curProcD = Services.dirsvc.get("CurProcD", Ci.nsIFile);
-
-    MockFilePicker.setFiles([profD]);
-    MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
+      input = gManagerWindow.document.getAnonymousElementByAttribute(settings[6], "anonid", "input");
+      is(input.value, "", "Label value should be empty");
+      is(input.tooltipText, "", "Label tooltip should be empty");
 
-    let promise = new Promise(resolve => {
-      MockFilePicker.afterOpenCallback = resolve;
+      var profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
+      var curProcD = Services.dirsvc.get("CurProcD", Ci.nsIFile);
+
+      MockFilePicker.returnFiles = [profD];
+      MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
       EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
-    });
-
-    promise.then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeOpen, "File picker mode should be open file");
       is(input.value, profD.path, "Label value should match file chosen");
       is(input.tooltipText, profD.path, "Label tooltip should match file chosen");
       is(Services.prefs.getCharPref("extensions.inlinesettings1.file"), profD.path, "File pref should match file chosen");
 
-      MockFilePicker.setFiles([curProcD]);
+      MockFilePicker.returnFiles = [curProcD];
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnCancel;
-
-      return promise = new Promise(resolve => {
-        MockFilePicker.afterOpenCallback = resolve;
-        EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
-      });
-    }).then(() => {
+      EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeOpen, "File picker mode should be open file");
       is(input.value, profD.path, "Label value should not have changed");
       is(input.tooltipText, profD.path, "Label tooltip should not have changed");
       is(Services.prefs.getCharPref("extensions.inlinesettings1.file"), profD.path, "File pref should not have changed");
 
       ok(!settings[7].hasAttribute("first-row"), "Not the first row");
       button = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "button");
       input = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "input");
       is(input.value, "", "Label value should be empty");
       is(input.tooltipText, "", "Label tooltip should be empty");
 
-      MockFilePicker.setFiles([profD]);
+      MockFilePicker.returnFiles = [profD];
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
-
-      return new Promise(resolve => {
-        MockFilePicker.afterOpenCallback = resolve;
-        EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
-      });
-    }).then(() => {
+      EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeGetFolder, "File picker mode should be directory");
       is(input.value, profD.path, "Label value should match file chosen");
       is(input.tooltipText, profD.path, "Label tooltip should match file chosen");
       is(Services.prefs.getCharPref("extensions.inlinesettings1.directory"), profD.path, "Directory pref should match file chosen");
 
-      MockFilePicker.setFiles([curProcD]);
+      MockFilePicker.returnFiles = [curProcD];
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnCancel;
-
-      return new Promise(resolve => {
-        MockFilePicker.afterOpenCallback = resolve;
-        EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
-      });
-    }).then(() => {
+      EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeGetFolder, "File picker mode should be directory");
       is(input.value, profD.path, "Label value should not have changed");
       is(input.tooltipText, profD.path, "Label tooltip should not have changed");
       is(Services.prefs.getCharPref("extensions.inlinesettings1.directory"), profD.path, "Directory pref should not have changed");
-    }).then(() => {
+
+    } finally {
       button = gManagerWindow.document.getElementById("detail-prefs-btn");
       is_element_hidden(button, "Preferences button should not be visible");
 
       gCategoryUtilities.openType("extension", run_next_test);
-    });
+    }
   });
 });
 
 // Tests for the setting.xml bindings introduced after Mozilla 7
 add_test(function() {
   observer.checkHidden("inlinesettings1@tests.mozilla.org");
 
   var addon = get_addon_element(gManagerWindow, "inlinesettings3@tests.mozilla.org");
--- a/toolkit/mozapps/handling/content/dialog.js
+++ b/toolkit/mozapps/handling/content/dialog.js
@@ -161,47 +161,45 @@ var dialog = {
   chooseApplication: function chooseApplication() {
     var bundle = document.getElementById("base-strings");
     var title = bundle.getString("choose.application.title");
 
     var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
     fp.init(window, title, Ci.nsIFilePicker.modeOpen);
     fp.appendFilters(Ci.nsIFilePicker.filterApps);
 
-    fp.open(rv => {
-      if (rv == Ci.nsIFilePicker.returnOK && fp.file) {
-        let uri = Cc["@mozilla.org/network/util;1"].
-                  getService(Ci.nsIIOService).
-                  newFileURI(fp.file);
+    if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file) {
+      let uri = Cc["@mozilla.org/network/util;1"].
+                getService(Ci.nsIIOService).
+                newFileURI(fp.file);
 
-        let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
-                         createInstance(Ci.nsILocalHandlerApp);
-        handlerApp.executable = fp.file;
+      let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
+                       createInstance(Ci.nsILocalHandlerApp);
+      handlerApp.executable = fp.file;
 
-        // if this application is already in the list, select it and don't add it again
-        let parent = document.getElementById("items");
-        for (let i = 0; i < parent.childNodes.length; ++i) {
-          let elm = parent.childNodes[i];
-          if (elm.obj instanceof Ci.nsILocalHandlerApp && elm.obj.equals(handlerApp)) {
-            parent.selectedItem = elm;
-            parent.ensureSelectedElementIsVisible();
-            return;
-          }
+      // if this application is already in the list, select it and don't add it again
+      let parent = document.getElementById("items");
+      for (let i = 0; i < parent.childNodes.length; ++i) {
+        let elm = parent.childNodes[i];
+        if (elm.obj instanceof Ci.nsILocalHandlerApp && elm.obj.equals(handlerApp)) {
+          parent.selectedItem = elm;
+          parent.ensureSelectedElementIsVisible();
+          return;
         }
+      }
 
-        let elm = document.createElement("richlistitem");
-        elm.setAttribute("type", "handler");
-        elm.setAttribute("name", fp.file.leafName);
-        elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32");
-        elm.obj = handlerApp;
+      let elm = document.createElement("richlistitem");
+      elm.setAttribute("type", "handler");
+      elm.setAttribute("name", fp.file.leafName);
+      elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32");
+      elm.obj = handlerApp;
 
-        parent.selectedItem = parent.insertBefore(elm, parent.firstChild);
-        parent.ensureSelectedElementIsVisible();
-      }
-    });
+      parent.selectedItem = parent.insertBefore(elm, parent.firstChild);
+      parent.ensureSelectedElementIsVisible();
+    }
   },
 
  /**
   * Function called when the OK button is pressed.
   */
   onAccept: function onAccept() {
     var checkbox = document.getElementById("remember");
     if (!checkbox.hidden) {
--- a/widget/nsIFilePicker.idl
+++ b/widget/nsIFilePicker.idl
@@ -160,18 +160,16 @@ interface nsIFilePicker : nsISupports
   * Controls whether the chosen file(s) should be added to the system's recent
   * documents list. This attribute will be ignored if the system has no "Recent
   * Docs" concept, or if the application is in private browsing mode (in which
   * case the file will not be added). Defaults to true.
   */
   attribute boolean addToRecentDocs;
 
  /**
-  * This method is **deprecated**. Please use open()
-  *
   * Show File Dialog. The dialog is displayed modally.
   *
   * @return returnOK if the user selects OK, returnCancel if the user selects cancel
   *
   */
   [deprecated] short show();