1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/base/content/test/plugins/browser_pluginplaypreview.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,315 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +var rootDir = getRootDirectory(gTestPath); 1.9 +const gTestRoot = rootDir; 1.10 + 1.11 +var gTestBrowser = null; 1.12 +var gNextTest = null; 1.13 +var gNextTestSkip = 0; 1.14 +var gPlayPreviewPluginActualEvents = 0; 1.15 +var gPlayPreviewPluginExpectedEvents = 1; 1.16 + 1.17 +var gPlayPreviewRegistration = null; 1.18 + 1.19 +function registerPlayPreview(mimeType, targetUrl) { 1.20 + 1.21 + function StreamConverterFactory() {} 1.22 + StreamConverterFactory.prototype = { 1.23 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]), 1.24 + _targetConstructor: null, 1.25 + 1.26 + register: function register(targetConstructor) { 1.27 + this._targetConstructor = targetConstructor; 1.28 + var proto = targetConstructor.prototype; 1.29 + var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); 1.30 + registrar.registerFactory(proto.classID, proto.classDescription, 1.31 + proto.contractID, this); 1.32 + }, 1.33 + 1.34 + unregister: function unregister() { 1.35 + var proto = this._targetConstructor.prototype; 1.36 + var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); 1.37 + registrar.unregisterFactory(proto.classID, this); 1.38 + this._targetConstructor = null; 1.39 + }, 1.40 + 1.41 + // nsIFactory 1.42 + createInstance: function createInstance(aOuter, iid) { 1.43 + if (aOuter !== null) 1.44 + throw Cr.NS_ERROR_NO_AGGREGATION; 1.45 + return (new (this._targetConstructor)).QueryInterface(iid); 1.46 + }, 1.47 + 1.48 + // nsIFactory 1.49 + lockFactory: function lockFactory(lock) { 1.50 + // No longer used as of gecko 1.7. 1.51 + throw Cr.NS_ERROR_NOT_IMPLEMENTED; 1.52 + } 1.53 + }; 1.54 + 1.55 + function OverlayStreamConverter() {} 1.56 + OverlayStreamConverter.prototype = { 1.57 + QueryInterface: XPCOMUtils.generateQI([ 1.58 + Ci.nsISupports, 1.59 + Ci.nsIStreamConverter, 1.60 + Ci.nsIStreamListener, 1.61 + Ci.nsIRequestObserver 1.62 + ]), 1.63 + 1.64 + classID: Components.ID('{4c6030f7-e20a-264f-0f9b-ada3a9e97384}'), 1.65 + classDescription: 'overlay-test-data Component', 1.66 + contractID: '@mozilla.org/streamconv;1?from=application/x-moz-playpreview&to=*/*', 1.67 + 1.68 + // nsIStreamConverter::convert 1.69 + convert: function(aFromStream, aFromType, aToType, aCtxt) { 1.70 + throw Cr.NS_ERROR_NOT_IMPLEMENTED; 1.71 + }, 1.72 + 1.73 + // nsIStreamConverter::asyncConvertData 1.74 + asyncConvertData: function(aFromType, aToType, aListener, aCtxt) { 1.75 + var isValidRequest = false; 1.76 + try { 1.77 + var request = aCtxt; 1.78 + request.QueryInterface(Ci.nsIChannel); 1.79 + var spec = request.URI.spec; 1.80 + var expectedSpec = 'data:application/x-moz-playpreview;,' + mimeType; 1.81 + isValidRequest = (spec == expectedSpec); 1.82 + } catch (e) { } 1.83 + if (!isValidRequest) 1.84 + throw Cr.NS_ERROR_NOT_IMPLEMENTED; 1.85 + 1.86 + // Store the listener passed to us 1.87 + this.listener = aListener; 1.88 + }, 1.89 + 1.90 + // nsIStreamListener::onDataAvailable 1.91 + onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) { 1.92 + // Do nothing since all the data loading is handled by the viewer. 1.93 + ok(false, "onDataAvailable should not be called"); 1.94 + }, 1.95 + 1.96 + // nsIRequestObserver::onStartRequest 1.97 + onStartRequest: function(aRequest, aContext) { 1.98 + 1.99 + // Setup the request so we can use it below. 1.100 + aRequest.QueryInterface(Ci.nsIChannel); 1.101 + // Cancel the request so the viewer can handle it. 1.102 + aRequest.cancel(Cr.NS_BINDING_ABORTED); 1.103 + 1.104 + // Create a new channel that is viewer loaded as a resource. 1.105 + var ioService = Services.io; 1.106 + var channel = ioService.newChannel(targetUrl, null, null); 1.107 + channel.asyncOpen(this.listener, aContext); 1.108 + }, 1.109 + 1.110 + // nsIRequestObserver::onStopRequest 1.111 + onStopRequest: function(aRequest, aContext, aStatusCode) { 1.112 + // Do nothing. 1.113 + } 1.114 + }; 1.115 + 1.116 + var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); 1.117 + ph.registerPlayPreviewMimeType(mimeType, true); // ignoring CTP rules 1.118 + 1.119 + var factory = new StreamConverterFactory(); 1.120 + factory.register(OverlayStreamConverter); 1.121 + 1.122 + return (gPlayPreviewRegistration = { 1.123 + unregister: function() { 1.124 + ph.unregisterPlayPreviewMimeType(mimeType); 1.125 + factory.unregister(); 1.126 + gPlayPreviewRegistration = null; 1.127 + } 1.128 + }); 1.129 +} 1.130 + 1.131 +function unregisterPlayPreview() { 1.132 + gPlayPreviewRegistration.unregister(); 1.133 +} 1.134 + 1.135 +Components.utils.import('resource://gre/modules/XPCOMUtils.jsm'); 1.136 +Components.utils.import("resource://gre/modules/Services.jsm"); 1.137 + 1.138 + 1.139 +function test() { 1.140 + waitForExplicitFinish(); 1.141 + registerCleanupFunction(function() { 1.142 + if (gPlayPreviewRegistration) 1.143 + gPlayPreviewRegistration.unregister(); 1.144 + Services.prefs.clearUserPref("plugins.click_to_play"); 1.145 + }); 1.146 + 1.147 + var newTab = gBrowser.addTab(); 1.148 + gBrowser.selectedTab = newTab; 1.149 + gTestBrowser = gBrowser.selectedBrowser; 1.150 + gTestBrowser.addEventListener("load", pageLoad, true); 1.151 + gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true); 1.152 + 1.153 + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED); 1.154 + registerPlayPreview('application/x-test', 'about:'); 1.155 + prepareTest(test1a, gTestRoot + "plugin_test.html", 1); 1.156 +} 1.157 + 1.158 +function finishTest() { 1.159 + gTestBrowser.removeEventListener("load", pageLoad, true); 1.160 + gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true); 1.161 + gBrowser.removeCurrentTab(); 1.162 + window.focus(); 1.163 + finish(); 1.164 +} 1.165 + 1.166 +function handleBindingAttached(evt) { 1.167 + if (evt.target instanceof Ci.nsIObjectLoadingContent && 1.168 + evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) 1.169 + gPlayPreviewPluginActualEvents++; 1.170 +} 1.171 + 1.172 +function pageLoad() { 1.173 + // The plugin events are async dispatched and can come after the load event 1.174 + // This just allows the events to fire before we then go on to test the states 1.175 + 1.176 + // iframe might triggers load event as well, making sure we skip some to let 1.177 + // all iframes on the page be loaded as well 1.178 + if (gNextTestSkip) { 1.179 + gNextTestSkip--; 1.180 + return; 1.181 + } 1.182 + executeSoon(gNextTest); 1.183 +} 1.184 + 1.185 +function prepareTest(nextTest, url, skip) { 1.186 + gNextTest = nextTest; 1.187 + gNextTestSkip = skip; 1.188 + gTestBrowser.contentWindow.location = url; 1.189 +} 1.190 + 1.191 +// Tests a page with normal play preview registration (1/2) 1.192 +function test1a() { 1.193 + var notificationBox = gBrowser.getNotificationBox(gTestBrowser); 1.194 + ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 1a, Should not have displayed the missing plugin notification"); 1.195 + ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 1a, Should not have displayed the blocked plugin notification"); 1.196 + 1.197 + var pluginInfo = getTestPlugin(); 1.198 + ok(pluginInfo, "Should have a test plugin"); 1.199 + 1.200 + var doc = gTestBrowser.contentDocument; 1.201 + var plugin = doc.getElementById("test"); 1.202 + var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); 1.203 + is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 1a, plugin fallback type should be PLUGIN_PLAY_PREVIEW"); 1.204 + ok(!objLoadingContent.activated, "Test 1a, Plugin should not be activated"); 1.205 + 1.206 + var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent"); 1.207 + ok(overlay, "Test 1a, the overlay div is expected"); 1.208 + 1.209 + var iframe = overlay.getElementsByClassName("previewPluginContentFrame")[0]; 1.210 + ok(iframe && iframe.localName == "iframe", "Test 1a, the overlay iframe is expected"); 1.211 + var iframeHref = iframe.contentWindow.location.href; 1.212 + ok(iframeHref == "about:", "Test 1a, the overlay about: content is expected"); 1.213 + 1.214 + var rect = iframe.getBoundingClientRect(); 1.215 + ok(rect.width == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being replaced by actual plugin"); 1.216 + ok(rect.height == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being replaced by actual plugin"); 1.217 + 1.218 + var e = overlay.ownerDocument.createEvent("CustomEvent"); 1.219 + e.initCustomEvent("MozPlayPlugin", true, true, null); 1.220 + overlay.dispatchEvent(e); 1.221 + var condition = function() objLoadingContent.activated; 1.222 + waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin to stop play preview"); 1.223 +} 1.224 + 1.225 +// Tests that activating via MozPlayPlugin through the notification works (part 2/2) 1.226 +function test1b() { 1.227 + var plugin = gTestBrowser.contentDocument.getElementById("test"); 1.228 + var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); 1.229 + ok(objLoadingContent.activated, "Test 1b, Plugin should be activated"); 1.230 + 1.231 + is(gPlayPreviewPluginActualEvents, gPlayPreviewPluginExpectedEvents, 1.232 + "There should be exactly one PluginPlayPreview event"); 1.233 + 1.234 + unregisterPlayPreview(); 1.235 + 1.236 + prepareTest(test2, gTestRoot + "plugin_test.html"); 1.237 +} 1.238 + 1.239 +// Tests a page with a working plugin in it -- the mime type was just unregistered. 1.240 +function test2() { 1.241 + var plugin = gTestBrowser.contentDocument.getElementById("test"); 1.242 + var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); 1.243 + ok(objLoadingContent.activated, "Test 2, Plugin should be activated"); 1.244 + 1.245 + registerPlayPreview('application/x-unknown', 'about:'); 1.246 + 1.247 + prepareTest(test3, gTestRoot + "plugin_test.html"); 1.248 +} 1.249 + 1.250 +// Tests a page with a working plugin in it -- diffent play preview type is reserved. 1.251 +function test3() { 1.252 + var plugin = gTestBrowser.contentDocument.getElementById("test"); 1.253 + var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); 1.254 + ok(objLoadingContent.activated, "Test 3, Plugin should be activated"); 1.255 + 1.256 + unregisterPlayPreview(); 1.257 + 1.258 + registerPlayPreview('application/x-test', 'about:'); 1.259 + Services.prefs.setBoolPref("plugins.click_to_play", true); 1.260 + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); 1.261 + prepareTest(test4a, gTestRoot + "plugin_test.html", 1); 1.262 +} 1.263 + 1.264 +// Test a fallback to the click-to-play 1.265 +function test4a() { 1.266 + var doc = gTestBrowser.contentDocument; 1.267 + var plugin = doc.getElementById("test"); 1.268 + var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); 1.269 + is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 4a, plugin fallback type should be PLUGIN_PLAY_PREVIEW"); 1.270 + ok(!objLoadingContent.activated, "Test 4a, Plugin should not be activated"); 1.271 + 1.272 + var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent"); 1.273 + ok(overlay, "Test 4a, the overlay div is expected"); 1.274 + 1.275 + var e = overlay.ownerDocument.createEvent("CustomEvent"); 1.276 + e.initCustomEvent("MozPlayPlugin", true, true, true); 1.277 + overlay.dispatchEvent(e); 1.278 + var condition = function() objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY; 1.279 + waitForCondition(condition, test4b, "Test 4a, Waited too long for plugin to stop play preview"); 1.280 +} 1.281 + 1.282 +function test4b() { 1.283 + var doc = gTestBrowser.contentDocument; 1.284 + var plugin = doc.getElementById("test"); 1.285 + var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); 1.286 + ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 4b, plugin fallback type should not be PLUGIN_PLAY_PREVIEW"); 1.287 + ok(!objLoadingContent.activated, "Test 4b, Plugin should not be activated"); 1.288 + 1.289 + prepareTest(test5a, gTestRoot + "plugin_test.html", 1); 1.290 +} 1.291 + 1.292 +// Test a bypass of the click-to-play 1.293 +function test5a() { 1.294 + var doc = gTestBrowser.contentDocument; 1.295 + var plugin = doc.getElementById("test"); 1.296 + var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); 1.297 + is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 5a, plugin fallback type should be PLUGIN_PLAY_PREVIEW"); 1.298 + ok(!objLoadingContent.activated, "Test 5a, Plugin should not be activated"); 1.299 + 1.300 + var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent"); 1.301 + ok(overlay, "Test 5a, the overlay div is expected"); 1.302 + 1.303 + var e = overlay.ownerDocument.createEvent("CustomEvent"); 1.304 + e.initCustomEvent("MozPlayPlugin", true, true, false); 1.305 + overlay.dispatchEvent(e); 1.306 + var condition = function() objLoadingContent.activated; 1.307 + waitForCondition(condition, test5b, "Test 5a, Waited too long for plugin to stop play preview"); 1.308 +} 1.309 + 1.310 +function test5b() { 1.311 + var doc = gTestBrowser.contentDocument; 1.312 + var plugin = doc.getElementById("test"); 1.313 + var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); 1.314 + ok(objLoadingContent.activated, "Test 5b, Plugin should be activated"); 1.315 + 1.316 + finishTest(); 1.317 +} 1.318 +