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 392283 63c4e77cfe90e90d35d85e1a4821015823c4ecee
parent 392282 d50d68150aba3350501d2cc4df8233fa021a08e5
child 392284 b23d6277acca34a4b1be9a4c24efd3b999e47ec3
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1334975, 1335539
milestone54.0a1
backs out429ff39f3d28b195fb5ee1467cd8126bab3d89b8
eea959a93ce48bc477b32e752d89a5c685f1eef0
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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();