diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc index 0e1e712fe0b..6c83caa0092 100644 --- a/browser/base/content/browser-menubar.inc +++ b/browser/base/content/browser-menubar.inc @@ -451,7 +451,8 @@ + accesskey="&toolsMenu.accesskey;" + onpopupshowing="mirrorShow(this)"> + + + #ifndef XP_UNIX { + let item = doc.createElement("menuitem"); + item.setAttribute("label", service.friendlyName); + item._service = service; + item.addEventListener("command", mirrorMenuItemClicked); + popup.appendChild(item); + }); +}; + function _checkDefaultAndSwitchToMetro() { #ifdef HAVE_SHELL_SERVICE #ifdef XP_WIN diff --git a/browser/base/content/content.js b/browser/base/content/content.js index 47e3568a59e..5a7bc986845 100644 --- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -27,6 +27,22 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "FormSubmitObserver", "resource:///modules/FormSubmitObserver.jsm"); +XPCOMUtils.defineLazyGetter(this, "SimpleServiceDiscovery", function() { + let ssdp = Cu.import("resource://gre/modules/SimpleServiceDiscovery.jsm", {}).SimpleServiceDiscovery; + // Register targets + ssdp.registerDevice({ + id: "roku:ecp", + target: "roku:ecp", + factory: function(aService) { + Cu.import("resource://gre/modules/RokuApp.jsm"); + return new RokuApp(aService); + }, + mirror: true, + types: ["video/mp4"], + extensions: ["mp4"] + }); + return ssdp; +}); // TabChildGlobal var global = this; @@ -76,6 +92,16 @@ addMessageListener("MixedContent:ReenableProtection", function() { docShell.mixedContentChannel = null; }); +addMessageListener("SecondScreen:tab-mirror", function(message) { + let app = SimpleServiceDiscovery.findAppForService(message.data.service); + if (app) { + let width = content.scrollWidth; + let height = content.scrollHeight; + let viewport = {cssWidth: width, cssHeight: height, width: width, height: height}; + app.mirror(function() {}, content, viewport, function() {}, content); + } +}); + addEventListener("DOMFormHasPassword", function(event) { InsecurePasswordUtils.checkForInsecurePasswords(event.target); LoginManagerContent.onFormPassword(event); diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 0b8241317e6..a9f02ecda85 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -807,7 +807,7 @@ BrowserGlue.prototype = { Cu.import("resource://gre/modules/RokuApp.jsm"); return new RokuApp(aService); }, - mirror: false, + mirror: true, types: ["video/mp4"], extensions: ["mp4"] }; diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd index 792cc4792d5..d2095ee7781 100644 --- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -95,6 +95,8 @@ when there are no windows but Firefox is still running. --> + + diff --git a/browser/modules/CastingApps.jsm b/browser/modules/CastingApps.jsm index df974f04f60..1c8a706ea02 100644 --- a/browser/modules/CastingApps.jsm +++ b/browser/modules/CastingApps.jsm @@ -130,6 +130,10 @@ var CastingApps = { return filteredServices; }, + getServicesForMirroring: function () { + return SimpleServiceDiscovery.services.filter(service => service.mirror); + }, + // RemoteMedia callback API methods onRemoteMediaStart: function (remoteMedia) { if (!this.session) { diff --git a/mobile/android/chrome/content/CastingApps.js b/mobile/android/chrome/content/CastingApps.js index 82c8422aad8..5e2bd3bdd37 100644 --- a/mobile/android/chrome/content/CastingApps.js +++ b/mobile/android/chrome/content/CastingApps.js @@ -98,7 +98,7 @@ var CastingApps = { let callbackFunc = function(aService) { let app = SimpleServiceDiscovery.findAppForService(aService); if (app) { - app.mirror(function() {}, window, BrowserApp.selectedTab.getViewport(), this._mirrorStarted.bind(this)); + app.mirror(function() {}, window, BrowserApp.selectedTab.getViewport(), this._mirrorStarted.bind(this), window.BrowserApp.selectedBrowser.contentWindow); } }.bind(this); diff --git a/toolkit/modules/secondscreen/RokuApp.jsm b/toolkit/modules/secondscreen/RokuApp.jsm index bcd637162c6..5feb5d47c3f 100644 --- a/toolkit/modules/secondscreen/RokuApp.jsm +++ b/toolkit/modules/secondscreen/RokuApp.jsm @@ -147,16 +147,16 @@ RokuApp.prototype = { } }, - mirror: function(callback, win, viewport, mirrorStartedCallback) { + mirror: function(callback, win, viewport, mirrorStartedCallback, contentWindow) { if (this.mirrorAppID == -1) { // The status function may not have been called yet if mirrorAppID is -1 - this.status(this._createRemoteMirror.bind(this, callback, win, viewport, mirrorStartedCallback)); + this.status(this._createRemoteMirror.bind(this, callback, win, viewport, mirrorStartedCallback, contentWindow)); } else { - this._createRemoteMirror(callback, win, viewport, mirrorStartedCallback); + this._createRemoteMirror(callback, win, viewport, mirrorStartedCallback, contentWindow); } }, - _createRemoteMirror: function(callback, win, viewport, mirrorStartedCallback) { + _createRemoteMirror: function(callback, win, viewport, mirrorStartedCallback, contentWindow) { if (this.mirrorAppID == -1) { // TODO: Inform user to install Roku WebRTC Player Channel. log("RokuApp: Failed to find Mirror App ID."); @@ -169,7 +169,7 @@ RokuApp.prototype = { xhr.addEventListener("load", (function() { // 204 seems to be returned if the channel is already running if ((xhr.status == 200) || (xhr.status == 204)) { - this.remoteMirror = new RemoteMirror(this.resourceURL, win, viewport, mirrorStartedCallback); + this.remoteMirror = new RemoteMirror(this.resourceURL, win, viewport, mirrorStartedCallback, contentWindow); } }).bind(this), false); @@ -279,7 +279,7 @@ RemoteMedia.prototype = { } } -function RemoteMirror(url, win, viewport, mirrorStartedCallback) { +function RemoteMirror(url, win, viewport, mirrorStartedCallback, contentWindow) { this._serverURI = Services.io.newURI(url , null, null); this._window = win; this._iceCandidates = []; @@ -287,7 +287,7 @@ function RemoteMirror(url, win, viewport, mirrorStartedCallback) { // This code insures the generated tab mirror is not wider than 800 nor taller than 600 // Better dimensions should be chosen after the Roku Channel is working. - let windowId = win.BrowserApp.selectedBrowser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).outerWindowID; + let windowId = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).outerWindowID; let cWidth = Math.max(viewport.cssWidth, viewport.width); let cHeight = Math.max(viewport.cssHeight, viewport.height);