|
1 <!DOCTYPE html> |
|
2 <html> |
|
3 <head> |
|
4 <meta charset="utf-8"> |
|
5 <title>Test that processes that are shutdown send a 'process-shutdown' |
|
6 message to their process message manager.</title> |
|
7 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
9 </head> |
|
10 <body onload="runTests();"> |
|
11 <p id="display"> |
|
12 </p> |
|
13 <div id="content" style="display: none"> |
|
14 |
|
15 </div> |
|
16 <pre id="test"> |
|
17 <script class="testbody" type="application/javascript;version=1.8"> |
|
18 |
|
19 const APP_URL = "http://example.org"; |
|
20 const APP_MANIFEST = "http://example.org/manifest.webapp"; |
|
21 const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown"; |
|
22 |
|
23 let ppmm = SpecialPowers.Cc["@mozilla.org/parentprocessmessagemanager;1"] |
|
24 .getService(SpecialPowers.Ci.nsIMessageBroadcaster); |
|
25 let obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"] |
|
26 .getService(SpecialPowers.Ci.nsIObserverService); |
|
27 |
|
28 /** |
|
29 * Load the example.org site in an <iframe mozbrowser> |
|
30 * |
|
31 * @param isApp |
|
32 * If true, the example.org site will be loaded as an app. |
|
33 */ |
|
34 function loadBrowser(isApp, callback) { |
|
35 let iframe = document.createElement("iframe"); |
|
36 if (isApp) { |
|
37 iframe.setAttribute("mozapp", APP_MANIFEST); |
|
38 } |
|
39 SpecialPowers.wrap(iframe).mozbrowser = true; |
|
40 iframe.src = APP_URL; |
|
41 document.getElementById("content").appendChild(iframe); |
|
42 |
|
43 iframe.addEventListener("mozbrowserloadend", function onloadend() { |
|
44 iframe.removeEventListener("mozbrowserloadend", onloadend); |
|
45 callback(iframe); |
|
46 }); |
|
47 } |
|
48 |
|
49 /** |
|
50 * Prepare the child process for an intentional crash. This is to keep |
|
51 * the leak automation tools happy. |
|
52 * |
|
53 * This also allows us to acquire the process message manaager that |
|
54 * corresponds to the process by sending a message to a frame script |
|
55 * in the content process and having it reply to us via the child |
|
56 * process message manager. |
|
57 */ |
|
58 function prepareProcess(frameMM, callback) { |
|
59 let frameScript = 'data:,\ |
|
60 privateNoteIntentionalCrash();\ |
|
61 var cpmm = Components.classes["@mozilla.org/childprocessmessagemanager;1"]\ |
|
62 .getService(Components.interfaces.nsISyncMessageSender);\ |
|
63 addMessageListener("TestChild:Ohai", function receiveMessage(msg) {\ |
|
64 cpmm.sendAsyncMessage("TestChild:Ohai");\ |
|
65 });'; |
|
66 frameMM.loadFrameScript(frameScript, false); |
|
67 frameMM.sendAsyncMessage("TestChild:Ohai"); |
|
68 ppmm.addMessageListener("TestChild:Ohai", function receiveMessage(msg) { |
|
69 ppmm.removeMessageListener("TestChild:Ohai", receiveMessage); |
|
70 msg = SpecialPowers.wrap(msg); |
|
71 callback(msg.target); |
|
72 }); |
|
73 } |
|
74 |
|
75 /** |
|
76 * Expects an OOP frame's process to shut down and report four |
|
77 * events/messages: an error event on the browser element, and a |
|
78 * 'child-process-shutdown' message on both the frame and process |
|
79 * message managers. |
|
80 */ |
|
81 function expectFrameProcessShutdown(iframe, frameMM, processMM, callback) { |
|
82 let msgCount = 0; |
|
83 function countMessage() { |
|
84 msgCount += 1; |
|
85 if (msgCount == 4) { |
|
86 ok(true, "Observed all four expected events."); |
|
87 callback(); |
|
88 } |
|
89 }; |
|
90 |
|
91 iframe.addEventListener("mozbrowsererror", function onerror(event) { |
|
92 iframe.removeEventListener("mozbrowsererror", onerror); |
|
93 is(event.detail.type, "fatal", "Observed expected event."); |
|
94 countMessage(); |
|
95 }); |
|
96 |
|
97 processMM.addMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, function receiveMessage() { |
|
98 processMM.removeMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, receiveMessage); |
|
99 ok(true, "Received 'child-process-shutdown' message from process message manager."); |
|
100 countMessage(); |
|
101 }); |
|
102 |
|
103 frameMM.addMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, function receiveMessage() { |
|
104 frameMM.removeMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, receiveMessage); |
|
105 ok(true, "Received 'child-process-shutdown' message from frame message manager."); |
|
106 countMessage(); |
|
107 }); |
|
108 |
|
109 obs.addObserver(function observe(subject, type, data) { |
|
110 if (subject == SpecialPowers.unwrap(processMM)) { |
|
111 obs.removeObserver(observe, "message-manager-disconnect"); |
|
112 ok(true, "Received 'message-manager-disconnect' notification with " + |
|
113 "frame message manager"); |
|
114 countMessage(); |
|
115 } |
|
116 }, "message-manager-disconnect", false); |
|
117 } |
|
118 |
|
119 function setUp() { |
|
120 SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true); |
|
121 SpecialPowers.setBoolPref("dom.ipc.browser_frames.oop_by_default", true); |
|
122 SpecialPowers.addPermission("browser", true, window.document); |
|
123 SpecialPowers.addPermission("embed-apps", true, window.document); |
|
124 |
|
125 // TODO: remove in bug 820712 |
|
126 SpecialPowers.setBoolPref("network.disable.ipc.security", true); |
|
127 |
|
128 runNextTest(); |
|
129 } |
|
130 |
|
131 function makeKillTest(isApp) function testKill() { |
|
132 loadBrowser(isApp, function (iframe) { |
|
133 // We want to make sure we get notified on both the frame and |
|
134 // process message managers. |
|
135 let frameMM = SpecialPowers.getBrowserFrameMessageManager(iframe); |
|
136 prepareProcess(frameMM, function (processMM) { |
|
137 // Let's kill the content process by asking for a permission |
|
138 // that it doesn't have. |
|
139 ok(!processMM.assertPermission("frobnaz"), |
|
140 "Content child should not have this permission"); |
|
141 expectFrameProcessShutdown(iframe, frameMM, processMM, function () { |
|
142 iframe.parentNode.removeChild(iframe); |
|
143 runNextTest(); |
|
144 }); |
|
145 }); |
|
146 }); |
|
147 } |
|
148 |
|
149 function tearDown() { |
|
150 SpecialPowers.clearUserPref("dom.mozBrowserFramesEnabled"); |
|
151 SpecialPowers.clearUserPref("dom.ipc.browser_frames.oop_by_default"); |
|
152 |
|
153 // TODO: remove in bug 820712 |
|
154 SpecialPowers.clearUserPref("network.disable.ipc.security"); |
|
155 |
|
156 SimpleTest.finish(); |
|
157 } |
|
158 |
|
159 let _tests = [ |
|
160 setUp, |
|
161 makeKillTest(false), |
|
162 makeKillTest(true), |
|
163 tearDown |
|
164 ] |
|
165 function runNextTest() { |
|
166 SimpleTest.executeSoon(_tests.shift()); |
|
167 } |
|
168 |
|
169 function runTests() { |
|
170 SimpleTest.waitForExplicitFinish(); |
|
171 runNextTest(); |
|
172 } |
|
173 |
|
174 </script> |
|
175 </pre> |
|
176 </body> |
|
177 </html> |