michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: var rootDir = getRootDirectory(gTestPath); michael@0: const gTestRoot = rootDir; michael@0: michael@0: var gTestBrowser = null; michael@0: var gNextTest = null; michael@0: var gNextTestSkip = 0; michael@0: var gPlayPreviewPluginActualEvents = 0; michael@0: var gPlayPreviewPluginExpectedEvents = 1; michael@0: michael@0: var gPlayPreviewRegistration = null; michael@0: michael@0: function registerPlayPreview(mimeType, targetUrl) { michael@0: michael@0: function StreamConverterFactory() {} michael@0: StreamConverterFactory.prototype = { michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]), michael@0: _targetConstructor: null, michael@0: michael@0: register: function register(targetConstructor) { michael@0: this._targetConstructor = targetConstructor; michael@0: var proto = targetConstructor.prototype; michael@0: var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); michael@0: registrar.registerFactory(proto.classID, proto.classDescription, michael@0: proto.contractID, this); michael@0: }, michael@0: michael@0: unregister: function unregister() { michael@0: var proto = this._targetConstructor.prototype; michael@0: var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); michael@0: registrar.unregisterFactory(proto.classID, this); michael@0: this._targetConstructor = null; michael@0: }, michael@0: michael@0: // nsIFactory michael@0: createInstance: function createInstance(aOuter, iid) { michael@0: if (aOuter !== null) michael@0: throw Cr.NS_ERROR_NO_AGGREGATION; michael@0: return (new (this._targetConstructor)).QueryInterface(iid); michael@0: }, michael@0: michael@0: // nsIFactory michael@0: lockFactory: function lockFactory(lock) { michael@0: // No longer used as of gecko 1.7. michael@0: throw Cr.NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: }; michael@0: michael@0: function OverlayStreamConverter() {} michael@0: OverlayStreamConverter.prototype = { michael@0: QueryInterface: XPCOMUtils.generateQI([ michael@0: Ci.nsISupports, michael@0: Ci.nsIStreamConverter, michael@0: Ci.nsIStreamListener, michael@0: Ci.nsIRequestObserver michael@0: ]), michael@0: michael@0: classID: Components.ID('{4c6030f7-e20a-264f-0f9b-ada3a9e97384}'), michael@0: classDescription: 'overlay-test-data Component', michael@0: contractID: '@mozilla.org/streamconv;1?from=application/x-moz-playpreview&to=*/*', michael@0: michael@0: // nsIStreamConverter::convert michael@0: convert: function(aFromStream, aFromType, aToType, aCtxt) { michael@0: throw Cr.NS_ERROR_NOT_IMPLEMENTED; michael@0: }, michael@0: michael@0: // nsIStreamConverter::asyncConvertData michael@0: asyncConvertData: function(aFromType, aToType, aListener, aCtxt) { michael@0: var isValidRequest = false; michael@0: try { michael@0: var request = aCtxt; michael@0: request.QueryInterface(Ci.nsIChannel); michael@0: var spec = request.URI.spec; michael@0: var expectedSpec = 'data:application/x-moz-playpreview;,' + mimeType; michael@0: isValidRequest = (spec == expectedSpec); michael@0: } catch (e) { } michael@0: if (!isValidRequest) michael@0: throw Cr.NS_ERROR_NOT_IMPLEMENTED; michael@0: michael@0: // Store the listener passed to us michael@0: this.listener = aListener; michael@0: }, michael@0: michael@0: // nsIStreamListener::onDataAvailable michael@0: onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) { michael@0: // Do nothing since all the data loading is handled by the viewer. michael@0: ok(false, "onDataAvailable should not be called"); michael@0: }, michael@0: michael@0: // nsIRequestObserver::onStartRequest michael@0: onStartRequest: function(aRequest, aContext) { michael@0: michael@0: // Setup the request so we can use it below. michael@0: aRequest.QueryInterface(Ci.nsIChannel); michael@0: // Cancel the request so the viewer can handle it. michael@0: aRequest.cancel(Cr.NS_BINDING_ABORTED); michael@0: michael@0: // Create a new channel that is viewer loaded as a resource. michael@0: var ioService = Services.io; michael@0: var channel = ioService.newChannel(targetUrl, null, null); michael@0: channel.asyncOpen(this.listener, aContext); michael@0: }, michael@0: michael@0: // nsIRequestObserver::onStopRequest michael@0: onStopRequest: function(aRequest, aContext, aStatusCode) { michael@0: // Do nothing. michael@0: } michael@0: }; michael@0: michael@0: var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); michael@0: ph.registerPlayPreviewMimeType(mimeType, true); // ignoring CTP rules michael@0: michael@0: var factory = new StreamConverterFactory(); michael@0: factory.register(OverlayStreamConverter); michael@0: michael@0: return (gPlayPreviewRegistration = { michael@0: unregister: function() { michael@0: ph.unregisterPlayPreviewMimeType(mimeType); michael@0: factory.unregister(); michael@0: gPlayPreviewRegistration = null; michael@0: } michael@0: }); michael@0: } michael@0: michael@0: function unregisterPlayPreview() { michael@0: gPlayPreviewRegistration.unregister(); michael@0: } michael@0: michael@0: Components.utils.import('resource://gre/modules/XPCOMUtils.jsm'); michael@0: Components.utils.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: michael@0: function test() { michael@0: waitForExplicitFinish(); michael@0: registerCleanupFunction(function() { michael@0: if (gPlayPreviewRegistration) michael@0: gPlayPreviewRegistration.unregister(); michael@0: Services.prefs.clearUserPref("plugins.click_to_play"); michael@0: }); michael@0: michael@0: var newTab = gBrowser.addTab(); michael@0: gBrowser.selectedTab = newTab; michael@0: gTestBrowser = gBrowser.selectedBrowser; michael@0: gTestBrowser.addEventListener("load", pageLoad, true); michael@0: gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true); michael@0: michael@0: setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED); michael@0: registerPlayPreview('application/x-test', 'about:'); michael@0: prepareTest(test1a, gTestRoot + "plugin_test.html", 1); michael@0: } michael@0: michael@0: function finishTest() { michael@0: gTestBrowser.removeEventListener("load", pageLoad, true); michael@0: gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true); michael@0: gBrowser.removeCurrentTab(); michael@0: window.focus(); michael@0: finish(); michael@0: } michael@0: michael@0: function handleBindingAttached(evt) { michael@0: if (evt.target instanceof Ci.nsIObjectLoadingContent && michael@0: evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) michael@0: gPlayPreviewPluginActualEvents++; michael@0: } michael@0: michael@0: function pageLoad() { michael@0: // The plugin events are async dispatched and can come after the load event michael@0: // This just allows the events to fire before we then go on to test the states michael@0: michael@0: // iframe might triggers load event as well, making sure we skip some to let michael@0: // all iframes on the page be loaded as well michael@0: if (gNextTestSkip) { michael@0: gNextTestSkip--; michael@0: return; michael@0: } michael@0: executeSoon(gNextTest); michael@0: } michael@0: michael@0: function prepareTest(nextTest, url, skip) { michael@0: gNextTest = nextTest; michael@0: gNextTestSkip = skip; michael@0: gTestBrowser.contentWindow.location = url; michael@0: } michael@0: michael@0: // Tests a page with normal play preview registration (1/2) michael@0: function test1a() { michael@0: var notificationBox = gBrowser.getNotificationBox(gTestBrowser); michael@0: ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 1a, Should not have displayed the missing plugin notification"); michael@0: ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 1a, Should not have displayed the blocked plugin notification"); michael@0: michael@0: var pluginInfo = getTestPlugin(); michael@0: ok(pluginInfo, "Should have a test plugin"); michael@0: michael@0: var doc = gTestBrowser.contentDocument; michael@0: var plugin = doc.getElementById("test"); michael@0: var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); michael@0: is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 1a, plugin fallback type should be PLUGIN_PLAY_PREVIEW"); michael@0: ok(!objLoadingContent.activated, "Test 1a, Plugin should not be activated"); michael@0: michael@0: var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent"); michael@0: ok(overlay, "Test 1a, the overlay div is expected"); michael@0: michael@0: var iframe = overlay.getElementsByClassName("previewPluginContentFrame")[0]; michael@0: ok(iframe && iframe.localName == "iframe", "Test 1a, the overlay iframe is expected"); michael@0: var iframeHref = iframe.contentWindow.location.href; michael@0: ok(iframeHref == "about:", "Test 1a, the overlay about: content is expected"); michael@0: michael@0: var rect = iframe.getBoundingClientRect(); michael@0: ok(rect.width == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being replaced by actual plugin"); michael@0: ok(rect.height == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being replaced by actual plugin"); michael@0: michael@0: var e = overlay.ownerDocument.createEvent("CustomEvent"); michael@0: e.initCustomEvent("MozPlayPlugin", true, true, null); michael@0: overlay.dispatchEvent(e); michael@0: var condition = function() objLoadingContent.activated; michael@0: waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin to stop play preview"); michael@0: } michael@0: michael@0: // Tests that activating via MozPlayPlugin through the notification works (part 2/2) michael@0: function test1b() { michael@0: var plugin = gTestBrowser.contentDocument.getElementById("test"); michael@0: var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); michael@0: ok(objLoadingContent.activated, "Test 1b, Plugin should be activated"); michael@0: michael@0: is(gPlayPreviewPluginActualEvents, gPlayPreviewPluginExpectedEvents, michael@0: "There should be exactly one PluginPlayPreview event"); michael@0: michael@0: unregisterPlayPreview(); michael@0: michael@0: prepareTest(test2, gTestRoot + "plugin_test.html"); michael@0: } michael@0: michael@0: // Tests a page with a working plugin in it -- the mime type was just unregistered. michael@0: function test2() { michael@0: var plugin = gTestBrowser.contentDocument.getElementById("test"); michael@0: var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); michael@0: ok(objLoadingContent.activated, "Test 2, Plugin should be activated"); michael@0: michael@0: registerPlayPreview('application/x-unknown', 'about:'); michael@0: michael@0: prepareTest(test3, gTestRoot + "plugin_test.html"); michael@0: } michael@0: michael@0: // Tests a page with a working plugin in it -- diffent play preview type is reserved. michael@0: function test3() { michael@0: var plugin = gTestBrowser.contentDocument.getElementById("test"); michael@0: var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); michael@0: ok(objLoadingContent.activated, "Test 3, Plugin should be activated"); michael@0: michael@0: unregisterPlayPreview(); michael@0: michael@0: registerPlayPreview('application/x-test', 'about:'); michael@0: Services.prefs.setBoolPref("plugins.click_to_play", true); michael@0: setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); michael@0: prepareTest(test4a, gTestRoot + "plugin_test.html", 1); michael@0: } michael@0: michael@0: // Test a fallback to the click-to-play michael@0: function test4a() { michael@0: var doc = gTestBrowser.contentDocument; michael@0: var plugin = doc.getElementById("test"); michael@0: var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); michael@0: is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 4a, plugin fallback type should be PLUGIN_PLAY_PREVIEW"); michael@0: ok(!objLoadingContent.activated, "Test 4a, Plugin should not be activated"); michael@0: michael@0: var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent"); michael@0: ok(overlay, "Test 4a, the overlay div is expected"); michael@0: michael@0: var e = overlay.ownerDocument.createEvent("CustomEvent"); michael@0: e.initCustomEvent("MozPlayPlugin", true, true, true); michael@0: overlay.dispatchEvent(e); michael@0: var condition = function() objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY; michael@0: waitForCondition(condition, test4b, "Test 4a, Waited too long for plugin to stop play preview"); michael@0: } michael@0: michael@0: function test4b() { michael@0: var doc = gTestBrowser.contentDocument; michael@0: var plugin = doc.getElementById("test"); michael@0: var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); michael@0: ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 4b, plugin fallback type should not be PLUGIN_PLAY_PREVIEW"); michael@0: ok(!objLoadingContent.activated, "Test 4b, Plugin should not be activated"); michael@0: michael@0: prepareTest(test5a, gTestRoot + "plugin_test.html", 1); michael@0: } michael@0: michael@0: // Test a bypass of the click-to-play michael@0: function test5a() { michael@0: var doc = gTestBrowser.contentDocument; michael@0: var plugin = doc.getElementById("test"); michael@0: var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); michael@0: is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 5a, plugin fallback type should be PLUGIN_PLAY_PREVIEW"); michael@0: ok(!objLoadingContent.activated, "Test 5a, Plugin should not be activated"); michael@0: michael@0: var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent"); michael@0: ok(overlay, "Test 5a, the overlay div is expected"); michael@0: michael@0: var e = overlay.ownerDocument.createEvent("CustomEvent"); michael@0: e.initCustomEvent("MozPlayPlugin", true, true, false); michael@0: overlay.dispatchEvent(e); michael@0: var condition = function() objLoadingContent.activated; michael@0: waitForCondition(condition, test5b, "Test 5a, Waited too long for plugin to stop play preview"); michael@0: } michael@0: michael@0: function test5b() { michael@0: var doc = gTestBrowser.contentDocument; michael@0: var plugin = doc.getElementById("test"); michael@0: var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); michael@0: ok(objLoadingContent.activated, "Test 5b, Plugin should be activated"); michael@0: michael@0: finishTest(); michael@0: } michael@0: