screencastService: Promisify Recorder start/stopRecording functions

This will allow for cleaner error handling in the following commits.

A benefit we get from it right now is having one less callback when
calling startRecording/stopRecording().

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2197>
This commit is contained in:
Jonas Dreßler 2022-02-03 11:10:36 +01:00
parent 9711a918e7
commit 9eea48536a

View File

@ -114,12 +114,12 @@ var Recorder = class {
_notifyStopped() { _notifyStopped() {
this._unwatchSender(); this._unwatchSender();
if (this._onStartedCallback) if (this._startRequest)
this._onStartedCallback(this, false); this._startRequest.reject(new Error());
else if (this._onStoppedCallback) else if (this._stopRequest)
this._onStoppedCallback(this); this._stopRequest.resolve();
else else
this._onErrorCallback(this); this._onErrorCallback();
} }
_onSessionClosed() { _onSessionClosed() {
@ -151,38 +151,46 @@ var Recorder = class {
this._pipeline.set_state(Gst.State.PLAYING); this._pipeline.set_state(Gst.State.PLAYING);
this._pipelineState = PipelineState.PLAYING; this._pipelineState = PipelineState.PLAYING;
this._onStartedCallback(this, true); this._startRequest.resolve();
this._onStartedCallback = null; delete this._startRequest;
} }
startRecording(onStartedCallback) { startRecording() {
this._onStartedCallback = onStartedCallback; return new Promise((resolve, reject) => {
this._startRequest = {resolve, reject};
const [streamPath] = this._sessionProxy.RecordAreaSync( const [streamPath] = this._sessionProxy.RecordAreaSync(
this._x, this._y, this._x, this._y,
this._width, this._height, this._width, this._height,
{ {
'is-recording': GLib.Variant.new('b', true), 'is-recording': GLib.Variant.new('b', true),
'cursor-mode': GLib.Variant.new('u', this._drawCursor ? 1 : 0), 'cursor-mode': GLib.Variant.new('u', this._drawCursor ? 1 : 0),
}); });
this._streamProxy = new ScreenCastStreamProxy(Gio.DBus.session, this._streamProxy = new ScreenCastStreamProxy(Gio.DBus.session,
'org.gnome.ScreenCast.Stream', 'org.gnome.ScreenCast.Stream',
streamPath); streamPath);
this._streamProxy.connectSignal('PipeWireStreamAdded', this._streamProxy.connectSignal('PipeWireStreamAdded',
(proxy, sender, params) => { (_proxy, _sender, params) => {
const [nodeId] = params; const [nodeId] = params;
this._startPipeline(nodeId); this._startPipeline(nodeId);
}); });
this._sessionProxy.StartSync(); this._sessionProxy.StartSync();
this._sessionState = SessionState.ACTIVE; this._sessionState = SessionState.ACTIVE;
});
} }
stopRecording(onStoppedCallback) { stopRecording() {
this._pipelineState = PipelineState.FLUSHING; if (this._startRequest)
this._onStoppedCallback = onStoppedCallback; return Promise.reject(new Error('Unable to stop recorder while still starting'));
this._pipeline.send_event(Gst.Event.new_eos());
return new Promise((resolve, reject) => {
this._stopRequest = {resolve, reject};
this._pipelineState = PipelineState.FLUSHING;
this._pipeline.send_event(Gst.Event.new_eos());
});
} }
_stopSession() { _stopSession() {
@ -366,7 +374,7 @@ var ScreencastService = class extends ServiceImplementation {
return this._getAbsolutePath(filename); return this._getAbsolutePath(filename);
} }
ScreencastAsync(params, invocation) { async ScreencastAsync(params, invocation) {
let returnValue = [false, '']; let returnValue = [false, ''];
if (this._lockdownSettings.get_boolean('disable-save-to-disk')) { if (this._lockdownSettings.get_boolean('disable-save-to-disk')) {
@ -397,7 +405,7 @@ var ScreencastService = class extends ServiceImplementation {
filePath, filePath,
options, options,
invocation, invocation,
_recorder => this._removeRecorder(sender)); () => this._removeRecorder(sender));
} catch (error) { } catch (error) {
log(`Failed to create recorder: ${error.message}`); log(`Failed to create recorder: ${error.message}`);
invocation.return_value(GLib.Variant.new('(bs)', returnValue)); invocation.return_value(GLib.Variant.new('(bs)', returnValue));
@ -407,24 +415,17 @@ var ScreencastService = class extends ServiceImplementation {
this._addRecorder(sender, recorder); this._addRecorder(sender, recorder);
try { try {
recorder.startRecording( await recorder.startRecording();
(_, result) => { returnValue = [true, filePath];
if (result) {
returnValue = [true, filePath];
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} else {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
});
} catch (error) { } catch (error) {
log(`Failed to start recorder: ${error.message}`); log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender); this._removeRecorder(sender);
} finally {
invocation.return_value(GLib.Variant.new('(bs)', returnValue)); invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} }
} }
ScreencastAreaAsync(params, invocation) { async ScreencastAreaAsync(params, invocation) {
let returnValue = [false, '']; let returnValue = [false, ''];
if (this._lockdownSettings.get_boolean('disable-save-to-disk')) { if (this._lockdownSettings.get_boolean('disable-save-to-disk')) {
@ -454,7 +455,7 @@ var ScreencastService = class extends ServiceImplementation {
filePath, filePath,
options, options,
invocation, invocation,
_recorder => this._removeRecorder(sender)); () => this._removeRecorder(sender));
} catch (error) { } catch (error) {
log(`Failed to create recorder: ${error.message}`); log(`Failed to create recorder: ${error.message}`);
invocation.return_value(GLib.Variant.new('(bs)', returnValue)); invocation.return_value(GLib.Variant.new('(bs)', returnValue));
@ -464,24 +465,17 @@ var ScreencastService = class extends ServiceImplementation {
this._addRecorder(sender, recorder); this._addRecorder(sender, recorder);
try { try {
recorder.startRecording( await recorder.startRecording();
(_, result) => { returnValue = [true, filePath];
if (result) {
returnValue = [true, filePath];
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} else {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
});
} catch (error) { } catch (error) {
log(`Failed to start recorder: ${error.message}`); log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender); this._removeRecorder(sender);
} finally {
invocation.return_value(GLib.Variant.new('(bs)', returnValue)); invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} }
} }
StopScreencastAsync(params, invocation) { async StopScreencastAsync(params, invocation) {
const sender = invocation.get_sender(); const sender = invocation.get_sender();
const recorder = this._recorders.get(sender); const recorder = this._recorders.get(sender);
@ -490,9 +484,13 @@ var ScreencastService = class extends ServiceImplementation {
return; return;
} }
recorder.stopRecording(() => { try {
await recorder.stopRecording();
} catch (error) {
log(`${sender}: Error while stopping recorder: ${error.message}`);
} finally {
this._removeRecorder(sender); this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(b)', [true])); invocation.return_value(GLib.Variant.new('(b)', [true]));
}); }
} }
}; };