Bug 1756245 - Migrate GeckoViewMedia to actor. r=owlish

Differential Revision: https://phabricator.services.mozilla.com/D141688
This commit is contained in:
Agi Sferro 2022-05-16 21:52:53 +00:00
Родитель d16fbd366d
Коммит fffdc8a3ab
6 изменённых файлов: 90 добавлений и 127 удалений

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

@ -35,6 +35,13 @@ class GeckoViewPermissionChild extends GeckoViewActorChild {
return this.sendQuery("GetAppPermissions", aPermissions);
}
mediaRecordingStatusChanged(aDevices) {
return this.eventDispatcher.sendRequest({
type: "GeckoView:MediaRecordingStatusChanged",
devices: aDevices,
});
}
async promptPermission(aRequest) {
// Only allow exactly one permission request here.
const types = aRequest.types.QueryInterface(Ci.nsIArray);

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

@ -12,8 +12,27 @@ const { GeckoViewUtils } = ChromeUtils.import(
"resource://gre/modules/GeckoViewUtils.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyServiceGetter(
this,
"MediaManagerService",
"@mozilla.org/mediaManagerService;1",
"nsIMediaManagerService"
);
const STATUS_RECORDING = "recording";
const STATUS_INACTIVE = "inactive";
const TYPE_CAMERA = "camera";
const TYPE_MICROPHONE = "microphone";
class GeckoViewPermissionProcessChild extends JSProcessActorChild {
getActor(window) {
return window.windowGlobalChild.getActor("GeckoViewPermission");
}
/* ---------- nsIObserver ---------- */
async observe(aSubject, aTopic, aData) {
switch (aTopic) {
@ -45,9 +64,62 @@ class GeckoViewPermissionProcessChild extends JSProcessActorChild {
);
break;
}
case "recording-device-events": {
this.handleRecordingDeviceEvents(aSubject);
break;
}
}
}
handleRecordingDeviceEvents(aRequest) {
aRequest.QueryInterface(Ci.nsIPropertyBag2);
const contentWindow = aRequest.getProperty("window");
const devices = [];
const getStatusString = function(activityStatus) {
switch (activityStatus) {
case MediaManagerService.STATE_CAPTURE_ENABLED:
case MediaManagerService.STATE_CAPTURE_DISABLED:
return STATUS_RECORDING;
case MediaManagerService.STATE_NOCAPTURE:
return STATUS_INACTIVE;
default:
throw new Error("Unexpected activityStatus value");
}
};
const hasCamera = {};
const hasMicrophone = {};
const screen = {};
const window = {};
const browser = {};
const mediaDevices = {};
MediaManagerService.mediaCaptureWindowState(
contentWindow,
hasCamera,
hasMicrophone,
screen,
window,
browser,
mediaDevices
);
var cameraStatus = getStatusString(hasCamera.value);
var microphoneStatus = getStatusString(hasMicrophone.value);
if (hasCamera.value != MediaManagerService.STATE_NOCAPTURE) {
devices.push({
type: TYPE_CAMERA,
status: cameraStatus,
});
}
if (hasMicrophone.value != MediaManagerService.STATE_NOCAPTURE) {
devices.push({
type: TYPE_MICROPHONE,
status: microphoneStatus,
});
}
this.getActor(contentWindow).mediaRecordingStatusChanged(devices);
}
async handleMediaRequest(aRequest) {
const constraints = aRequest.getConstraints();
const { devices, windowID } = aRequest;
@ -84,17 +156,15 @@ class GeckoViewPermissionProcessChild extends JSProcessActorChild {
return null;
}
const response = await window.windowGlobalChild
.getActor("GeckoViewPermission")
.getMediaPermission({
uri: window.document.documentURI,
video: constraints.video
? sources.filter(source => source.type === "videoinput")
: null,
audio: constraints.audio
? sources.filter(source => source.type === "audioinput")
: null,
});
const response = await this.getActor(window).getMediaPermission({
uri: window.document.documentURI,
video: constraints.video
? sources.filter(source => source.type === "videoinput")
: null,
audio: constraints.audio
? sources.filter(source => source.type === "audioinput")
: null,
});
if (!response) {
// Rejected.
@ -110,9 +180,7 @@ class GeckoViewPermissionProcessChild extends JSProcessActorChild {
Cu.reportError("Media device error: invalid video id");
return null;
}
await window.windowGlobalChild
.getActor("GeckoViewPermission")
.addCameraPermission();
await this.getActor(window).addCameraPermission();
allowedDevices.appendElement(video);
}
if (constraints.audio) {

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

@ -39,6 +39,7 @@ const JSPROCESSACTORS = {
observers: [
"getUserMedia:ask-device-permission",
"getUserMedia:request",
"recording-device-events",
"PeerConnection:request",
],
},
@ -99,12 +100,6 @@ class GeckoViewStartup {
switch (aTopic) {
case "content-process-ready-for-script":
case "app-startup": {
// Parent and content process.
GeckoViewUtils.addLazyGetter(this, "GeckoViewRecordingMedia", {
module: "resource://gre/modules/GeckoViewMedia.jsm",
observers: ["recording-device-events"],
});
GeckoViewUtils.addLazyGetter(this, "GeckoViewConsole", {
module: "resource://gre/modules/GeckoViewConsole.jsm",
});

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

@ -148,9 +148,6 @@ class MediaDelegateXOriginTest : BaseSessionTest() {
}
@Test fun testDeviceRecordingEventAudioAndVideoInXOriginIframe() {
// TODO: Bug 1648153
assumeThat(sessionRule.env.isFission, Matchers.equalTo(false))
// TODO: needs bug 1700243
assumeThat(sessionRule.env.isIsolatedProcess, Matchers.equalTo(false))
@ -166,9 +163,6 @@ class MediaDelegateXOriginTest : BaseSessionTest() {
}
@Test fun testDeviceRecordingEventAudioAndVideoInXOriginIframeNoAllow() {
// TODO: Bug 1648153
assumeThat(sessionRule.env.isFission, Matchers.equalTo(false))
mainSession.loadTestPath(GETUSERMEDIA_XORIGIN_CONTAINER_HTML_PATH)
mainSession.waitForPageStop()

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

@ -1,100 +0,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/. */
"use strict";
var EXPORTED_SYMBOLS = ["GeckoViewRecordingMedia"];
const { GeckoViewUtils } = ChromeUtils.import(
"resource://gre/modules/GeckoViewUtils.jsm"
);
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyServiceGetter(
this,
"MediaManagerService",
"@mozilla.org/mediaManagerService;1",
"nsIMediaManagerService"
);
const STATUS_RECORDING = "recording";
const STATUS_INACTIVE = "inactive";
const TYPE_CAMERA = "camera";
const TYPE_MICROPHONE = "microphone";
const GeckoViewRecordingMedia = {
// The event listener for this is hooked up in GeckoViewStartup.jsm
observe(aSubject, aTopic, aData) {
debug`observe: aTopic=${aTopic}`;
switch (aTopic) {
case "recording-device-events": {
this.handleRecordingDeviceEvents();
break;
}
}
},
handleRecordingDeviceEvents() {
const [dispatcher] = GeckoViewUtils.getActiveDispatcherAndWindow();
if (dispatcher) {
const windows = MediaManagerService.activeMediaCaptureWindows;
const devices = [];
const getStatusString = function(activityStatus) {
switch (activityStatus) {
case MediaManagerService.STATE_CAPTURE_ENABLED:
case MediaManagerService.STATE_CAPTURE_DISABLED:
return STATUS_RECORDING;
case MediaManagerService.STATE_NOCAPTURE:
return STATUS_INACTIVE;
default:
throw new Error("Unexpected activityStatus value");
}
};
for (let i = 0; i < windows.length; i++) {
const win = windows.queryElementAt(i, Ci.nsIDOMWindow);
const hasCamera = {};
const hasMicrophone = {};
const screen = {};
const window = {};
const browser = {};
const mediaDevices = {};
MediaManagerService.mediaCaptureWindowState(
win,
hasCamera,
hasMicrophone,
screen,
window,
browser,
mediaDevices
);
var cameraStatus = getStatusString(hasCamera.value);
var microphoneStatus = getStatusString(hasMicrophone.value);
if (hasCamera.value != MediaManagerService.STATE_NOCAPTURE) {
devices.push({
type: TYPE_CAMERA,
status: cameraStatus,
});
}
if (hasMicrophone.value != MediaManagerService.STATE_NOCAPTURE) {
devices.push({
type: TYPE_MICROPHONE,
status: microphoneStatus,
});
}
}
dispatcher.sendRequestForResult({
type: "GeckoView:MediaRecordingStatusChanged",
devices,
});
} else {
console.log("no dispatcher present");
}
},
};
const { debug, warn } = GeckoViewUtils.initLogging("GeckoViewMedia");

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

@ -18,7 +18,6 @@ EXTRA_JS_MODULES += [
"GeckoViewConsole.jsm",
"GeckoViewContent.jsm",
"GeckoViewContentBlocking.jsm",
"GeckoViewMedia.jsm",
"GeckoViewMediaControl.jsm",
"GeckoViewModule.jsm",
"GeckoViewNavigation.jsm",