From d4bbc884fc0ca6c325dce3c6102cd4a90ffeaaf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Fri, 5 Oct 2012 02:37:00 -0700 Subject: [PATCH] Bug 729522: Implement navigator.getUserMedia() permission UI; r=dolske,ui-r=boriss --- browser/components/nsBrowserGlue.js | 5 + .../en-US/chrome/browser/browser.properties | 14 ++ browser/modules/Makefile.in | 1 + browser/modules/webrtcUI.jsm | 123 ++++++++++++++++++ browser/themes/gnomestripe/browser.css | 8 ++ browser/themes/gnomestripe/jar.mn | 14 +- .../gnomestripe/webRTC-shareDevice-16.png | Bin 0 -> 854 bytes .../gnomestripe/webRTC-shareDevice-64.png | Bin 0 -> 4204 bytes browser/themes/pinstripe/browser.css | 8 ++ browser/themes/pinstripe/jar.mn | 2 + .../pinstripe/webRTC-shareDevice-16.png | Bin 0 -> 854 bytes .../pinstripe/webRTC-shareDevice-64.png | Bin 0 -> 4204 bytes browser/themes/winstripe/browser.css | 8 ++ browser/themes/winstripe/jar.mn | 80 ++++++------ .../winstripe/webRTC-shareDevice-16.png | Bin 0 -> 854 bytes .../winstripe/webRTC-shareDevice-64.png | Bin 0 -> 4204 bytes 16 files changed, 219 insertions(+), 44 deletions(-) create mode 100644 browser/modules/webrtcUI.jsm create mode 100644 browser/themes/gnomestripe/webRTC-shareDevice-16.png create mode 100644 browser/themes/gnomestripe/webRTC-shareDevice-64.png create mode 100644 browser/themes/pinstripe/webRTC-shareDevice-16.png create mode 100644 browser/themes/pinstripe/webRTC-shareDevice-64.png create mode 100644 browser/themes/winstripe/webRTC-shareDevice-16.png create mode 100644 browser/themes/winstripe/webRTC-shareDevice-64.png diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index e4722bfd59c9..87724b832ff4 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -44,6 +44,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "BrowserNewTabPreloader", XPCOMUtils.defineLazyModuleGetter(this, "PdfJs", "resource://pdf.js/PdfJs.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "webrtcUI", + "resource:///modules/webrtcUI.jsm"); + const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser"; const PREF_PLUGINS_UPDATEURL = "plugins.update.url"; @@ -320,6 +323,7 @@ BrowserGlue.prototype = { UserAgentOverrides.uninit(); webappsUI.uninit(); SignInToWebsiteUX.uninit(); + webrtcUI.uninit(); }, _onAppDefaults: function BG__onAppDefaults() { @@ -351,6 +355,7 @@ BrowserGlue.prototype = { BrowserNewTabPreloader.init(); SignInToWebsiteUX.init(); PdfJs.init(); + webrtcUI.init(); Services.obs.notifyObservers(null, "browser-ui-startup-complete", ""); }, diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index a0eef8ab4413..4472661270a2 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -423,3 +423,17 @@ identity.next.accessKey = n identity.loggedIn.description = Signed in as: %S identity.loggedIn.signOut.label = Sign Out identity.loggedIn.signOut.accessKey = O + +# LOCALIZATION NOTE (getUserMedia.shareCamera.message, getUserMedia.shareMicrophone.message, getUserMedia.shareCameraAndMicrophone.message): %S is the website origin (e.g. www.mozilla.org) +# LOCALIZATION NOTE (getUserMedia.shareMicrophone.message, getUserMedia.shareSpecificMicrophone.label): %S is the website origin (e.g. www.mozilla.org) +getUserMedia.shareCamera.message = Would you like to share your camera with %S? +getUserMedia.shareCamera.label = Share Camera +getUserMedia.shareCamera.accesskey = S +getUserMedia.shareSpecificCamera.label = Share Camera: %S +getUserMedia.shareMicrophone.message = Would you like to share your microphone with %S? +getUserMedia.shareMicrophone.label = Share Microphone +getUserMedia.shareMicrophone.accesskey = S +getUserMedia.shareSpecificMicrophone.label = Share Microphone: %S +getUserMedia.shareCameraAndMicrophone.message = Would you like to share your camera and microphone with %S? +getUserMedia.shareCameraAndMicrophone.label = Share Camera and Microphone +getUserMedia.shareCameraAndMicrophone.accesskey = S diff --git a/browser/modules/Makefile.in b/browser/modules/Makefile.in index 72f58fb38ef6..d74f5179dcdf 100644 --- a/browser/modules/Makefile.in +++ b/browser/modules/Makefile.in @@ -24,6 +24,7 @@ EXTRA_JS_MODULES = \ TelemetryTimestamps.jsm \ Social.jsm \ webappsUI.jsm \ + webrtcUI.jsm \ $(NULL) ifeq ($(MOZ_WIDGET_TOOLKIT),windows) diff --git a/browser/modules/webrtcUI.jsm b/browser/modules/webrtcUI.jsm new file mode 100644 index 000000000000..917bc89b174e --- /dev/null +++ b/browser/modules/webrtcUI.jsm @@ -0,0 +1,123 @@ +/* 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"; + +let EXPORTED_SYMBOLS = ["webrtcUI"]; + +const Cu = Components.utils; +const Ci = Components.interfaces; + +Cu.import("resource://gre/modules/Services.jsm"); + +let webrtcUI = { + init: function () { + Services.obs.addObserver(handleRequest, "getUserMedia:request", false); + }, + uninit: function () { + Services.obs.removeObserver(handleRequest, "getUserMedia:request"); + } +} + +function handleRequest(aSubject, aTopic, aData) { + let {windowID: windowID, callID: callID} = JSON.parse(aData); + + let someWindow = Services.wm.getMostRecentWindow(null); + let contentWindow = someWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .getOuterWindowWithId(windowID); + let browser = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell) + .chromeEventHandler; + + let params = aSubject.QueryInterface(Ci.nsIMediaStreamOptions); + + browser.ownerDocument.defaultView.navigator.mozGetUserMediaDevices( + function (devices) { + prompt(browser, callID, params.audio, params.video, devices); + }, + function (error) { + Cu.reportError(error); + } + ); +} + +function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) { + let audioDevices = []; + let videoDevices = []; + for (let device of aDevices) { + device = device.QueryInterface(Ci.nsIMediaDevice); + switch (device.type) { + case "audio": + if (aAudioRequested) + audioDevices.push(device); + break; + case "video": + if (aVideoRequested) + videoDevices.push(device); + break; + } + } + + let requestType; + if (audioDevices.length && videoDevices.length) + requestType = "shareCameraAndMicrophone"; + else if (audioDevices.length) + requestType = "shareMicrophone"; + else if (videoDevices.length) + requestType = "shareCamera"; + else + return; + + let host = aBrowser.contentDocument.documentURIObject.asciiHost; + let chromeWin = aBrowser.ownerDocument.defaultView; + let stringBundle = chromeWin.gNavigatorBundle; + let message = stringBundle.getFormattedString("getUserMedia." + requestType + ".message", + [ host ]); + + let responseSent = false; + + let mainAction = { + label: stringBundle.getString("getUserMedia." + requestType + ".label"), + accessKey: stringBundle.getString("getUserMedia." + requestType + ".accesskey"), + callback: function () { + Services.obs.notifyObservers(null, "getUserMedia:response:allow", aCallID); + responseSent = true; + } + }; + + let secondaryActions = []; + let selectableDevices = videoDevices.length ? videoDevices : audioDevices; + if (selectableDevices.length > 1) { + let selectableDeviceNumber = 0; + for (let device of selectableDevices) { + selectableDeviceNumber++; + secondaryActions.push({ + label: stringBundle.getFormattedString( + device.type == "audio" ? + "getUserMedia.shareSpecificMicrophone.label" : + "getUserMedia.shareSpecificCamera.label", + [ device.name ]), + accessKey: selectableDeviceNumber, + callback: function () { + Services.obs.notifyObservers(device, "getUserMedia:response:allow", aCallID); + responseSent = true; + } + }); + } + } + + let options = { + removeOnDismissal: true, + eventCallback: function (aType) { + if (!responseSent && aType == "removed") + Services.obs.notifyObservers(null, "getUserMedia:response:deny", aCallID); + } + }; + + chromeWin.PopupNotifications.show(aBrowser, "webRTC-shareDevices", message, + "webRTC-notification-icon", mainAction, + secondaryActions, options); +} diff --git a/browser/themes/gnomestripe/browser.css b/browser/themes/gnomestripe/browser.css index fa0821bba8ae..a136fc981abd 100644 --- a/browser/themes/gnomestripe/browser.css +++ b/browser/themes/gnomestripe/browser.css @@ -1199,6 +1199,10 @@ toolbar[iconsize="small"] #feed-button { list-style-image: url(chrome://browser/skin/webapps-64.png); } +.popup-notification-icon[popupid="webRTC-shareDevices"] { + list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png); +} + /* Notification icon box */ #notification-popup-box { position: relative; @@ -1266,6 +1270,10 @@ toolbar[iconsize="small"] #feed-button { list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric-16.png); } +#webRTC-notification-icon { + list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png); +} + #treecolAutoCompleteImage { max-width : 36px; } diff --git a/browser/themes/gnomestripe/jar.mn b/browser/themes/gnomestripe/jar.mn index df1daa3c2be5..a250a22c812f 100644 --- a/browser/themes/gnomestripe/jar.mn +++ b/browser/themes/gnomestripe/jar.mn @@ -5,9 +5,9 @@ browser.jar: % skin browser classic/1.0 %skin/classic/browser/ % override chrome://global/skin/icons/warning-16.png moz-icon://stock/gtk-dialog-warning?size=menu - skin/classic/browser/sanitizeDialog.css (sanitizeDialog.css) -* skin/classic/browser/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css) -* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css) + skin/classic/browser/sanitizeDialog.css +* skin/classic/browser/aboutPrivateBrowsing.css +* skin/classic/browser/aboutSessionRestore.css skin/classic/browser/aboutSessionRestore-window-icon.png skin/classic/browser/aboutCertError.css skin/classic/browser/aboutCertError_sectionCollapsed.png @@ -18,8 +18,8 @@ browser.jar: skin/classic/browser/aboutSyncTabs.css #endif skin/classic/browser/actionicon-tab.png -* skin/classic/browser/browser.css (browser.css) -* skin/classic/browser/engineManager.css (engineManager.css) +* skin/classic/browser/browser.css +* skin/classic/browser/engineManager.css skin/classic/browser/Geolocation-16.png skin/classic/browser/Geolocation-64.png skin/classic/browser/Go-arrow.png @@ -36,13 +36,15 @@ browser.jar: skin/classic/browser/page-livemarks.png skin/classic/browser/Privacy-16.png skin/classic/browser/Privacy-48.png - skin/classic/browser/searchbar.css (searchbar.css) + skin/classic/browser/searchbar.css skin/classic/browser/Secure.png skin/classic/browser/Security-broken.png skin/classic/browser/setDesktopBackground.css skin/classic/browser/Toolbar.png skin/classic/browser/Toolbar-small.png skin/classic/browser/urlbar-arrow.png + skin/classic/browser/webRTC-shareDevice-16.png + skin/classic/browser/webRTC-shareDevice-64.png skin/classic/browser/downloads/buttons.png (downloads/buttons.png) skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png) skin/classic/browser/downloads/download-notification.png (downloads/download-notification.png) diff --git a/browser/themes/gnomestripe/webRTC-shareDevice-16.png b/browser/themes/gnomestripe/webRTC-shareDevice-16.png new file mode 100644 index 0000000000000000000000000000000000000000..0c8eafda08acf20c21eeef8ae63cc6630590084b GIT binary patch literal 854 zcmV-c1F8IpP) zWOHlNeK|33b|a}HsQA>C)T=B_t6TpK_Lk;6WJaxvgd*GK*( za8~TED?ZrNVkvRERmow~839R#W6M83e)7KV?p*ltsxK`8p(b-#!}U&AZS(nH+yW)O zgn~>Jk^s!bMaV)XY-Sa~;qJa){Z}t&N+M$5#8sxU6K(hMYcDr?JQ0-V#Bi_^MF!C{FpiXyD*rWDNnB|JB8gkd;Xb&+Fc*j?(t^a8`fkp*N>2C8!bP3J3*D;h{>@sOA5ni30t9~~8l zm;xIO#;S1#?E`+?cbZa^2(JAPf3nS3VO#<9o zMVN^pxdP@hDv==OCmwY0E1;(cp}<(X)3*(i?IxNxM}1-pf$T%-h; z1n*c^zZ{x+@%L3GM6_?OZ!508)M{}QP>w*Y+m2X5$LQxM1kr@#;&05pzug=9`lN;9 zqG=zKWG$@8tvJ?fE84Y36?2@_xGh>FyyzL92!4BZSB}gK{P#7k6$o(>G0Vlbl&MPr g-sel#_eX#M0Kal~wlU;xA^-pY07*qoM6N<$g5Uvyf&c&j literal 0 HcmV?d00001 diff --git a/browser/themes/gnomestripe/webRTC-shareDevice-64.png b/browser/themes/gnomestripe/webRTC-shareDevice-64.png new file mode 100644 index 0000000000000000000000000000000000000000..a1a51b8d8f580a7c97b449aed9ae60207a6a5373 GIT binary patch literal 4204 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 .toolbarbutton-menu-dropmarker { list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric-16.png); } +#webRTC-notification-icon { + list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png); +} + .popup-notification-icon { width: 64px; height: 64px; @@ -3107,6 +3111,10 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { list-style-image: url(chrome://browser/skin/webapps-64.png); } +.popup-notification-icon[popupid="webRTC-shareDevices"] { + list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png); +} + /* Popup Buttons */ #identity-popup-more-info-button { @hudButton@ diff --git a/browser/themes/pinstripe/jar.mn b/browser/themes/pinstripe/jar.mn index 1fff34f6ee05..003e62d7c4ae 100644 --- a/browser/themes/pinstripe/jar.mn +++ b/browser/themes/pinstripe/jar.mn @@ -66,6 +66,8 @@ browser.jar: skin/classic/browser/urlbar-arrow@2x.png skin/classic/browser/urlbar-popup-blocked.png skin/classic/browser/urlbar-popup-blocked@2x.png + skin/classic/browser/webRTC-shareDevice-16.png + skin/classic/browser/webRTC-shareDevice-64.png skin/classic/browser/downloads/buttons.png (downloads/buttons.png) skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png) skin/classic/browser/downloads/download-notification.png (downloads/download-notification.png) diff --git a/browser/themes/pinstripe/webRTC-shareDevice-16.png b/browser/themes/pinstripe/webRTC-shareDevice-16.png new file mode 100644 index 0000000000000000000000000000000000000000..0c8eafda08acf20c21eeef8ae63cc6630590084b GIT binary patch literal 854 zcmV-c1F8IpP) zWOHlNeK|33b|a}HsQA>C)T=B_t6TpK_Lk;6WJaxvgd*GK*( za8~TED?ZrNVkvRERmow~839R#W6M83e)7KV?p*ltsxK`8p(b-#!}U&AZS(nH+yW)O zgn~>Jk^s!bMaV)XY-Sa~;qJa){Z}t&N+M$5#8sxU6K(hMYcDr?JQ0-V#Bi_^MF!C{FpiXyD*rWDNnB|JB8gkd;Xb&+Fc*j?(t^a8`fkp*N>2C8!bP3J3*D;h{>@sOA5ni30t9~~8l zm;xIO#;S1#?E`+?cbZa^2(JAPf3nS3VO#<9o zMVN^pxdP@hDv==OCmwY0E1;(cp}<(X)3*(i?IxNxM}1-pf$T%-h; z1n*c^zZ{x+@%L3GM6_?OZ!508)M{}QP>w*Y+m2X5$LQxM1kr@#;&05pzug=9`lN;9 zqG=zKWG$@8tvJ?fE84Y36?2@_xGh>FyyzL92!4BZSB}gK{P#7k6$o(>G0Vlbl&MPr g-sel#_eX#M0Kal~wlU;xA^-pY07*qoM6N<$g5Uvyf&c&j literal 0 HcmV?d00001 diff --git a/browser/themes/pinstripe/webRTC-shareDevice-64.png b/browser/themes/pinstripe/webRTC-shareDevice-64.png new file mode 100644 index 0000000000000000000000000000000000000000..a1a51b8d8f580a7c97b449aed9ae60207a6a5373 GIT binary patch literal 4204 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 literal 0 HcmV?d00001 diff --git a/browser/themes/winstripe/webRTC-shareDevice-64.png b/browser/themes/winstripe/webRTC-shareDevice-64.png new file mode 100644 index 0000000000000000000000000000000000000000..a1a51b8d8f580a7c97b449aed9ae60207a6a5373 GIT binary patch literal 4204 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