Bug 973001 - getUserMedia UI doesn't work with e10s - fix the urlbar indicators and show the global indicators, r=felipe.

This commit is contained in:
Florian Quèze 2014-09-22 20:39:57 +02:00
Родитель f485086973
Коммит 0d58508a60
4 изменённых файлов: 162 добавлений и 69 удалений

Просмотреть файл

@ -7,6 +7,7 @@ let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/ContentWebRTC.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
"resource://gre/modules/BrowserUtils.jsm");
@ -642,6 +643,9 @@ let DOMFullscreenHandler = {
};
DOMFullscreenHandler.init();
ContentWebRTC.init();
addMessageListener("webrtc:StopSharing", ContentWebRTC);
function gKeywordURIFixup(fixupInfo) {
fixupInfo.QueryInterface(Ci.nsIURIFixupInfo);

Просмотреть файл

@ -0,0 +1,110 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
this.EXPORTED_SYMBOLS = [ "ContentWebRTC" ];
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
"@mozilla.org/mediaManagerService;1",
"nsIMediaManagerService");
this.ContentWebRTC = {
_initialized: false,
init: function() {
if (this._initialized)
return;
this._initialized = true;
Services.obs.addObserver(updateIndicators, "recording-device-events", false);
Services.obs.addObserver(removeBrowserSpecificIndicator, "recording-window-ended", false);
},
receiveMessage: function(aMessage) {
switch (aMessage.name) {
case "webrtc:StopSharing":
Services.obs.notifyObservers(null, "getUserMedia:revoke", aMessage.data);
break;
}
}
};
function updateIndicators() {
let contentWindowSupportsArray = MediaManagerService.activeMediaCaptureWindows;
let count = contentWindowSupportsArray.Count();
let state = {
showGlobalIndicator: count > 0,
showCameraIndicator: false,
showMicrophoneIndicator: false,
showScreenSharingIndicator: ""
};
for (let i = 0; i < count; ++i) {
let contentWindow = contentWindowSupportsArray.GetElementAt(i);
let camera = {}, microphone = {}, screen = {}, window = {}, app = {};
MediaManagerService.mediaCaptureWindowState(contentWindow, camera,
microphone, screen, window, app);
let tabState = {camera: camera.value, microphone: microphone.value};
if (camera.value)
state.showCameraIndicator = true;
if (microphone.value)
state.showMicrophoneIndicator = true;
if (screen.value) {
state.showScreenSharingIndicator = "Screen";
tabState.screen = "Screen";
}
else if (window.value) {
if (state.showScreenSharingIndicator != "Screen")
state.showScreenSharingIndicator = "Window";
tabState.screen = "Window";
}
else if (app.value) {
if (!state.showScreenSharingIndicator)
state.showScreenSharingIndicator = "Application";
tabState.screen = "Application";
}
tabState.windowId = getInnerWindowIDForWindow(contentWindow);
tabState.documentURI = contentWindow.document.documentURI;
let mm = getMessageManagerForWindow(contentWindow);
mm.sendAsyncMessage("webrtc:UpdateBrowserIndicators", tabState);
}
let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
.getService(Ci.nsIMessageSender);
cpmm.sendAsyncMessage("webrtc:UpdateGlobalIndicators", state);
}
function removeBrowserSpecificIndicator(aSubject, aTopic, aData) {
let contentWindow = Services.wm.getOuterWindowWithId(aData);
let mm = getMessageManagerForWindow(contentWindow);
if (mm)
mm.sendAsyncMessage("webrtc:UpdateBrowserIndicators",
{windowId: getInnerWindowIDForWindow(contentWindow)});
}
function getInnerWindowIDForWindow(aContentWindow) {
return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.currentInnerWindowID;
}
function getMessageManagerForWindow(aContentWindow) {
let ir = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor);
try {
// If e10s is disabled, this throws NS_NOINTERFACE for closed tabs.
return ir.getInterface(Ci.nsIContentFrameMessageManager);
} catch(e if e.result == Cr.NS_NOINTERFACE) {
return null;
}
}

Просмотреть файл

