2 * Test to ensure that image loading/decoding notifications are always
3 * delivered async, and in the order we expect.
5 * Must be included from a file that has a uri of the image to test defined in
8 /* import-globals-from image_load_helpers.js */
10 const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
11 const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
12 const ReferrerInfo = Components.Constructor(
13 "@mozilla.org/referrer-info;1",
18 var server = new HttpServer();
19 server.registerDirectory("/", do_get_file(""));
20 server.registerContentType("sjs", "sjs");
23 load("image_load_helpers.js");
28 // Return a closure that holds on to the listener from the original
29 // imgIRequest, and compares its results to the cloned one.
30 function getCloneStopCallback(original_listener) {
31 return function cloneStop(listener) {
32 Assert.equal(original_listener.state, listener.state);
34 // Sanity check to make sure we didn't accidentally use the same listener
36 Assert.notEqual(original_listener, listener);
41 // Make sure that cloned requests get all the same callbacks as the original,
42 // but they aren't synchronous right now.
43 function checkClone(other_listener, aRequest) {
46 // For as long as clone notification is synchronous, we can't test the clone state reliably.
47 var listener = new ImageListener(
51 } /* getCloneStopCallback(other_listener)*/
53 listener.synchronous = false;
54 var outer = Cc["@mozilla.org/image/tools;1"]
55 .getService(Ci.imgITools)
56 .createScriptedObserver(listener);
57 var clone = aRequest.clone(outer);
58 requests.push({ request: clone, locked: false });
61 // Ensure that all the callbacks were called on aRequest.
62 function checkSizeAndLoad(listener, aRequest) {
63 Assert.notEqual(listener.state & SIZE_AVAILABLE, 0);
64 Assert.notEqual(listener.state & LOAD_COMPLETE, 0);
69 function secondLoadDone(oldlistener, aRequest) {
73 var staticrequest = aRequest.getStaticRequest();
75 // For as long as clone notification is synchronous, we can't test the
76 // clone state reliably.
77 var listener = new ImageListener(null, checkSizeAndLoad);
78 listener.synchronous = false;
79 var outer = Cc["@mozilla.org/image/tools;1"]
80 .getService(Ci.imgITools)
81 .createScriptedObserver(listener);
82 var staticrequestclone = staticrequest.clone(outer);
83 requests.push({ request: staticrequestclone, locked: false });
85 // We can't create a static request. Most likely the request we started
86 // with didn't load successfully.
90 run_loadImageWithChannel_tests();
95 // Load the request a second time. This should come from the image cache, and
96 // therefore would be at most risk of being served synchronously.
97 function checkSecondLoad() {
100 var listener = new ImageListener(checkClone, secondLoadDone);
101 var outer = Cc["@mozilla.org/image/tools;1"]
102 .getService(Ci.imgITools)
103 .createScriptedObserver(listener);
104 var referrerInfo = new ReferrerInfo(
105 Ci.nsIReferrerInfo.NO_REFERRER_WHEN_DOWNGRADE,
110 request: gCurrentLoader.loadImageXPCOM(
123 listener.synchronous = false;
126 function firstLoadDone(oldlistener, aRequest) {
127 checkSecondLoad(uri);
132 // Return a closure that allows us to check the stream listener's status when the
133 // image finishes loading.
134 function getChannelLoadImageStopCallback(streamlistener, next) {
135 return function channelLoadStop(imglistener, aRequest) {
142 // Load the request a second time. This should come from the image cache, and
143 // therefore would be at most risk of being served synchronously.
144 function checkSecondChannelLoad() {
146 var channel = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true });
147 var channellistener = new ChannelListener();
148 channel.asyncOpen(channellistener);
150 var listener = new ImageListener(
152 getChannelLoadImageStopCallback(channellistener, all_done_callback)
154 var outer = Cc["@mozilla.org/image/tools;1"]
155 .getService(Ci.imgITools)
156 .createScriptedObserver(listener);
157 var outlistener = {};
159 request: gCurrentLoader.loadImageWithChannelXPCOM(
167 channellistener.outputListener = outlistener.value;
169 listener.synchronous = false;
172 function run_loadImageWithChannel_tests() {
173 // To ensure we're testing what we expect to, create a new loader and cache.
174 gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
179 var channel = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true });
180 var channellistener = new ChannelListener();
181 channel.asyncOpen(channellistener);
183 var listener = new ImageListener(
185 getChannelLoadImageStopCallback(channellistener, checkSecondChannelLoad)
187 var outer = Cc["@mozilla.org/image/tools;1"]
188 .getService(Ci.imgITools)
189 .createScriptedObserver(listener);
190 var outlistener = {};
192 request: gCurrentLoader.loadImageWithChannelXPCOM(
200 channellistener.outputListener = outlistener.value;
202 listener.synchronous = false;
205 function all_done_callback() {
206 server.stop(function() {
211 function startImageCallback(otherCb) {
212 return function(listener, request) {
213 // Make sure we can load the same image immediately out of the cache.
215 var listener2 = new ImageListener(null, function(foo, bar) {
218 var outer = Cc["@mozilla.org/image/tools;1"]
219 .getService(Ci.imgITools)
220 .createScriptedObserver(listener2);
221 var referrerInfo = new ReferrerInfo(
222 Ci.nsIReferrerInfo.NO_REFERRER_WHEN_DOWNGRADE,
227 request: gCurrentLoader.loadImageXPCOM(
240 listener2.synchronous = false;
242 // Now that we've started another load, chain to the callback.
243 otherCb(listener, request);
250 for (let { request, locked } of requests) {
253 request.unlockImage();
256 request.cancelAndForgetObserver(0);
260 function run_test() {
261 registerCleanupFunction(cleanup);
263 gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
268 var listener = new ImageListener(
269 startImageCallback(checkClone),
272 var outer = Cc["@mozilla.org/image/tools;1"]
273 .getService(Ci.imgITools)
274 .createScriptedObserver(listener);
275 var referrerInfo = new ReferrerInfo(
276 Ci.nsIReferrerInfo.NO_REFERRER_WHEN_DOWNGRADE,
280 var req = gCurrentLoader.loadImageXPCOM(
292 // Ensure that we don't cause any mayhem when we lock an image.
295 requests.push({ request: req, locked: true });
297 listener.synchronous = false;