mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 774521 - Desktop Web Runtime UI implementation for mozGetUserMedia (Camera API). r=myk
This commit is contained in:
parent
d91e3f7465
commit
5a4a2f1db1
@ -786,6 +786,7 @@ bin/libfreebl_32int64_3.so
|
||||
@BINPATH@/webapprt/modules/WebappRT.jsm
|
||||
@BINPATH@/webapprt/modules/WebappsHandler.jsm
|
||||
@BINPATH@/webapprt/modules/RemoteDebugger.jsm
|
||||
@BINPATH@/webapprt/modules/WebRTCHandler.jsm
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_METRO
|
||||
|
@ -25,6 +25,7 @@ Cu.import("resource://gre/modules/osfile.jsm");
|
||||
// Initialize window-independent handling of webapps- notifications.
|
||||
Cu.import("resource://webapprt/modules/WebappsHandler.jsm");
|
||||
Cu.import("resource://webapprt/modules/WebappRT.jsm");
|
||||
Cu.import("resource://webapprt/modules/WebRTCHandler.jsm");
|
||||
|
||||
const PROFILE_DIR = OS.Constants.Path.profileDir;
|
||||
|
||||
|
103
webapprt/WebRTCHandler.jsm
Normal file
103
webapprt/WebRTCHandler.jsm
Normal file
@ -0,0 +1,103 @@
|
||||
/* 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";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [];
|
||||
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
function handleRequest(aSubject, aTopic, aData) {
|
||||
let { windowID, callID } = aSubject;
|
||||
let constraints = aSubject.getConstraints();
|
||||
let contentWindow = Services.wm.getOuterWindowWithId(windowID);
|
||||
|
||||
contentWindow.navigator.mozGetUserMediaDevices(
|
||||
constraints,
|
||||
function (devices) {
|
||||
prompt(contentWindow, callID, constraints.audio,
|
||||
constraints.video || constraints.picture,
|
||||
devices);
|
||||
},
|
||||
function (error) {
|
||||
denyRequest(callID, error);
|
||||
});
|
||||
}
|
||||
|
||||
function prompt(aWindow, 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (audioDevices.length == 0 && videoDevices.length == 0) {
|
||||
denyRequest(aCallID);
|
||||
return;
|
||||
}
|
||||
|
||||
let params = {
|
||||
videoDevices: videoDevices,
|
||||
audioDevices: audioDevices,
|
||||
out: null
|
||||
};
|
||||
aWindow.openDialog("chrome://webapprt/content/getUserMediaDialog.xul", "",
|
||||
"chrome, dialog, modal", params).focus();
|
||||
|
||||
if (!params.out) {
|
||||
denyRequest(aCallID);
|
||||
return;
|
||||
}
|
||||
|
||||
let allowedDevices = Cc["@mozilla.org/supports-array;1"].
|
||||
createInstance(Ci.nsISupportsArray);
|
||||
let videoIndex = params.out.video;
|
||||
let audioIndex = params.out.audio;
|
||||
|
||||
if (videoIndex != -1) {
|
||||
allowedDevices.AppendElement(videoDevices[videoIndex]);
|
||||
}
|
||||
|
||||
if (audioIndex != -1) {
|
||||
allowedDevices.AppendElement(audioDevices[audioIndex]);
|
||||
}
|
||||
|
||||
if (allowedDevices.Count()) {
|
||||
Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow",
|
||||
aCallID);
|
||||
} else {
|
||||
denyRequest(aCallID);
|
||||
}
|
||||
}
|
||||
|
||||
function denyRequest(aCallID, aError) {
|
||||
let msg = null;
|
||||
if (aError) {
|
||||
msg = Cc["@mozilla.org/supports-string;1"].
|
||||
createInstance(Ci.nsISupportsString);
|
||||
msg.data = aError;
|
||||
}
|
||||
|
||||
Services.obs.notifyObservers(msg, "getUserMedia:response:deny", aCallID);
|
||||
}
|
||||
|
||||
Services.obs.addObserver(handleRequest, "getUserMedia:request", false);
|
38
webapprt/content/getUserMediaDialog.js
Normal file
38
webapprt/content/getUserMediaDialog.js
Normal file
@ -0,0 +1,38 @@
|
||||
/* 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/. */
|
||||
|
||||
function onOK() {
|
||||
window.arguments[0].out = {
|
||||
video: document.getElementById("video").selectedItem.value,
|
||||
audio: document.getElementById("audio").selectedItem.value
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function onLoad() {
|
||||
let videoDevices = window.arguments[0].videoDevices;
|
||||
if (videoDevices.length) {
|
||||
let videoMenu = document.getElementById("video");
|
||||
for (let i = 0; i < videoDevices.length; i++) {
|
||||
videoMenu.appendItem(videoDevices[i].name, i);
|
||||
}
|
||||
videoMenu.selectedIndex = 1;
|
||||
} else {
|
||||
document.getElementById("videoGroup").hidden = true;
|
||||
}
|
||||
|
||||
let audioDevices = window.arguments[0].audioDevices;
|
||||
if (audioDevices.length) {
|
||||
let audioMenu = document.getElementById("audio");
|
||||
for (let i = 0; i < audioDevices.length; i++) {
|
||||
audioMenu.appendItem(audioDevices[i].name, i);
|
||||
}
|
||||
audioMenu.selectedIndex = 1;
|
||||
} else {
|
||||
document.getElementById("audioGroup").hidden = true;
|
||||
}
|
||||
|
||||
window.sizeToContent();
|
||||
}
|
45
webapprt/content/getUserMediaDialog.xul
Normal file
45
webapprt/content/getUserMediaDialog.xul
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog [
|
||||
<!ENTITY % gum-askDTD SYSTEM "chrome://webapprt/locale/getUserMediaDialog.dtd">
|
||||
%gum-askDTD;
|
||||
]>
|
||||
|
||||
<dialog id="getUserMediaDialog" title="&getUserMediaDialog.title;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
buttons="accept,cancel"
|
||||
buttonlabelaccept="&getUserMediaDialog.buttonlabelaccept;"
|
||||
buttonaccesskeyaccept="&getUserMediaDialog.buttonaccesskeyaccept;"
|
||||
onload="onLoad()"
|
||||
ondialogaccept="return onOK()"
|
||||
buttonlabelcancel="&getUserMediaDialog.buttonlabelcancel;"
|
||||
buttonaccesskeycancel="&getUserMediaDialog.buttonaccesskeycancel;">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://webapprt/content/getUserMediaDialog.js"/>
|
||||
|
||||
<groupbox id="videoGroup" flex="1">
|
||||
<caption label="&getUserMediaDialog.video.label;"/>
|
||||
<menulist id="video">
|
||||
<menupopup>
|
||||
<menuitem label="&getUserMediaDialog.video.noVideo;" value="-1"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</groupbox>
|
||||
|
||||
<groupbox id="audioGroup" flex="1">
|
||||
<caption label="&getUserMediaDialog.audio.label;"/>
|
||||
<menulist id="audio">
|
||||
<menupopup>
|
||||
<menuitem label="&getUserMediaDialog.audio.noAudio;" value="-1"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</groupbox>
|
||||
|
||||
</dialog>
|
@ -6,6 +6,8 @@ webapprt.jar:
|
||||
% content webapprt %content/
|
||||
* content/webapp.js (content/webapp.js)
|
||||
* content/webapp.xul (content/webapp.xul)
|
||||
content/getUserMediaDialog.xul (content/getUserMediaDialog.xul)
|
||||
content/getUserMediaDialog.js (content/getUserMediaDialog.js)
|
||||
content/mochitest-shared.js (content/mochitest-shared.js)
|
||||
content/mochitest.js (content/mochitest.js)
|
||||
content/mochitest.xul (content/mochitest.xul)
|
||||
|
17
webapprt/locales/en-US/webapprt/getUserMediaDialog.dtd
Normal file
17
webapprt/locales/en-US/webapprt/getUserMediaDialog.dtd
Normal file
@ -0,0 +1,17 @@
|
||||
<!-- 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/. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE: These are localized strings for the getUserMedia dialog
|
||||
- to ask permissions in the webapp runtime. -->
|
||||
|
||||
<!ENTITY getUserMediaDialog.title "Media Sharing">
|
||||
<!ENTITY getUserMediaDialog.buttonlabelaccept "Share">
|
||||
<!ENTITY getUserMediaDialog.buttonaccesskeyaccept "S">
|
||||
<!ENTITY getUserMediaDialog.buttonlabelcancel "Cancel">
|
||||
<!ENTITY getUserMediaDialog.buttonaccesskeycancel "n">
|
||||
|
||||
<!ENTITY getUserMediaDialog.video.label "Select camera">
|
||||
<!ENTITY getUserMediaDialog.video.noVideo "No video">
|
||||
<!ENTITY getUserMediaDialog.audio.label "Select microphone">
|
||||
<!ENTITY getUserMediaDialog.audio.noAudio "No audio">
|
@ -7,5 +7,6 @@
|
||||
% locale webapprt @AB_CD@ %locale/webapprt/
|
||||
locale/webapprt/webapp.dtd (%webapprt/webapp.dtd)
|
||||
locale/webapprt/webapp.properties (%webapprt/webapp.properties)
|
||||
locale/webapprt/getUserMediaDialog.dtd (%webapprt/getUserMediaDialog.dtd)
|
||||
|
||||
% locale branding @AB_CD@ resource://webappbranding/
|
||||
|
@ -24,6 +24,7 @@ EXTRA_COMPONENTS += [
|
||||
EXTRA_JS_MODULES += [
|
||||
'RemoteDebugger.jsm',
|
||||
'Startup.jsm',
|
||||
'WebRTCHandler.jsm',
|
||||
'WebappRT.jsm',
|
||||
'WebappsHandler.jsm',
|
||||
]
|
||||
|
38
webapprt/test/chrome/browser_getUserMedia.js
Normal file
38
webapprt/test/chrome/browser_getUserMedia.js
Normal file
@ -0,0 +1,38 @@
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let openedWindows = 0;
|
||||
|
||||
let winObserver = function(win, topic) {
|
||||
if (topic == "domwindowopened") {
|
||||
win.addEventListener("load", function onLoadWindow() {
|
||||
win.removeEventListener("load", onLoadWindow, false);
|
||||
openedWindows++;
|
||||
if (openedWindows == 2) {
|
||||
win.close();
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
|
||||
Services.ww.registerNotification(winObserver);
|
||||
|
||||
let mutObserver = null;
|
||||
|
||||
loadWebapp("getUserMedia.webapp", undefined, function onLoad() {
|
||||
let msg = gAppBrowser.contentDocument.getElementById("msg");
|
||||
mutObserver = new MutationObserver(function(mutations) {
|
||||
is(msg.textContent, "PERMISSION_DENIED", "getUserMedia permission denied.");
|
||||
is(openedWindows, 2, "Prompt shown.");
|
||||
finish();
|
||||
});
|
||||
mutObserver.observe(msg, { childList: true });
|
||||
});
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.ww.unregisterNotification(winObserver);
|
||||
mutObserver.disconnect();
|
||||
});
|
||||
}
|
21
webapprt/test/chrome/getUserMedia.html
Normal file
21
webapprt/test/chrome/getUserMedia.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>getUserMedia Test App</title>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<span id="msg"></span>
|
||||
<script>
|
||||
navigator.mozGetUserMedia({ video: true, audio: true },
|
||||
function(localMediaStream) {
|
||||
document.getElementById("msg").textContent = window.URL.createObjectURL(localMediaStream);
|
||||
},
|
||||
|
||||
function(err) {
|
||||
document.getElementById("msg").textContent = err;
|
||||
});
|
||||
</script>
|
||||
<h1>getUserMedia Test App</h1>
|
||||
</body>
|
||||
</html>
|
5
webapprt/test/chrome/getUserMedia.webapp
Normal file
5
webapprt/test/chrome/getUserMedia.webapp
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "getUserMedia Test App",
|
||||
"description": "an app for testing getUserMedia",
|
||||
"launch_path": "/webapprtChrome/webapprt/test/chrome/getUserMedia.html"
|
||||
}
|
1
webapprt/test/chrome/getUserMedia.webapp^headers^
Normal file
1
webapprt/test/chrome/getUserMedia.webapp^headers^
Normal file
@ -0,0 +1 @@
|
||||
Content-Type: application/x-web-app-manifest+json
|
@ -26,6 +26,9 @@ support-files =
|
||||
mozpay.webapp^headers^
|
||||
mozpay.html
|
||||
mozpay-success.html
|
||||
getUserMedia.webapp
|
||||
getUserMedia.webapp^headers^
|
||||
getUserMedia.html
|
||||
|
||||
|
||||
[browser_sample.js]
|
||||
@ -36,3 +39,5 @@ support-files =
|
||||
[browser_geolocation-prompt-noperm.js]
|
||||
[browser_debugger.js]
|
||||
[browser_mozpay.js]
|
||||
[browser_getUserMedia.js]
|
||||
skip-if = true
|
||||
|
Loading…
Reference in New Issue
Block a user