Prevent display sleep while on a call

This commit is contained in:
Evan Hahn 2021-12-10 16:53:10 -06:00 committed by GitHub
parent 34fd945f83
commit 0e3d12c457
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 152 additions and 0 deletions

View file

@ -0,0 +1,40 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { PowerSaveBlocker } from 'electron';
import * as log from '../ts/logging/log';
export class PreventDisplaySleepService {
private blockerId: undefined | number;
constructor(private powerSaveBlocker: PowerSaveBlocker) {}
setEnabled(isEnabled: boolean): void {
log.info(
`Prevent display sleep service: ${
isEnabled ? 'preventing' : 'allowing'
} display sleep`
);
if (isEnabled) {
this.enable();
} else {
this.disable();
}
}
private enable(): void {
if (this.blockerId !== undefined) {
return;
}
this.blockerId = this.powerSaveBlocker.start('prevent-display-sleep');
}
private disable(): void {
if (this.blockerId === undefined) {
return;
}
this.powerSaveBlocker.stop(this.blockerId);
delete this.blockerId;
}
}

View file

@ -19,6 +19,7 @@ import {
dialog,
ipcMain as ipc,
Menu,
powerSaveBlocker,
protocol as electronProtocol,
screen,
shell,
@ -54,6 +55,7 @@ import * as attachments from './attachments';
import * as attachmentChannel from './attachment_channel';
import * as bounce from '../ts/services/bounce';
import * as updater from '../ts/updater/index';
import { PreventDisplaySleepService } from './PreventDisplaySleepService';
import { SystemTrayService } from './SystemTrayService';
import { SystemTraySettingCache } from './SystemTraySettingCache';
import {
@ -120,6 +122,10 @@ const enableCI = config.get<boolean>('enableCI');
const sql = new MainSQL();
const heicConverter = getHeicConverter();
const preventDisplaySleepService = new PreventDisplaySleepService(
powerSaveBlocker
);
let systemTrayService: SystemTrayService | undefined;
const systemTraySettingCache = new SystemTraySettingCache(
sql,
@ -761,6 +767,8 @@ ipc.on('title-bar-double-click', () => {
});
ipc.on('set-is-call-active', (_event, isCallActive) => {
preventDisplaySleepService.setEnabled(isCallActive);
if (!mainWindow) {
return;
}

View file

@ -0,0 +1,104 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import * as sinon from 'sinon';
import type { PowerSaveBlocker } from 'electron';
import { PreventDisplaySleepService } from '../../../app/PreventDisplaySleepService';
describe('PreventDisplaySleepService', () => {
class FakePowerSaveBlocker implements PowerSaveBlocker {
private nextId = 0;
private idsStarted = new Set<number>();
isStarted(id: number): boolean {
return this.idsStarted.has(id);
}
start(type: 'prevent-app-suspension' | 'prevent-display-sleep'): number {
assert.strictEqual(type, 'prevent-display-sleep');
const result = this.nextId;
this.nextId += 1;
this.idsStarted.add(result);
return result;
}
stop(id: number): void {
assert(this.idsStarted.has(id), `${id} was never started`);
this.idsStarted.delete(id);
}
// This is only for testing.
_idCount(): number {
return this.idsStarted.size;
}
}
let sandbox: sinon.SinonSandbox;
let powerSaveBlocker: FakePowerSaveBlocker;
let service: PreventDisplaySleepService;
beforeEach(() => {
sandbox = sinon.createSandbox();
powerSaveBlocker = new FakePowerSaveBlocker();
service = new PreventDisplaySleepService(powerSaveBlocker);
});
afterEach(() => {
sandbox.restore();
});
it('does nothing if disabling when it was already disabled', () => {
const startStub = sandbox.stub(powerSaveBlocker, 'start');
const stopStub = sandbox.stub(powerSaveBlocker, 'stop');
service.setEnabled(false);
assert.strictEqual(powerSaveBlocker._idCount(), 0);
sinon.assert.notCalled(startStub);
sinon.assert.notCalled(stopStub);
});
it('can start power blocking', () => {
service.setEnabled(true);
assert.strictEqual(powerSaveBlocker._idCount(), 1);
});
it('only starts power blocking once', () => {
service.setEnabled(true);
service.setEnabled(true);
service.setEnabled(true);
assert.strictEqual(powerSaveBlocker._idCount(), 1);
});
it('can start and stop power blocking', () => {
const startSpy = sandbox.spy(powerSaveBlocker, 'start');
const stopStub = sandbox.spy(powerSaveBlocker, 'stop');
service.setEnabled(true);
service.setEnabled(false);
assert.strictEqual(powerSaveBlocker._idCount(), 0);
sinon.assert.calledOnce(startSpy);
sinon.assert.calledOnce(stopStub);
});
it('can toggle power blocking several times', () => {
const startSpy = sandbox.spy(powerSaveBlocker, 'start');
const stopStub = sandbox.spy(powerSaveBlocker, 'stop');
service.setEnabled(true);
service.setEnabled(false);
service.setEnabled(true);
service.setEnabled(false);
service.setEnabled(true);
assert.strictEqual(powerSaveBlocker._idCount(), 1);
sinon.assert.calledThrice(startSpy);
sinon.assert.calledTwice(stopStub);
});
});