Bug 1333468 - Part 1 - Move WebRTC sharing indicator into the identity block and add a paused state. r=florian

MozReview-Commit-ID: ETi6nX2Eapc

--HG--
extra : rebase_source : cc7575236c84de23ff7e86182c81160306f096c6
This commit is contained in:
Johann Hofmann 2017-11-16 19:33:19 +01:00
Родитель 415481dcda
Коммит 593a01f28c
5 изменённых файлов: 94 добавлений и 67 удалений

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

@ -7426,14 +7426,17 @@ var gIdentityHandler = {
updateSharingIndicator() {
let tab = gBrowser.selectedTab;
let sharing = tab.getAttribute("sharing");
if (sharing)
this._identityBox.setAttribute("sharing", sharing);
else
this._identityBox.removeAttribute("sharing");
this._sharingState = tab._sharingState;
this._identityBox.removeAttribute("paused");
this._identityBox.removeAttribute("sharing");
if (this._sharingState && this._sharingState.sharing) {
this._identityBox.setAttribute("sharing", this._sharingState.sharing);
if (this._sharingState.paused) {
this._identityBox.setAttribute("paused", "true");
}
}
if (this._identityPopup.state == "open") {
this.updateSitePermissions();
PanelView.forNode(this._identityPopupMainView)
@ -7930,7 +7933,7 @@ var gIdentityHandler = {
if (this._sharingState) {
// If WebRTC device or screen permissions are in use, we need to find
// the associated permission item to set the inUse field to true.
// the associated permission item to set the sharingState field.
for (let id of ["camera", "microphone", "screen"]) {
if (this._sharingState[id]) {
let found = false;
@ -7938,7 +7941,7 @@ var gIdentityHandler = {
if (permission.id != id)
continue;
found = true;
permission.inUse = true;
permission.sharingState = this._sharingState[id];
break;
}
if (!found) {
@ -7949,7 +7952,7 @@ var gIdentityHandler = {
id,
state: SitePermissions.ALLOW,
scope: SitePermissions.SCOPE_REQUEST,
inUse: true,
sharingState: this._sharingState[id],
});
}
}
@ -8000,8 +8003,28 @@ var gIdentityHandler = {
let classes = "identity-popup-permission-icon " + aPermission.id + "-icon";
if (aPermission.state == SitePermissions.BLOCK)
classes += " blocked-permission-icon";
if (aPermission.inUse)
if (aPermission.sharingState == Ci.nsIMediaManagerService.STATE_CAPTURE_ENABLED ||
(aPermission.id == "screen" && aPermission.sharingState &&
!aPermission.sharingState.includes("Paused"))) {
classes += " in-use";
// Synchronize control center and identity block blinking animations.
BrowserUtils.promiseLayoutFlushed(document, "style", () => {
let sharingIconBlink = document.getElementById("sharing-icon").getAnimations()[0];
if (sharingIconBlink) {
let startTime = sharingIconBlink.startTime;
window.requestAnimationFrame(() => {
// TODO(Bug 1440607): This could cause a style flush, but putting
// the getAnimations() call outside of rAF causes a leak.
let imgBlink = img.getAnimations()[0];
if (imgBlink) {
imgBlink.startTime = startTime;
}
});
}
});
}
img.setAttribute("class", classes);
let nameLabel = document.createElement("label");
@ -8060,7 +8083,7 @@ var gIdentityHandler = {
let {state, scope} = aPermission;
// If the user did not permanently allow this device but it is currently
// used, set the variables to display a "temporarily allowed" info.
if (state != SitePermissions.ALLOW && aPermission.inUse) {
if (state != SitePermissions.ALLOW && aPermission.sharingState) {
state = SitePermissions.ALLOW;
scope = SitePermissions.SCOPE_REQUEST;
}
@ -8084,7 +8107,7 @@ var gIdentityHandler = {
button.addEventListener("command", () => {
let browser = gBrowser.selectedBrowser;
this._permissionList.removeChild(container);
if (aPermission.inUse &&
if (aPermission.sharingState &&
["camera", "microphone", "screen"].includes(aPermission.id)) {
let windowId = this._sharingState.windowId;
if (aPermission.id == "screen") {

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

@ -1560,21 +1560,16 @@
if (!tab)
return;
let sharing;
if (aState.screen) {
sharing = "screen";
} else if (aState.camera) {
sharing = "camera";
} else if (aState.microphone) {
sharing = "microphone";
}
if (sharing) {
tab.setAttribute("sharing", sharing);
if (aState.sharing) {
tab._sharingState = aState;
if (aState.paused) {
tab.removeAttribute("sharing");
} else {
tab.setAttribute("sharing", aState.sharing);
}
} else {
tab.removeAttribute("sharing");
tab._sharingState = null;
tab.removeAttribute("sharing");
}
this._tabAttrModified(tab, ["sharing"]);
@ -1588,10 +1583,11 @@
<body><![CDATA[
// Normalize the state object for consumers (ie.extensions).
let state = Object.assign({}, aTab._sharingState);
// ensure bool if undefined
state.camera = !!state.camera;
state.microphone = !!state.microphone;
return state;
return {
camera: !!state.camera,
microphone: !!state.microphone,
screen: state.screen && state.screen.replace("Paused", ""),
};
]]></body>
</method>

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

@ -313,28 +313,29 @@ function updateIndicators(aSubject, aTopic, aData) {
}
let tabState = getTabStateForContentWindow(contentWindow);
if (tabState.camera == MediaManagerService.STATE_CAPTURE_ENABLED)
if (tabState.camera == MediaManagerService.STATE_CAPTURE_ENABLED ||
tabState.camera == MediaManagerService.STATE_CAPTURE_DISABLED) {
state.showCameraIndicator = true;
if (tabState.camera == MediaManagerService.STATE_CAPTURE_DISABLED)
state.showCameraIndicator = true;
if (tabState.microphone == MediaManagerService.STATE_CAPTURE_ENABLED)
state.showMicrophoneIndicator = true;
if (tabState.microphone == MediaManagerService.STATE_CAPTURE_DISABLED)
}
if (tabState.microphone == MediaManagerService.STATE_CAPTURE_ENABLED ||
tabState.microphone == MediaManagerService.STATE_CAPTURE_DISABLED) {
state.showMicrophoneIndicator = true;
}
if (tabState.screen) {
if (tabState.screen == "Screen") {
if (tabState.screen.startsWith("Screen")) {
state.showScreenSharingIndicator = "Screen";
} else if (tabState.screen == "Window") {
} else if (tabState.screen.startsWith("Window")) {
if (state.showScreenSharingIndicator != "Screen")
state.showScreenSharingIndicator = "Window";
} else if (tabState.screen == "Application") {
} else if (tabState.screen.startsWith("Application")) {
if (!state.showScreenSharingIndicator)
state.showScreenSharingIndicator = "Application";
} else if (tabState.screen == "Browser") {
} else if (tabState.screen.startsWith("Browser")) {
if (!state.showScreenSharingIndicator)
state.showScreenSharingIndicator = "Browser";
}
}
let mm = getMessageManagerForWindow(contentWindow);
mm.sendAsyncMessage("webrtc:UpdateBrowserIndicators", tabState);
}
@ -366,14 +367,37 @@ function getTabStateForContentWindow(aContentWindow) {
camera, microphone,
screen, window, app, browser);
let tabState = {camera: camera.value, microphone: microphone.value};
if (screen.value != MediaManagerService.STATE_NOCAPTURE)
if (screen.value == MediaManagerService.STATE_CAPTURE_ENABLED)
tabState.screen = "Screen";
else if (window.value != MediaManagerService.STATE_NOCAPTURE)
else if (window.value == MediaManagerService.STATE_CAPTURE_ENABLED)
tabState.screen = "Window";
else if (app.value != MediaManagerService.STATE_NOCAPTURE)
else if (app.value == MediaManagerService.STATE_CAPTURE_ENABLED)
tabState.screen = "Application";
else if (browser.value != MediaManagerService.STATE_NOCAPTURE)
else if (browser.value == MediaManagerService.STATE_CAPTURE_ENABLED)
tabState.screen = "Browser";
else if (screen.value == MediaManagerService.STATE_CAPTURE_DISABLED)
tabState.screen = "ScreenPaused";
else if (window.value == MediaManagerService.STATE_CAPTURE_DISABLED)
tabState.screen = "WindowPaused";
else if (app.value == MediaManagerService.STATE_CAPTURE_DISABLED)
tabState.screen = "ApplicationPaused";
else if (browser.value == MediaManagerService.STATE_CAPTURE_DISABLED)
tabState.screen = "BrowserPaused";
if (tabState.screen) {
tabState.sharing = "screen";
} else if (tabState.camera) {
tabState.sharing = "camera";
} else if (tabState.microphone) {
tabState.sharing = "microphone";
}
// The stream is considered paused when we're sharing something
// but all devices are off or set to disabled.
tabState.paused = tabState.sharing &&
(!tabState.screen || tabState.screen.includes("Paused")) &&
tabState.camera != MediaManagerService.STATE_CAPTURE_ENABLED &&
tabState.microphone != MediaManagerService.STATE_CAPTURE_ENABLED;
tabState.windowId = getInnerWindowIDForWindow(aContentWindow);
tabState.documentURI = aContentWindow.document.documentURI;

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

@ -76,6 +76,7 @@
border-image-slice: 1;
}
#sharing-icon,
#identity-icon,
#tracking-protection-icon,
#connection-icon,
@ -113,16 +114,6 @@
/* SHARING ICON */
#sharing-icon {
width: 16px;
height: 16px;
margin-inline-start: -16px;
position: relative;
-moz-context-properties: fill;
fill: rgb(224, 41, 29);
display: none;
}
#identity-box[sharing="camera"] > #sharing-icon {
list-style-image: url("chrome://browser/skin/notification-icons/camera.svg");
}
@ -135,24 +126,18 @@
list-style-image: url("chrome://browser/skin/notification-icons/screen.svg");
}
#identity-box[sharing] > #sharing-icon {
display: -moz-box;
animation-delay: -1.5s;
#identity-box:not([sharing]) > #sharing-icon {
display: none;
}
#identity-box[sharing] > #identity-icon,
#sharing-icon {
animation: 3s linear identity-box-sharing-icon-pulse infinite;
#identity-box[sharing]:not([paused]) > #sharing-icon {
animation: 1.5s ease in-use-blink infinite;
-moz-context-properties: fill;
fill: rgb(224, 41, 29);
}
/* This should remain identical to tab-sharing-icon-pulse in tabs.inc.css */
@keyframes identity-box-sharing-icon-pulse {
0%, 16.66%, 83.33%, 100% {
opacity: 0;
}
33.33%, 66.66% {
opacity: 1;
}
@keyframes in-use-blink {
50% { opacity: 0; }
}
/* TRACKING PROTECTION ICON */

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

@ -249,7 +249,6 @@ tabbrowser {
animation: 3s linear tab-sharing-icon-pulse infinite;
}
/* This should remain identical to identity-box-sharing-icon-pulse in identity-block.inc.css */
@keyframes tab-sharing-icon-pulse {
0%, 16.66%, 83.33%, 100% {
opacity: 0;