browser(firefox): add screencast control methods to context (#3530)

This commit is contained in:
Yury Semikhatsky 2020-08-19 12:43:53 -07:00 committed by GitHub
parent 745dc339a6
commit 73cd6ecef3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 13 deletions

View File

@ -1,2 +1,2 @@
1160
Changed: lushnikov@chromium.org Thu Aug 13 23:10:17 PDT 2020
1161
Changed: yurys@chromium.org Wed Aug 19 11:51:52 PDT 2020

View File

@ -198,7 +198,7 @@ class TargetRegistry {
setViewportSizeForBrowser(browserContext.defaultViewportSize, tab.linkedBrowser, window);
};
const onTabCloseListener = event => {
const onTabCloseListener = async event => {
const tab = event.target;
const linkedBrowser = tab.linkedBrowser;
const target = this._browserToTarget.get(linkedBrowser);
@ -497,6 +497,7 @@ class BrowserContext {
this.ignoreHTTPSErrors = undefined;
this.downloadOptions = undefined;
this.defaultViewportSize = undefined;
this.screencastOptions = undefined;
this.scriptsToEvaluateOnNewDocument = [];
this.bindings = [];
this.settings = {};
@ -684,6 +685,10 @@ class BrowserContext {
}
return result;
}
setScreencastOptions(options) {
this.screencastOptions = options;
}
}
function dirPath(path) {

View File

@ -64,11 +64,11 @@ class BrowserHandler {
this._createdBrowserContextIds.delete(browserContextId);
}
dispose() {
async dispose() {
helper.removeListeners(this._eventListeners);
for (const [target, session] of this._attachedSessions) {
target.disconnectSession(session);
this._dispatcher.destroySession(session);
await this._dispatcher.destroySession(session);
}
this._attachedSessions.clear();
for (const browserContextId of this._createdBrowserContextIds) {
@ -99,12 +99,12 @@ class BrowserHandler {
sessions.push(session);
}
_onTargetDestroyed(target) {
async _onTargetDestroyed(target) {
const session = this._attachedSessions.get(target);
if (!session)
return;
this._attachedSessions.delete(target);
this._dispatcher.destroySession(session);
await this._dispatcher.destroySession(session);
this._session.emitEvent('Browser.detachedFromTarget', {
sessionId: session.sessionId(),
targetId: target.id(),
@ -184,6 +184,10 @@ class BrowserHandler {
await this._targetRegistry.browserContextForId(browserContextId).applySetting('colorScheme', nullToUndefined(colorScheme));
}
async setScreencastOptions({browserContextId, dir, width, height, scale}) {
await this._targetRegistry.browserContextForId(browserContextId).setScreencastOptions({dir, width, height, scale});
}
async setUserAgentOverride({browserContextId, userAgent}) {
await this._targetRegistry.browserContextForId(browserContextId).applySetting('userAgent', nullToUndefined(userAgent));
}

View File

@ -29,9 +29,9 @@ class Dispatcher {
return session;
}
destroySession(session) {
session.dispose();
async destroySession(session) {
this._sessions.delete(session.sessionId());
await session.dispose();
}
_dispose() {
@ -108,13 +108,15 @@ class ProtocolSession {
this._handlers.set(domainName, handler);
}
dispose() {
async dispose() {
const promises = [];
for (const [domainName, handler] of this._handlers) {
if (typeof handler.dispose !== 'function')
throw new Error(`Handler for "${domainName}" domain does not define |dispose| method!`);
handler.dispose();
promises.push(handler.dispose());
}
this._handlers.clear();
await Promise.all(promises);
this._dispatcher = null;
}

View File

@ -6,6 +6,7 @@
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -132,13 +133,19 @@ class PageHandler {
this._session.emitEvent('Page.crashed', {});
}),
]);
const options = this._pageTarget.browserContext().screencastOptions;
if (options) {
const file = OS.Path.join(options.dir, helper.generateId() + '.webm');
await this.startVideoRecording(Object.assign({file}, options));
}
}
dispose() {
async dispose() {
this._contentPage.dispose();
helper.removeListeners(this._eventListeners);
if (this._videoSessionId !== -1)
this.stopVideoRecording().catch(e => dump(`stopVideoRecording failed:\n${e}\n`));
await this.stopVideoRecording().catch(e => dump(`stopVideoRecording failed:\n${e}\n`));
}
async setViewportSize({viewportSize}) {
@ -304,6 +311,7 @@ class PageHandler {
const rect = this._pageTarget.linkedBrowser().getBoundingClientRect();
const devicePixelRatio = this._pageTarget._window.devicePixelRatio;
this._videoSessionId = screencast.startVideoRecording(docShell, file, width, height, scale || 0, devicePixelRatio * rect.top);
this._session.emitEvent('Page.screencastStarted', {uid: '' + this._videoSessionId, file});
}
async stopVideoRecording() {
@ -312,6 +320,7 @@ class PageHandler {
const videoSessionId = this._videoSessionId;
this._videoSessionId = -1;
const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
const session = this._session;
const result = new Promise(resolve =>
Services.obs.addObserver(function onStopped(subject, topic, data) {
if (videoSessionId != data)
@ -319,6 +328,8 @@ class PageHandler {
Services.obs.removeObserver(onStopped, 'juggler-screencast-stopped');
resolve();
session.emitEvent('Page.screencastStopped', {uid: '' + videoSessionId});
}, 'juggler-screencast-stopped')
);
screencast.stopVideoRecording(videoSessionId);

View File

@ -407,6 +407,15 @@ const Browser = {
colorScheme: t.Nullable(t.Enum(['dark', 'light', 'no-preference'])),
},
},
'setScreencastOptions': {
params: {
browserContextId: t.Optional(t.String),
dir: t.String,
width: t.Number,
height: t.Number,
scale: t.Optional(t.Number),
},
},
},
};
@ -640,6 +649,13 @@ const Page = {
workerId: t.String,
message: t.String,
},
'screencastStarted': {
uid: t.String,
file: t.String,
},
'screencastStopped': {
uid: t.String,
},
},
methods: {