file_bug549682.xhtml (7245B)
1 <?xml version="1.0"?> 2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?> 3 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" 4 type="text/css"?> 5 <!-- 6 https://bugzilla.mozilla.org/show_bug.cgi?id=549682 7 --> 8 <window title="Mozilla Bug 549682" 9 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 10 onload="run()"> 11 <label value="Mozilla Bug 549682"/> 12 <!-- test code goes here --> 13 <script type="application/javascript"><![CDATA[ 14 /* global messageManager, sendAsyncMessage */ 15 var didRunAsync = false; 16 var didRunLocal = false; 17 18 var global = Cc["@mozilla.org/globalmessagemanager;1"].getService(); 19 var ppm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(); 20 var cpm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(); 21 22 function ok(cond, msg) { 23 window.arguments[0].ok(cond, msg); 24 } 25 26 function is(actual, expected, msg) { 27 window.arguments[0].is(actual, expected, msg); 28 } 29 30 var asyncPPML = false; 31 function ppmASL() { 32 asyncPPML = true; 33 } 34 var syncPPML = false; 35 function ppmSL() { 36 syncPPML = true; 37 } 38 ppm.addMessageListener("processmessageAsync", ppmASL); 39 ppm.addMessageListener("processmessageSync", ppmSL); 40 41 cpm.sendAsyncMessage("processmessageAsync", ""); 42 cpm.sendSyncMessage("processmessageSync", ""); 43 44 var asyncCPML = false; 45 function cpmASL() { 46 asyncCPML = true; 47 } 48 cpm.addMessageListener("childprocessmessage", cpmASL); 49 ppm.broadcastAsyncMessage("childprocessmessage", ""); 50 51 function checkPMMMessages() { 52 ok(asyncPPML, "should have handled async message"); 53 ok(syncPPML, "should have handled sync message"); 54 ok(asyncCPML, "should have handled async message"); 55 ppm.removeMessageListener("processmessageAsync", ppmASL); 56 ppm.removeMessageListener("processmessageSync", ppmSL); 57 cpm.removeMessageListener("childprocessmessage", cpmASL); 58 } 59 60 var globalListenerCallCount = 0; 61 function globalListener(m) { 62 ++globalListenerCallCount; 63 if (m.name == "sync") { 64 global.removeMessageListener("async", globalListener); 65 global.removeMessageListener("sync", globalListener); 66 global.removeMessageListener("global-sync", globalListener); 67 // Note, the result depends on what other windows are open. 68 ok(globalListenerCallCount >= 4, 69 "Global listener should have been called at least 4 times!"); 70 ok(didRunLocal, "Local message received."); 71 } 72 } 73 74 function asyncL(m) { 75 didRunAsync = true; 76 is(m.name, "async", "Wrong message!"); 77 is(m.json.data, 1234, "Wrong data!"); 78 } 79 80 function syncL(m) { 81 is(m.name, "sync", "Wrong message!"); 82 is(m.json.data, 1234, "Wrong data!"); 83 ok(didRunAsync, "Should have run async!"); 84 } 85 86 function localL(m) { 87 is(m.name, "lasync", "Wrong message!"); 88 is(m.json.data, 2345, "Wrong data!"); 89 didRunLocal = true; 90 } 91 92 var weakMessageReceived = false; 93 var weakListener = { 94 QueryInterface: ChromeUtils.generateQI(["nsISupportsWeakReference"]), 95 96 receiveMessage() { 97 if (weakMessageReceived) { 98 ok(false, 'Weak listener fired twice.'); 99 return; 100 } 101 102 ok(true, 'Weak listener fired once.'); 103 weakMessageReceived = true; 104 document.getElementById('ifr').messageManager 105 .removeWeakMessageListener('weak', weakListener); 106 } 107 }; 108 109 var weakListener2 = { 110 QueryInterface: ChromeUtils.generateQI(["nsISupportsWeakReference"]), 111 112 receiveMessage() { 113 ok(false, 'Should not have received a message.'); 114 } 115 }; 116 117 function weakDoneListener() { 118 ok(weakMessageReceived, 'Got "weak" message.'); 119 finish(); 120 } 121 122 function finish() { 123 window.arguments[0].setTimeout(function() { this.done(); }, 0); 124 var i = document.getElementById("ifr"); 125 i.remove(); // This is a crash test! 126 window.close(); 127 } 128 129 function loadScript() { 130 // Async should be processed first! 131 messageManager.loadFrameScript("data:,\ 132 sendAsyncMessage('async', { data: 1234 });\ 133 sendSyncMessage('sync', { data: 1234 });\ 134 sendAsyncMessage('weak', {});\ 135 sendAsyncMessage('weak', {});\ 136 sendAsyncMessage('weakdone', {});", false); 137 } 138 139 function run() { 140 var localmm = document.getElementById('ifr').messageManager; 141 142 var docShell = document.getElementById('ifr').contentWindow.docShell; 143 ok(docShell, "Should have docshell"); 144 var cfmm = docShell.messageManager; 145 ok(cfmm, "Should have content messageManager"); 146 147 var didGetSyncMessage = false; 148 function syncContinueTestFn() { 149 didGetSyncMessage = true; 150 } 151 localmm.addMessageListener("syncContinueTest", syncContinueTestFn); 152 cfmm.sendSyncMessage("syncContinueTest", {}); 153 localmm.removeMessageListener("syncContinueTest", syncContinueTestFn); 154 ok(didGetSyncMessage, "Should have got sync message!"); 155 156 localmm.addMessageListener("lasync", localL); 157 localmm.loadFrameScript("data:,sendAsyncMessage('lasync', { data: 2345 })", false); 158 159 messageManager.addMessageListener("async", asyncL); 160 messageManager.addMessageListener("sync", syncL); 161 global.addMessageListener("async", globalListener); 162 global.addMessageListener("sync", globalListener); 163 global.addMessageListener("global-sync", globalListener); 164 global.loadFrameScript("data:,sendSyncMessage('global-sync', { data: 1234 });", true); 165 var toBeRemovedScript = "data:,sendAsyncMessage('toberemoved', { data: 2345 })"; 166 var c = 0; 167 messageManager.addMessageListener("toberemoved", function() { 168 ++c; 169 is(c, 1, "Should be called only once!"); 170 }); 171 // This loads the script in the existing <browser> 172 messageManager.loadFrameScript(toBeRemovedScript, true); 173 // But it won't be loaded in the dynamically created <browser> 174 messageManager.removeDelayedFrameScript(toBeRemovedScript); 175 176 var oldValue = globalListenerCallCount; 177 var b = document.createXULElement("browser"); 178 b.setAttribute("type", "content"); 179 document.documentElement.appendChild(b); 180 is(globalListenerCallCount, oldValue + 1, 181 "Wrong message count"); 182 183 localmm.addWeakMessageListener('weak', weakListener); 184 localmm.addMessageListener('weakdone', weakDoneListener); 185 186 // Add weakListener2 as a weak message listener, then force weakListener2 187 // to be gc'ed. weakListener2 shouldn't be run. 188 var weakRef = Cu.getWeakReference(weakListener2); 189 localmm.addWeakMessageListener('weak', weakListener2); 190 weakListener2 = null; 191 192 // Force a gc/cc in a loop until weakRef's referent has gone away. 193 function waitForWeakRefToDie() { 194 if (weakRef.get()) { 195 var mgr = Cc["@mozilla.org/memory-reporter-manager;1"] 196 .getService(Ci.nsIMemoryReporterManager); 197 mgr.minimizeMemoryUsage(waitForWeakRefToDie); 198 199 // Print a message so that if the test hangs in a minimizeMemoryUsage 200 // loop, we'll be able to see it in the log. 201 ok(true, "waitForWeakRefToDie spinning..."); 202 return; 203 } 204 205 setTimeout(checkPMMMessages, 0); 206 setTimeout(loadScript, 0); 207 } 208 209 waitForWeakRefToDie(); 210 } 211 212 ]]></script> 213 <browser type="content" src="about:blank" id="ifr"/> 214 </window>