@ -15,6 +15,7 @@ EXTRA_JS_MODULES += [
'ContentClick.jsm',
'ContentLinkHandler.jsm',
'ContentSearch.jsm',
'ContentWebRTC.jsm',
'CustomizationTabPreloader.jsm',
'Feeds.jsm',
'FormSubmitObserver.jsm',

Просмотреть файл

@ -23,16 +23,28 @@ XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
this.webrtcUI = {
init: function () {
Services.obs.addObserver(handleRequest, "getUserMedia:request", false);
Services.obs.addObserver(updateIndicators, "recording-device-events", false);
Services.obs.addObserver(removeBrowserSpecificIndicator, "recording-window-ended", false);
Services.obs.addObserver(maybeAddMenuIndicator, "browser-delayed-startup-finished", false);
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIMessageBroadcaster);
ppmm.addMessageListener("webrtc:UpdateGlobalIndicators", this);
let mm = Cc["@mozilla.org/globalmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
mm.addMessageListener("webrtc:UpdateBrowserIndicators", this);
},
uninit: function () {
Services.obs.removeObserver(handleRequest, "getUserMedia:request");
Services.obs.removeObserver(updateIndicators, "recording-device-events");
Services.obs.removeObserver(removeBrowserSpecificIndicator, "recording-window-ended");
Services.obs.removeObserver(maybeAddMenuIndicator, "browser-delayed-startup-finished");
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIMessageBroadcaster);
ppmm.removeMessageListener("webrtc:UpdateGlobalIndicators", this);
let mm = Cc["@mozilla.org/globalmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
mm.removeMessageListener("webrtc:UpdateBrowserIndicators", this);
},
showGlobalIndicator: false,
@ -119,12 +131,19 @@ this.webrtcUI = {
let stringId = "getUserMedia.share" + (type || "SelectedItems") + ".label";
let popupnotification = aMenuList.parentNode.parentNode;
popupnotification.setAttribute("buttonlabel", bundle.getString(stringId));
}
}
},
function getBrowserForWindowId(aWindowID) {
return getBrowserForWindow(Services.wm.getOuterWindowWithId(aWindowID));
}
receiveMessage: function(aMessage) {
switch (aMessage.name) {
case "webrtc:UpdateGlobalIndicators":
updateIndicators(aMessage.data)
break;
case "webrtc:UpdateBrowserIndicators":
updateBrowserSpecificIndicator(aMessage.target, aMessage.data);
break;
}
}
};
function getBrowserForWindow(aContentWindow) {
return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
@ -696,33 +715,11 @@ function maybeAddMenuIndicator(window) {
var gIndicatorWindow = null;
function updateIndicators() {
let contentWindowSupportsArray = MediaManagerService.activeMediaCaptureWindows;
let count = contentWindowSupportsArray.Count();
webrtcUI.showGlobalIndicator = count > 0;
webrtcUI.showCameraIndicator = false;
webrtcUI.showMicrophoneIndicator = false;
webrtcUI.showScreenSharingIndicator = "";
for (let i = 0; i < count; ++i) {
let contentWindow = contentWindowSupportsArray.GetElementAt(i);
let camera = {}, microphone = {}, screen = {}, window = {}, app = {};
MediaManagerService.mediaCaptureWindowState(contentWindow, camera,
microphone, screen, window, app);
if (camera.value)
webrtcUI.showCameraIndicator = true;
if (microphone.value)
webrtcUI.showMicrophoneIndicator = true;
if (screen.value)
webrtcUI.showScreenSharingIndicator = "Screen";
else if (window.value && webrtcUI.showScreenSharingIndicator != "Screen")
webrtcUI.showScreenSharingIndicator = "Window";
else if (app.value && !webrtcUI.showScreenSharingIndicator)
webrtcUI.showScreenSharingIndicator = "Application";
updateBrowserSpecificIndicator(getBrowserForWindow(contentWindow));
}
function updateIndicators(data) {
webrtcUI.showGlobalIndicator = data.showGlobalIndicator;
webrtcUI.showCameraIndicator = data.showCameraIndicator;
webrtcUI.showMicrophoneIndicator = data.showMicrophoneIndicator;
webrtcUI.showScreenSharingIndicator = data.showScreenSharingIndicator;
let browserWindowEnum = Services.wm.getEnumerator("navigator:browser");
while (browserWindowEnum.hasMoreElements()) {
@ -755,28 +752,20 @@ function updateIndicators() {
}
}
function updateBrowserSpecificIndicator(aBrowser) {
let camera = {}, microphone = {}, screen = {}, window = {}, app = {};
MediaManagerService.mediaCaptureWindowState(aBrowser.contentWindow,
camera, microphone, screen,
window, app);
function updateBrowserSpecificIndicator(aBrowser, aState) {
let captureState;
if (camera.value && microphone.value) {
if (aState.camera && aState.microphone) {
captureState = "CameraAndMicrophone";
} else if (camera.value) {
} else if (aState.camera) {
captureState = "Camera";
} else if (microphone.value) {
} else if (aState.microphone) {
captureState = "Microphone";
}
let chromeWin = aBrowser.ownerDocument.defaultView;
let stringBundle = chromeWin.gNavigatorBundle;
let uri = aBrowser.contentWindow.document.documentURIObject;
let windowId = aBrowser.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.currentInnerWindowID;
let windowId = aState.windowId;
let mainAction = {
label: stringBundle.getString("getUserMedia.continueSharing.label"),
accessKey: stringBundle.getString("getUserMedia.continueSharing.accesskey"),
@ -787,15 +776,16 @@ function updateBrowserSpecificIndicator(aBrowser) {
label: stringBundle.getString("getUserMedia.stopSharing.label"),
accessKey: stringBundle.getString("getUserMedia.stopSharing.accesskey"),
callback: function () {
let uri = Services.io.newURI(aState.documentURI, null, null);
let perms = Services.perms;
if (camera.value &&
if (aState.camera &&
perms.testExactPermission(uri, "camera") == perms.ALLOW_ACTION)
perms.remove(uri.host, "camera");
if (microphone.value &&
if (aState.microphone &&
perms.testExactPermission(uri, "microphone") == perms.ALLOW_ACTION)
perms.remove(uri.host, "microphone");
Services.obs.notifyObservers(null, "getUserMedia:revoke", windowId);
aBrowser.messageManager.sendAsyncMessage("webrtc:StopSharing", windowId);
}
}];
let options = {
@ -822,7 +812,7 @@ function updateBrowserSpecificIndicator(aBrowser) {
}
// Now handle the screen sharing indicator.
if (!screen.value && !window.value && !app.value) {
if (!aState.screen) {
removeBrowserNotification(aBrowser,"webRTC-sharingScreen");
return;
}
@ -842,17 +832,12 @@ function updateBrowserSpecificIndicator(aBrowser) {
label: stringBundle.getString("getUserMedia.stopSharing.label"),
accessKey: stringBundle.getString("getUserMedia.stopSharing.accesskey"),
callback: function () {
Services.obs.notifyObservers(null, "getUserMedia:revoke", "screen:" + windowId);
aBrowser.messageManager.sendAsyncMessage("webrtc:StopSharing",
"screen:" + windowId);
}
}];
// If we are sharing both a window and the screen, show 'Screen'.
let stringId = "getUserMedia.sharing";
if (screen.value)
stringId += "Screen";
else if (app.value)
stringId += "Application";
else
stringId += "Window";
// If we are sharing both a window and the screen, we show 'Screen'.
let stringId = "getUserMedia.sharing" + aState.screen;
chromeWin.PopupNotifications.show(aBrowser, "webRTC-sharingScreen",
stringBundle.getString(stringId + ".message"),
"webRTC-sharingScreen-notification-icon",
@ -866,10 +851,3 @@ function removeBrowserNotification(aBrowser, aNotificationId) {
if (notification)
win.PopupNotifications.remove(notification);
}
function removeBrowserSpecificIndicator(aSubject, aTopic, aData) {
let browser = getBrowserForWindowId(aData);
// If the tab has already been closed, ignore the notification.
if (browser.contentWindow)
updateBrowserSpecificIndicator(browser);
}