mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 989094 - Remember video and audio sources for webrtc. r=mfinkle
This commit is contained in:
parent
2f673f8913
commit
60c559be95
@ -4,9 +4,14 @@
|
||||
"use strict";
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Notifications", "resource://gre/modules/Notifications.jsm");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "contentPrefs",
|
||||
"@mozilla.org/content-pref/service;1",
|
||||
"nsIContentPrefService2");
|
||||
|
||||
var WebrtcUI = {
|
||||
_notificationId: null,
|
||||
VIDEO_SOURCE: "videoSource",
|
||||
AUDIO_SOURCE: "audioDevice",
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic === "getUserMedia:request") {
|
||||
@ -78,39 +83,42 @@ var WebrtcUI = {
|
||||
|
||||
contentWindow.navigator.mozGetUserMediaDevices(
|
||||
constraints,
|
||||
function (devices) {
|
||||
WebrtcUI.prompt(contentWindow, aSubject.callID, constraints.audio,
|
||||
constraints.video, devices);
|
||||
function (aDevices) {
|
||||
WebrtcUI.prompt(contentWindow, aSubject.callID, constraints.audio, constraints.video, aDevices);
|
||||
},
|
||||
function (error) {
|
||||
Cu.reportError(error);
|
||||
},
|
||||
aSubject.innerWindowID);
|
||||
Cu.reportError, aSubject.innerWindowID);
|
||||
},
|
||||
|
||||
getDeviceButtons: function(audioDevices, videoDevices, aCallID) {
|
||||
getDeviceButtons: function(aAudioDevices, aVideoDevices, aCallID, aHost) {
|
||||
return [{
|
||||
label: Strings.browser.GetStringFromName("getUserMedia.denyRequest.label"),
|
||||
callback: function() {
|
||||
callback: () => {
|
||||
Services.obs.notifyObservers(null, "getUserMedia:response:deny", aCallID);
|
||||
}
|
||||
},
|
||||
{
|
||||
}, {
|
||||
label: Strings.browser.GetStringFromName("getUserMedia.shareRequest.label"),
|
||||
callback: function(checked /* ignored */, inputs) {
|
||||
callback: (checked /* ignored */, inputs) => {
|
||||
let allowedDevices = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
|
||||
|
||||
let audioId = 0;
|
||||
if (inputs && inputs.audioDevice != undefined)
|
||||
audioId = inputs.audioDevice;
|
||||
if (audioDevices[audioId])
|
||||
allowedDevices.AppendElement(audioDevices[audioId]);
|
||||
if (inputs && inputs[this.AUDIO_SOURCE] != undefined) {
|
||||
audioId = inputs[this.AUDIO_SOURCE];
|
||||
}
|
||||
|
||||
if (aAudioDevices[audioId]) {
|
||||
allowedDevices.AppendElement(aAudioDevices[audioId]);
|
||||
this.setDefaultDevice(this.AUDIO_SOURCE, aAudioDevices[audioId].name, aHost);
|
||||
}
|
||||
|
||||
let videoId = 0;
|
||||
if (inputs && inputs.videoSource != undefined)
|
||||
videoId = inputs.videoSource;
|
||||
if (videoDevices[videoId])
|
||||
allowedDevices.AppendElement(videoDevices[videoId]);
|
||||
if (inputs && inputs[this.VIDEO_SOURCE] != undefined) {
|
||||
videoId = inputs[this.VIDEO_SOURCE];
|
||||
}
|
||||
|
||||
if (aVideoDevices[videoId]) {
|
||||
allowedDevices.AppendElement(aVideoDevices[videoId]);
|
||||
this.setDefaultDevice(this.VIDEO_SOURCE, aVideoDevices[videoId].name, aHost);
|
||||
}
|
||||
|
||||
Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
|
||||
}
|
||||
@ -121,30 +129,34 @@ var WebrtcUI = {
|
||||
_getList: function(aDevices, aType) {
|
||||
let defaultCount = 0;
|
||||
return aDevices.map(function(device) {
|
||||
// if this is a Camera input, convert the name to something readable
|
||||
let res = /Camera\ \d+,\ Facing (front|back)/.exec(device.name);
|
||||
if (res)
|
||||
return Strings.browser.GetStringFromName("getUserMedia." + aType + "." + res[1] + "Camera");
|
||||
let name = device.name;
|
||||
// if this is a Camera input, convert the name to something readable
|
||||
let res = /Camera\ \d+,\ Facing (front|back)/.exec(name);
|
||||
if (res) {
|
||||
return Strings.browser.GetStringFromName("getUserMedia." + aType + "." + res[1] + "Camera");
|
||||
}
|
||||
|
||||
if (device.name.startsWith("&") && device.name.endsWith(";"))
|
||||
return Strings.browser.GetStringFromName(device.name.substring(1, device.name.length -1));
|
||||
if (name.startsWith("&") && name.endsWith(";")) {
|
||||
return Strings.browser.GetStringFromName(name.substring(1, name.length -1));
|
||||
}
|
||||
|
||||
if (device.name.trim() == "") {
|
||||
defaultCount++;
|
||||
return Strings.browser.formatStringFromName("getUserMedia." + aType + ".default", [defaultCount], 1);
|
||||
}
|
||||
return device.name
|
||||
}, this);
|
||||
if (name.trim() == "") {
|
||||
defaultCount++;
|
||||
return Strings.browser.formatStringFromName("getUserMedia." + aType + ".default", [defaultCount], 1);
|
||||
}
|
||||
|
||||
return name;
|
||||
}, this);
|
||||
},
|
||||
|
||||
_addDevicesToOptions: function(aDevices, aType, aOptions, extraOptions) {
|
||||
if (aDevices.length) {
|
||||
_addDevicesToOptions: function(aDevices, aType, aOptions, aHost, aContext) {
|
||||
if (aDevices.length == 0) {
|
||||
return Promise.resolve(aOptions);
|
||||
}
|
||||
|
||||
let updateOptions = () => {
|
||||
// Filter out empty items from the list
|
||||
let list = this._getList(aDevices, aType);
|
||||
if (extraOptions)
|
||||
list = list.concat(extraOptions);
|
||||
|
||||
if (list.length > 0) {
|
||||
aOptions.inputs.push({
|
||||
id: aType,
|
||||
@ -152,40 +164,96 @@ var WebrtcUI = {
|
||||
label: Strings.browser.GetStringFromName("getUserMedia." + aType + ".prompt"),
|
||||
values: list
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return aOptions;
|
||||
}
|
||||
|
||||
return this.getDefaultDevice(aType, aHost, aContext).then((defaultDevice) => {
|
||||
aDevices.sort((a, b) => {
|
||||
if (b.name === defaultDevice) return 1;
|
||||
return 0;
|
||||
});
|
||||
return updateOptions();
|
||||
}).catch(updateOptions);
|
||||
},
|
||||
|
||||
// Sets the default for a aHost. If no aHost is specified, sets the browser wide default.
|
||||
// Saving is async, but this doesn't wait for a result.
|
||||
setDefaultDevice: function(aType, aValue, aHost, aContext) {
|
||||
if (aHost) {
|
||||
contentPrefs.set(aHost, "webrtc." + aType, aValue, aContext);
|
||||
} else {
|
||||
contentPrefs.setGlobal("webrtc." + aType, aValue, aContext);
|
||||
}
|
||||
},
|
||||
|
||||
prompt: function prompt(aContentWindow, aCallID, aAudioRequested,
|
||||
aVideoRequested, aDevices) {
|
||||
_checkContentPref(aHost, aType, aContext) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let result = null;
|
||||
let handler = {
|
||||
handleResult: (aResult) => result = aResult,
|
||||
handleCompletion: function(aReason) {
|
||||
if (aReason == Components.interfaces.nsIContentPrefCallback2.COMPLETE_OK &&
|
||||
result instanceof Components.interfaces.nsIContentPref) {
|
||||
resolve(result.value);
|
||||
} else {
|
||||
reject(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (aHost) {
|
||||
contentPrefs.getByDomainAndName(aHost, "webrtc." + aType, aContext, handler);
|
||||
} else {
|
||||
contentPrefs.getGlobal("webrtc." + aType, aContext, handler);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Returns the default device for this aHost. If no aHost is specified, returns a browser wide default
|
||||
getDefaultDevice: function(aType, aHost, aContext) {
|
||||
return this._checkContentPref(aHost, aType, aContext).catch(() => {
|
||||
// If we found nothing for the initial pref, try looking for a global one
|
||||
return this._checkContentPref(null, aType, aContext);
|
||||
});
|
||||
},
|
||||
|
||||
prompt: function (aWindow, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
let audioDevices = [];
|
||||
let videoDevices = [];
|
||||
|
||||
// Split up all the available aDevices into audio and video categories
|
||||
for (let device of aDevices) {
|
||||
device = device.QueryInterface(Ci.nsIMediaDevice);
|
||||
switch (device.type) {
|
||||
case "audio":
|
||||
if (aAudioRequested)
|
||||
if (aAudioRequested) {
|
||||
audioDevices.push(device);
|
||||
}
|
||||
break;
|
||||
case "video":
|
||||
if (aVideoRequested)
|
||||
if (aVideoRequested) {
|
||||
videoDevices.push(device);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Bsaed on the aTypes available, setup the prompt and icon text
|
||||
let requestType;
|
||||
if (audioDevices.length && videoDevices.length)
|
||||
if (audioDevices.length && videoDevices.length) {
|
||||
requestType = "CameraAndMicrophone";
|
||||
else if (audioDevices.length)
|
||||
} else if (audioDevices.length) {
|
||||
requestType = "Microphone";
|
||||
else if (videoDevices.length)
|
||||
} else if (videoDevices.length) {
|
||||
requestType = "Camera";
|
||||
else
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
let host = aContentWindow.document.documentURIObject.host;
|
||||
let host = aWindow.document.documentURIObject.host;
|
||||
// Show the app name if this is a WebRT app, otherwise show the host.
|
||||
let requestor = BrowserApp.manifest ? "'" + BrowserApp.manifest.name + "'" : host;
|
||||
let message = Strings.browser.formatStringFromName("getUserMedia.share" + requestType + ".message", [ requestor ], 1);
|
||||
|
||||
@ -193,24 +261,20 @@ var WebrtcUI = {
|
||||
// if the users only option would be to select "No Audio" or "No Video"
|
||||
// i.e. we're only showing audio or only video and there is only one device for that type
|
||||
// don't bother showing a menulist to select from
|
||||
var extraItems = null;
|
||||
if (videoDevices.length > 1 || audioDevices.length > 0) {
|
||||
// Only show the No Video option if there are also Audio devices to choose from
|
||||
if (audioDevices.length > 0)
|
||||
extraItems = [ Strings.browser.GetStringFromName("getUserMedia.videoSource.none") ];
|
||||
// videoSource is both the string used for l10n lookup and the object that will be returned
|
||||
this._addDevicesToOptions(videoDevices, "videoSource", options, extraItems);
|
||||
if (videoDevices.length > 0 && audioDevices.length > 0) {
|
||||
videoDevices.push({ name: Strings.browser.GetStringFromName("getUserMedia.videoSource.none") });
|
||||
audioDevices.push({ name: Strings.browser.GetStringFromName("getUserMedia.audioDevice.none") });
|
||||
}
|
||||
|
||||
if (audioDevices.length > 1 || videoDevices.length > 0) {
|
||||
// Only show the No Audio option if there are also Video devices to choose from
|
||||
if (videoDevices.length > 0)
|
||||
extraItems = [ Strings.browser.GetStringFromName("getUserMedia.audioDevice.none") ];
|
||||
this._addDevicesToOptions(audioDevices, "audioDevice", options, extraItems);
|
||||
}
|
||||
|
||||
let buttons = this.getDeviceButtons(audioDevices, videoDevices, aCallID);
|
||||
|
||||
NativeWindow.doorhanger.show(message, "webrtc-request", buttons, BrowserApp.selectedTab.id, options);
|
||||
let loadContext = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsILoadContext);
|
||||
// videoSource is both the string used for l10n lookup and the object that will be returned
|
||||
this._addDevicesToOptions(videoDevices, this.VIDEO_SOURCE, options, host, loadContext).then((aOptions) => {
|
||||
return this._addDevicesToOptions(audioDevices, this.AUDIO_SOURCE, aOptions, host, loadContext);
|
||||
}).catch(Cu.reportError).then((aOptions) => {
|
||||
let buttons = this.getDeviceButtons(audioDevices, videoDevices, aCallID, host);
|
||||
NativeWindow.doorhanger.show(message, "webrtc-request", buttons, BrowserApp.selectedTab.id, aOptions);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user