tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_shutdown_remote_own_reference.js (5863B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 add_task(async function () {
      8  await BrowserTestUtils.withNewTab(
      9    {
     10      gBrowser,
     11      url: `data:text/html,
     12      <html>
     13        <head>
     14          <meta charset="utf-8"/>
     15          <title>Accessibility Test</title>
     16        </head>
     17        <body></body>
     18      </html>`,
     19    },
     20    async function (browser) {
     21      info(
     22        "Creating a service in parent and waiting for service to be created " +
     23          "in content"
     24      );
     25      await loadContentScripts(browser, {
     26        script: "Common.sys.mjs",
     27        symbol: "CommonUtils",
     28      });
     29      // Create a11y service in the main process. This will trigger creating of
     30      // the a11y service in parent as well.
     31      const [parentA11yInitObserver, parentA11yInit] = initAccService();
     32      const [contentA11yInitObserver, contentA11yInit] =
     33        initAccService(browser);
     34      let [contentConsumersChangedObserver, contentConsumersChanged] =
     35        accConsumersChanged(browser);
     36 
     37      await Promise.all([
     38        parentA11yInitObserver,
     39        contentA11yInitObserver,
     40        contentConsumersChangedObserver,
     41      ]);
     42 
     43      let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     44        Ci.nsIAccessibilityService
     45      );
     46      ok(accService, "Service initialized in parent");
     47      await Promise.all([parentA11yInit, contentA11yInit]);
     48      await contentConsumersChanged.then(data =>
     49        Assert.deepEqual(
     50          data,
     51          {
     52            XPCOM: false,
     53            MainProcess: true,
     54            PlatformAPI: false,
     55          },
     56          "Accessibility service consumers in content are correct."
     57        )
     58      );
     59 
     60      info(
     61        "Adding additional reference to accessibility service in content " +
     62          "process"
     63      );
     64      [contentConsumersChangedObserver, contentConsumersChanged] =
     65        accConsumersChanged(browser);
     66      await contentConsumersChangedObserver;
     67      // Add a new reference to the a11y service inside the content process.
     68      await SpecialPowers.spawn(browser, [], () => {
     69        content.CommonUtils.accService;
     70      });
     71      await contentConsumersChanged.then(data =>
     72        Assert.deepEqual(
     73          data,
     74          {
     75            XPCOM: true,
     76            MainProcess: true,
     77            PlatformAPI: false,
     78          },
     79          "Accessibility service consumers in content are correct."
     80        )
     81      );
     82 
     83      const contentConsumers = await SpecialPowers.spawn(browser, [], () =>
     84        content.CommonUtils.accService.getConsumers()
     85      );
     86      Assert.deepEqual(
     87        JSON.parse(contentConsumers),
     88        {
     89          XPCOM: true,
     90          MainProcess: true,
     91          PlatformAPI: false,
     92        },
     93        "Accessibility service consumers in parent are correct."
     94      );
     95 
     96      info(
     97        "Shutting down a service in parent and making sure the one in " +
     98          "content stays alive"
     99      );
    100      let contentCanShutdown = false;
    101      const [parentA11yShutdownObserver, parentA11yShutdown] =
    102        shutdownAccService();
    103      [contentConsumersChangedObserver, contentConsumersChanged] =
    104        accConsumersChanged(browser);
    105      // This promise will resolve only if contentCanShutdown flag is set to true.
    106      // If 'a11y-init-or-shutdown' event with '0' flag (in content) comes before
    107      // it can be shut down, the promise will reject.
    108      const [contentA11yShutdownObserver, contentA11yShutdownPromise] =
    109        shutdownAccService(browser);
    110      const contentA11yShutdown = new Promise((resolve, reject) =>
    111        contentA11yShutdownPromise.then(() =>
    112          contentCanShutdown
    113            ? resolve()
    114            : reject("Accessible service was shut down incorrectly")
    115        )
    116      );
    117 
    118      await Promise.all([
    119        parentA11yShutdownObserver,
    120        contentA11yShutdownObserver,
    121        contentConsumersChangedObserver,
    122      ]);
    123      // Remove a11y service reference in the main process and force garbage
    124      // collection. This should not trigger shutdown in content since a11y
    125      // service is used by XPCOM.
    126      accService = null;
    127      ok(!accService, "Service is removed in parent");
    128      // Force garbage collection that should not trigger shutdown because there
    129      // is a reference in a content process.
    130      forceGC();
    131      await SpecialPowers.spawn(browser, [], () => {
    132        SpecialPowers.Cu.forceGC();
    133      });
    134      await parentA11yShutdown;
    135      await contentConsumersChanged.then(data =>
    136        Assert.deepEqual(
    137          data,
    138          {
    139            XPCOM: true,
    140            MainProcess: false,
    141            PlatformAPI: false,
    142          },
    143          "Accessibility service consumers in content are correct."
    144        )
    145      );
    146 
    147      // Have some breathing room between a11y service shutdowns.
    148      await TestUtils.waitForTick();
    149 
    150      info("Removing a service in content");
    151      // Now allow a11y service to shutdown in content.
    152      contentCanShutdown = true;
    153      [contentConsumersChangedObserver, contentConsumersChanged] =
    154        accConsumersChanged(browser);
    155      await contentConsumersChangedObserver;
    156      // Remove last reference to a11y service in content and force garbage
    157      // collection that should trigger shutdown.
    158      await SpecialPowers.spawn(browser, [], () => {
    159        content.CommonUtils.clearAccService();
    160      });
    161      await contentA11yShutdown;
    162      await contentConsumersChanged.then(data =>
    163        Assert.deepEqual(
    164          data,
    165          {
    166            XPCOM: false,
    167            MainProcess: false,
    168            PlatformAPI: false,
    169          },
    170          "Accessibility service consumers in content are correct."
    171        )
    172      );
    173    }
    174  );
    175 });