browser_shutdown_parent_own_reference.js (3502B)
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 35 await Promise.all([parentA11yInitObserver, contentA11yInitObserver]); 36 37 let accService = Cc["@mozilla.org/accessibilityService;1"].getService( 38 Ci.nsIAccessibilityService 39 ); 40 ok(accService, "Service initialized in parent"); 41 await Promise.all([parentA11yInit, contentA11yInit]); 42 43 info( 44 "Adding additional reference to accessibility service in content " + 45 "process" 46 ); 47 // Add a new reference to the a11y service inside the content process. 48 await SpecialPowers.spawn(browser, [], () => { 49 content.CommonUtils.accService; 50 }); 51 52 info( 53 "Trying to shut down a service in content and making sure it stays " + 54 "alive as it was started by parent" 55 ); 56 let contentCanShutdown = false; 57 // This promise will resolve only if contentCanShutdown flag is set to true. 58 // If 'a11y-init-or-shutdown' event with '0' flag (in content) comes before 59 // it can be shut down, the promise will reject. 60 const [contentA11yShutdownObserver, contentA11yShutdownPromise] = 61 shutdownAccService(browser); 62 await contentA11yShutdownObserver; 63 const contentA11yShutdown = new Promise((resolve, reject) => 64 contentA11yShutdownPromise.then(() => 65 contentCanShutdown 66 ? resolve() 67 : reject("Accessible service was shut down incorrectly") 68 ) 69 ); 70 // Remove a11y service reference in content and force garbage collection. 71 // This should not trigger shutdown since a11y was originally initialized by 72 // the main process. 73 await SpecialPowers.spawn(browser, [], () => { 74 content.CommonUtils.clearAccService(); 75 }); 76 77 // Have some breathing room between a11y service shutdowns. 78 await TestUtils.waitForTick(); 79 80 info("Removing a service in parent"); 81 // Now allow a11y service to shutdown in content. 82 contentCanShutdown = true; 83 // Remove the a11y service reference in the main process. 84 const [parentA11yShutdownObserver, parentA11yShutdown] = 85 shutdownAccService(); 86 await parentA11yShutdownObserver; 87 88 accService = null; 89 ok(!accService, "Service is removed in parent"); 90 // Force garbage collection that should trigger shutdown in both parent and 91 // content. 92 forceGC(); 93 await Promise.all([parentA11yShutdown, contentA11yShutdown]); 94 } 95 ); 96 });