Commit 42917d14 authored by Makoto Kato's avatar Makoto Kato
Browse files

Bug 1674428 - Part 0. Turn on test_webkitdirectory.html on Android. r=sefeng

To turn on this `test_webkitdirectory.html` on Android, we have to
intercept `nsIPromptCollection` since GeckoView/Android uses custom
implementation.

Differential Revision: https://phabricator.services.mozilla.com/D234922
parent 73bbe153
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@ support-files = [
["test_bug1319088.html"]

["test_webkitdirectory.html"]
skip-if = ["os == 'android'"] # Bug 1674428
support-files = ["script_promptHandler.js"]

["test_worker_basic.html"]
+28 −11
Original line number Diff line number Diff line
@@ -26,6 +26,15 @@ function waitForEvent(element, eventName) {
}

function waitForPromptHandled() {
  if (AppConstants.platform === "android") {
    return new Promise(resolve => {
      let MockPromptCollection = SpecialPowers.MockPromptCollection;
      MockPromptCollection.showConfirmFolderUploadCallback = function() {
        resolve();
        return true;
      };
    });
  }
  return new Promise(resolve => promptHandler.addMessageListener("promptAccepted", resolve));
}

@@ -48,7 +57,7 @@ function populateInputFile(aInputFile) {
  var script = SpecialPowers.loadChromeScript(url);

  var MockFilePicker = SpecialPowers.MockFilePicker;
  MockFilePicker.init(SpecialPowers.wrap(window).browsingContext, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeGetFolder);
  MockFilePicker.init(SpecialPowers.wrap(window).browsingContext);

  async function onOpened(message) {
    MockFilePicker.useDirectory(message.dir);
@@ -135,7 +144,7 @@ async function test_individualSymlink(aInputFile) {

  // -- Have the picker pick it
  var MockFilePicker = SpecialPowers.MockFilePicker;
  MockFilePicker.init(SpecialPowers.wrap(window).browsingContext, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeOpen);
  MockFilePicker.init(SpecialPowers.wrap(window).browsingContext);

  MockFilePicker.displayDirectory = dir;
  let pickerShown = new Promise(resolve => {
@@ -188,7 +197,7 @@ function test_changeDataWhileWorking() {
  var script = SpecialPowers.loadChromeScript(url);

  var MockFilePicker = SpecialPowers.MockFilePicker;
  MockFilePicker.init(SpecialPowers.wrap(window).browsingContext, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeGetFolder);
  MockFilePicker.init(SpecialPowers.wrap(window).browsingContext);
  let promptHandled;

  // Let's start retrieving the root nsIFile object
@@ -205,7 +214,7 @@ function test_changeDataWhileWorking() {
  // input.click() pointing to the root dir
  .then(async function(aDir) {
    MockFilePicker.cleanup();
    MockFilePicker.init(SpecialPowers.wrap(window).browsingContext, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeGetFolder);
    MockFilePicker.init(SpecialPowers.wrap(window).browsingContext);
    MockFilePicker.useDirectory(aDir);
    var input = document.getElementById("inputFileDirectoryChange");

@@ -232,7 +241,7 @@ function test_changeDataWhileWorking() {
  // Now let's click again and wait for onchange.
  .then(async function(aDir) {
      MockFilePicker.cleanup();
      MockFilePicker.init(SpecialPowers.wrap(window).browsingContext, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeGetFolder);
      MockFilePicker.init(SpecialPowers.wrap(window).browsingContext);
      MockFilePicker.useDirectory(aDir);

      let input = document.getElementById("inputFileDirectoryChange");
@@ -252,18 +261,26 @@ function test_changeDataWhileWorking() {
}

async function test_setup() {
  if (AppConstants.platform === "android") {
    let MockPromptCollection = SpecialPowers.MockPromptCollection;
    MockPromptCollection.init(SpecialPowers.wrap(window).browsingContext);
  } else {
    let promptHandlerUrl = SimpleTest.getTestFileURL("script_promptHandler.js")
    promptHandler = SpecialPowers.loadChromeScript(promptHandlerUrl);

    let promptHandlerReady = new Promise(resolve => promptHandler.addMessageListener("initDone", resolve));
    promptHandler.sendAsyncMessage("init");
    await promptHandlerReady;
  }

  SpecialPowers.pushPrefEnv({"set": [["dom.filesystem.pathcheck.disabled", true],
                                     ["dom.webkitBlink.dirPicker.enabled", true]]}, next);
}

async function test_cleanup() {
  if (AppConstants.platform === "android") {
    return;
  }
  let promptHandlerDone = new Promise(resolve => promptHandler.addMessageListener("cleanupDone", resolve));
  promptHandler.sendAsyncMessage("cleanup");
  await promptHandlerDone;
+114 −0
Original line number Diff line number Diff line
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const lazy = {};

ChromeUtils.defineESModuleGetters(lazy, {
  WrapPrivileged: "resource://testing-common/WrapPrivileged.sys.mjs",
});

const Cm = Components.manager;

const CONTRACT_ID = "@mozilla.org/embedcomp/prompt-collection;1";

Cu.crashIfNotInAutomation();

var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
var oldClassID = "";
var newClassID = Services.uuid.generateUUID();
var newFactory = function (window) {
  return {
    createInstance(aIID) {
      return new MockPromptCollectionInstance(window).QueryInterface(aIID);
    },
    QueryInterface: ChromeUtils.generateQI(["nsIFactory"]),
  };
};

export var MockPromptCollection = {
  init(browsingContext) {
    this.window = browsingContext.window;

    this.reset();
    this.factory = newFactory(this.window);
    if (!registrar.isCIDRegistered(newClassID)) {
      oldClassID = registrar.contractIDToCID(CONTRACT_ID);
      registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory);
    }
  },

  reset() {
    this.returnBeforeUnloadCheck = false;
    this.returnConfirmRepost = false;
    this.returnConfirmFolderUpload = false;
    this.showConfirmFolderUploadCallback = null;
  },

  cleanup() {
    var previousFactory = this.factory;
    this.reset();
    this.factory = null;

    registrar.unregisterFactory(newClassID, previousFactory);
    if (oldClassID != "") {
      registrar.registerFactory(oldClassID, "", CONTRACT_ID, null);
    }
  },
};

function MockPromptCollectionInstance(window) {
  this.window = window;
  this.showConfirmFolderUploadCallback = null;
  this.showConfirmFolderUploadCallbackWrapped = null;
  this.directoryName = "";
}

MockPromptCollectionInstance.prototype = {
  QueryInterface: ChromeUtils.generateQI(["nsIPromptCollection"]),

  asyncBeforeUnloadCheck() {
    return Promise.resolve(MockPromptCollection.returnBeforeUnloadCheck);
  },

  confirmRepost() {
    return MockPromptCollection.returnConfirmRepost;
  },

  confirmFolderUpload(aBrowsingContext, aDirectoryName) {
    this.directoryName = aDirectoryName;

    if (
      typeof MockPromptCollection.showConfirmFolderUploadCallback == "function"
    ) {
      if (
        MockPromptCollection.showConfirmFolderUploadCallback !=
        this.showConfirmFolderUploadCallback
      ) {
        this.showConfirmFolderUploadCallback =
          MockPromptCollection.showConfirmFolderUploadCallback;
        if (Cu.isXrayWrapper(this.window)) {
          this.showConfirmFolderUploadCallbackWrapped =
            lazy.WrapPrivileged.wrapCallback(
              MockPromptCollection.showConfirmFolderUploadCallback,
              this.window
            );
        } else {
          this.showConfirmFolderUploadCallbackWrapped =
            this.showConfirmFolderUploadCallback;
        }
      }

      try {
        let returnValue = this.showConfirmFolderUploadCallbackWrapped(this);
        if (typeof returnValue == "boolean") {
          return returnValue;
        }
      } catch (e) {
        return false;
      }
    }

    return MockPromptCollection.returnConfirmFolderUpload;
  },
};
+6 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
  MockFilePicker: "resource://testing-common/MockFilePicker.sys.mjs",
  MockPermissionPrompt:
    "resource://testing-common/MockPermissionPrompt.sys.mjs",
  MockPromptCollection:
    "resource://testing-common/MockPromptCollection.sys.mjs",
  MockSound: "resource://testing-common/MockSound.sys.mjs",
  NetUtil: "resource://gre/modules/NetUtil.sys.mjs",
  PerTestCoverageUtils:
@@ -442,6 +444,10 @@ export class SpecialPowersChild extends JSWindowActorChild {
    return lazy.MockColorPicker;
  }

  get MockPromptCollection() {
    return lazy.MockPromptCollection;
  }

  get MockPermissionPrompt() {
    return lazy.MockPermissionPrompt;
  }
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ modules = [
    "content/MockColorPicker.sys.mjs",
    "content/MockFilePicker.sys.mjs",
    "content/MockPermissionPrompt.sys.mjs",
    "content/MockPromptCollection.sys.mjs",
    "content/MockSound.sys.mjs",
    "content/SpecialPowersChild.sys.mjs",
    "content/SpecialPowersEventUtils.sys.mjs",