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 1161
Changed: lushnikov@chromium.org Thu Aug 13 23:10:17 PDT 2020 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); setViewportSizeForBrowser(browserContext.defaultViewportSize, tab.linkedBrowser, window);
}; };
const onTabCloseListener = event => { const onTabCloseListener = async event => {
const tab = event.target; const tab = event.target;
const linkedBrowser = tab.linkedBrowser; const linkedBrowser = tab.linkedBrowser;
const target = this._browserToTarget.get(linkedBrowser); const target = this._browserToTarget.get(linkedBrowser);
@ -497,6 +497,7 @@ class BrowserContext {
this.ignoreHTTPSErrors = undefined; this.ignoreHTTPSErrors = undefined;
this.downloadOptions = undefined; this.downloadOptions = undefined;
this.defaultViewportSize = undefined; this.defaultViewportSize = undefined;
this.screencastOptions = undefined;
this.scriptsToEvaluateOnNewDocument = []; this.scriptsToEvaluateOnNewDocument = [];
this.bindings = []; this.bindings = [];
this.settings = {}; this.settings = {};
@ -684,6 +685,10 @@ class BrowserContext {
} }
return result; return result;
} }
setScreencastOptions(options) {
this.screencastOptions = options;
}
} }
function dirPath(path) { function dirPath(path) {

View File

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

View File

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

View File

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

View File

@ -407,6 +407,15 @@ const Browser = {
colorScheme: t.Nullable(t.Enum(['dark', 'light', 'no-preference'])), 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, workerId: t.String,
message: t.String, message: t.String,
}, },
'screencastStarted': {
uid: t.String,
file: t.String,
},
'screencastStopped': {
uid: t.String,
},
}, },
methods: { methods: {