Closed
Bug 1088758
Opened 11 years ago
Closed 11 years ago
Add the ability to mirror tabs from desktop to a second screen
Categories
(Core :: WebRTC, defect)
Core
WebRTC
Tracking
()
RESOLVED
FIXED
mozilla37
People
(Reporter: blassey, Assigned: blassey)
References
Details
Attachments
(2 files, 5 obsolete files)
|
1.91 KB,
patch
|
jesup
:
review+
|
Details | Diff | Splinter Review |
|
13.15 KB,
patch
|
mconley
:
review+
|
Details | Diff | Splinter Review |
Splitting out tab mirroring work from bug 1054959
Attachment #8511116 -
Flags: review?(gavin.sharp)
| Assignee | ||
Updated•11 years ago
|
Assignee: nobody → blassey.bugs
Comment 1•11 years ago
|
||
Comment on attachment 8511116 [details] [diff] [review]
mirror.patch
AFAICT this just adding a Tools menu item, which is probably not ideal (not discoverable at all). Need to work with UX on a better option for that.
On my machine the menu appears and just doesn't have anything in it. It needs to be either hidden or disabled (UX call).
>diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
>+function populateMirrorTabMenu(popup) {
>+ let videoEl = this.target;
Not used. Also should remove the reportError().
>+ let width = gBrowser.selectedBrowser.contentWindow.scrollWidth;
>+ let height = gBrowser.selectedBrowser.contentWindow.scrollHeight;
>+ app.mirror(function() {}, window, viewport, function() {}, gBrowser.selectedBrowser.contentWindow);
These don't look very e10s friendly?
Attachment #8511116 -
Flags: review?(gavin.sharp) → review-
| Assignee | ||
Comment 2•11 years ago
|
||
I don't have a roku available in Portland, so this is untested.
Attachment #8511116 -
Attachment is obsolete: true
Attachment #8531519 -
Flags: review?(gavin.sharp)
| Assignee | ||
Comment 3•11 years ago
|
||
This works, as tested with rbarker's roku simulator[1]
1] https://people.mozilla.org/~rbarker/roku-sim.tgz
Jesup, I changed our check for privileged callers in MediaManager. I suspect this is what we actually want here (testing the privilege level of the caller rather than the document), but this code dates back to the original implementation of GuM in bug 752352 and has since wound its way though a few refactors.
Attachment #8531519 -
Attachment is obsolete: true
Attachment #8531519 -
Flags: review?(gavin.sharp)
Attachment #8534088 -
Flags: review?(rjesup)
Attachment #8534088 -
Flags: review?(gavin.sharp)
| Assignee | ||
Comment 4•11 years ago
|
||
Attachment #8534096 -
Flags: review?(rjesup)
Attachment #8534096 -
Flags: review?(gavin.sharp)
Comment 5•11 years ago
|
||
Comment on attachment 8534096 [details] [diff] [review]
mirror.patch
Review of attachment 8534096 [details] [diff] [review]:
-----------------------------------------------------------------
r- only because c++ callers of GetUserMedia() need to be modified to ensure they have a JS context (AutoNoJSAPI()) or the code needs to assume c++ callers are privileged in some manner (and be sure that's true). SpeechAPI, and jib thinks some B2G callers call it directly. If those are covered, r+
Attachment #8534096 -
Flags: review?(rjesup) → review-
| Assignee | ||
Comment 6•11 years ago
|
||
Attachment #8534088 -
Attachment is obsolete: true
Attachment #8534096 -
Attachment is obsolete: true
Attachment #8534088 -
Flags: review?(rjesup)
Attachment #8534088 -
Flags: review?(gavin.sharp)
Attachment #8534096 -
Flags: review?(gavin.sharp)
Attachment #8534410 -
Flags: review?(rjesup)
| Assignee | ||
Comment 7•11 years ago
|
||
Attachment #8534411 -
Flags: review?(gavin.sharp)
Updated•11 years ago
|
Attachment #8534410 -
Flags: review?(rjesup) → review+
| Assignee | ||
Comment 8•11 years ago
|
||
Comment on attachment 8534411 [details] [diff] [review]
mirror.patch
Review of attachment 8534411 [details] [diff] [review]:
-----------------------------------------------------------------
r?mfinkle for RokuApp.jsm and SimpleServiceDiscovery.jsm, r?mconley for everything else
Attachment #8534411 -
Flags: review?(mconley)
Attachment #8534411 -
Flags: review?(mark.finkle)
Attachment #8534411 -
Flags: review?(gavin.sharp)
Comment 9•11 years ago
|
||
Comment on attachment 8534411 [details] [diff] [review]
mirror.patch
>diff --git a/browser/base/content/content.js b/browser/base/content/content.js
>+addMessageListener("secondscreen:tab-mirror", function(message) {
>+ try {
>+ if (SimpleServiceDiscovery.numDevices() == 0) {
>+ SimpleServiceDiscovery.registerDevice(rokuDevice);
>+ }
I'd rather not add SimpleServiceDiscovery.numDevices(), but just call SimpleServiceDiscovery.registerDevice(...) which will ignore the device if it's already registered. If you don't like the log-spew, we could remove that.
>diff --git a/toolkit/modules/secondscreen/SimpleServiceDiscovery.jsm b/toolkit/modules/secondscreen/SimpleServiceDiscovery.jsm
>+ numDevices: function numDevices() {
>+ return this._devices.size;
>+ },
As mentioned above, I'd rather not add this.
r+ with the nits addressed
Attachment #8534411 -
Flags: review?(mark.finkle) → review+
| Assignee | ||
Comment 10•11 years ago
|
||
(In reply to Mark Finkle (:mfinkle) from comment #9)
> Comment on attachment 8534411 [details] [diff] [review]
> mirror.patch
>
> >diff --git a/browser/base/content/content.js b/browser/base/content/content.js
>
> >+addMessageListener("secondscreen:tab-mirror", function(message) {
> >+ try {
> >+ if (SimpleServiceDiscovery.numDevices() == 0) {
>
> >+ SimpleServiceDiscovery.registerDevice(rokuDevice);
> >+ }
>
> I'd rather not add SimpleServiceDiscovery.numDevices(), but just call
> SimpleServiceDiscovery.registerDevice(...) which will ignore the device if
> it's already registered. If you don't like the log-spew, we could remove
> that.
My concern isn't log spew as much as we'll be calling this a lot, and for each mirroring end point we add (though currently we only have roku) and presumably checking the size of the map is O(1) while calling get is O(log(n)).
>
> >diff --git a/toolkit/modules/secondscreen/SimpleServiceDiscovery.jsm b/toolkit/modules/secondscreen/SimpleServiceDiscovery.jsm
>
> >+ numDevices: function numDevices() {
> >+ return this._devices.size;
> >+ },
>
> As mentioned above, I'd rather not add this.
>
> r+ with the nits addressed
Comment 11•11 years ago
|
||
Comment on attachment 8534411 [details] [diff] [review]
mirror.patch
Review of attachment 8534411 [details] [diff] [review]:
-----------------------------------------------------------------
Just some minor suggestions - but in general, this looks good.
::: browser/base/content/browser.js
@@ +2989,5 @@
> + let services = CastingApps.getServicesForMirroring();
> + services.forEach(service => {
> + let item = doc.createElement("menuitem");
> + item.setAttribute("label", service.friendlyName);
> + item.addEventListener("command", event => {
Instead of attaching a command event listener to each item, I recommend the following:
1) Having a single oncommand event handler set on the popup directly. That handler looks at the event target, extracts some unique service ID from it, retrieves the service for that unique ID, and then sends the message down to the selected browser.
2) In populateMirrorTabMenu, for each service, append a menuitem, and set an attribute on that menuitem to be the unique ID for the service. This is what the oncommand handler will read.
@@ +2990,5 @@
> + services.forEach(service => {
> + let item = doc.createElement("menuitem");
> + item.setAttribute("label", service.friendlyName);
> + item.addEventListener("command", event => {
> + gBrowser.selectedBrowser.messageManager.sendAsyncMessage("secondscreen:tab-mirror",
Browser's been using Capitalized message strings. Might as well stick with it - SecondScreen:tab-mirror
::: browser/base/content/content.js
@@ +78,5 @@
> docShell.mixedContentChannel = null;
> });
>
> +addMessageListener("secondscreen:tab-mirror", function(message) {
> + try {
Nit - the rest of this file has 2-space indentation. Let's keep rolling with that.
@@ +92,5 @@
> + types: ["video/mp4"],
> + extensions: ["mp4"]
> + };
> +
> + // Register targets
Busted indentation
@@ +93,5 @@
> + extensions: ["mp4"]
> + };
> +
> + // Register targets
> + SimpleServiceDiscovery.registerDevice(rokuDevice);
rokuDevice actually doesn't seem to be used elsewhere, so maybe just:
SimpleServiceDiscovery.registerDevice({
id: "roku:ecp",
/* ... */
});
@@ +100,5 @@
> + if (app) {
> + let width = content.scrollWidth;
> + let height = content.scrollHeight;
> + let viewport = {cssWidth: width, cssHeight: height, width: width, height: height};
> + let en = Services.wm.getXULWindowEnumerator(null);
This doesn't appear to be used.
@@ +103,5 @@
> + let viewport = {cssWidth: width, cssHeight: height, width: width, height: height};
> + let en = Services.wm.getXULWindowEnumerator(null);
> + app.mirror(function() {}, content, viewport, function() {}, content);
> + }
> + } catch (ex) {Cu.reportError(ex);}
This massive try-catch freaks me out. What does it protect us from? If we throw when receiving this message from the parent... I don't see bad things happening.
::: browser/modules/CastingApps.jsm
@@ +134,5 @@
> + let filteredServices = SimpleServiceDiscovery.services.filter(service => {
> + return service.mirror;
> + });
> +
> + return filteredServices;
Might as well just do:
return SimpleServiceDiscovery.services.filter(service => service.mirror);
Attachment #8534411 -
Flags: review?(mconley)
| Assignee | ||
Comment 12•11 years ago
|
||
Attachment #8534411 -
Attachment is obsolete: true
Attachment #8536841 -
Flags: review?(mconley)
Comment 13•11 years ago
|
||
Comment on attachment 8536841 [details] [diff] [review]
mirror.patch
Review of attachment 8536841 [details] [diff] [review]:
-----------------------------------------------------------------
Just some last suggestions, and then let's land this puppy.
(Note that I did not actually apply and test the patch - my review was strictly from inspection).
::: browser/base/content/browser.js
@@ +2976,5 @@
>
> +function mirrorShow(popup) {
> + let services = CastingApps.getServicesForMirroring();
> + if (services.length == 0) {
> + popup.ownerDocument.getElementById("menu_mirrorTabCmd").disabled = true;
popup.ownerDocument.getElementById("menu_mirrorTabCmd").disabled = !Services.length;
@@ +2984,5 @@
> +}
> +
> +function mirrorMenuItemClicked() {
> + gBrowser.selectedBrowser.messageManager.sendAsyncMessage("SecondScreen:tab-mirror",
> + {service: this._service});
Nit - indentation
Also, we generally use the event.originalTarget - so take an event argument to mirrorMenuItemClicked, and pass event.originalTarget._service.
@@ +2996,5 @@
> + services.forEach(service => {
> + let item = doc.createElement("menuitem");
> + item.setAttribute("label", service.friendlyName);
> + item._service = service;
> + item.addEventListener("command", mirrorMenuItemClicked, false);
capturing is false by default, so no need for the third parameter.
Attachment #8536841 -
Flags: review?(mconley) → review+
Comment 14•11 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/d0be7c6566ae
https://hg.mozilla.org/mozilla-central/rev/a7770ec46f04
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla37
Comment 15•11 years ago
|
||
Reading comment #1), who made the UX decision to have an always-present disabled menu instead of a hidden one, and where?
I don't think this should be always-visible, considering most users don't actually have a device with which they can mirror. We can show them if/when they do.
Flags: needinfo?(blassey.bugs)
| Assignee | ||
Comment 16•11 years ago
|
||
(In reply to :Gijs Kruitbosch from comment #15)
> Reading comment #1), who made the UX decision to have an always-present
> disabled menu instead of a hidden one, and where?
no one
Flags: needinfo?(blassey.bugs)
Comment 17•11 years ago
|
||
(In reply to :Gijs Kruitbosch from comment #15)
> Reading comment #1), who made the UX decision to have an always-present
> disabled menu instead of a hidden one, and where?
>
> I don't think this should be always-visible, considering most users don't
> actually have a device with which they can mirror. We can show them if/when
> they do.
I agree. Let's file a follow-up bug to get that menuitem hidden in those cases.
You need to log in
before you can comment on or make changes to this bug.
Description
•