Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/power/vscode-node/powerStateLogger.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as vscode from 'vscode';
7
import { ILogService } from '../../../platform/log/common/logService';
8
import { Disposable } from '../../../util/vs/base/common/lifecycle';
9
import { IExtensionContribution } from '../../common/contributions';
10
11
/**
12
* Logs the initial power state and power state change events to the output channel.
13
* Monitors vscode.env.power for battery status, thermal state, suspend/resume, and power-saving modes.
14
*/
15
export class PowerStateLogger extends Disposable implements IExtensionContribution {
16
readonly id = 'powerStateLogger';
17
18
private _manualBlocker: vscode.env.power.PowerSaveBlocker | undefined;
19
20
constructor(
21
@ILogService private readonly logService: ILogService,
22
) {
23
super();
24
25
// Register toggle power save blocker command
26
this._register(vscode.commands.registerCommand('github.copilot.debug.togglePowerSaveBlocker', async () => {
27
const isActive = await this._toggleManualPowerSaveBlocker();
28
vscode.window.showInformationMessage(isActive ? 'Power save blocker is now active' : 'Power save blocker is now inactive');
29
}));
30
31
// Log initial power state
32
this.logInitialPowerState();
33
34
// Listen for system suspend/resume events
35
this._register(vscode.env.power.onDidSuspend(() => {
36
this.logService.debug('[Power] System is suspending (going to sleep)');
37
}));
38
39
this._register(vscode.env.power.onDidResume(() => {
40
this.logService.debug('[Power] System is resuming from sleep');
41
}));
42
43
// Listen for battery power state changes
44
this._register(vscode.env.power.onDidChangeOnBatteryPower(onBattery => {
45
this.logService.debug(`[Power] Battery power state changed: ${onBattery ? 'on battery' : 'on AC power'}`);
46
}));
47
48
// Listen for thermal state changes (macOS only)
49
this._register(vscode.env.power.onDidChangeThermalState(thermalState => {
50
this.logService.debug(`[Power] Thermal state changed: ${thermalState}`);
51
}));
52
53
// Listen for CPU speed limit changes
54
this._register(vscode.env.power.onDidChangeSpeedLimit(speedLimit => {
55
this.logService.debug(`[Power] CPU speed limit changed: ${speedLimit}% ${speedLimit < 100 ? '(throttled)' : ''}`);
56
}));
57
58
// Listen for shutdown events
59
this._register(vscode.env.power.onWillShutdown(() => {
60
this.logService.debug('[Power] System is about to shut down or reboot');
61
}));
62
63
// Listen for screen lock/unlock events
64
this._register(vscode.env.power.onDidLockScreen(() => {
65
this.logService.debug('[Power] Screen is being locked');
66
}));
67
68
this._register(vscode.env.power.onDidUnlockScreen(() => {
69
this.logService.debug('[Power] Screen has been unlocked');
70
}));
71
}
72
73
private async logInitialPowerState(): Promise<void> {
74
try {
75
const [onBattery, thermalState, idleTime] = await Promise.all([
76
vscode.env.power.isOnBatteryPower(),
77
vscode.env.power.getCurrentThermalState(),
78
vscode.env.power.getSystemIdleTime()
79
]);
80
81
this.logService.debug(`[Power] Initial power state: ${onBattery ? 'on battery' : 'on AC power'}, thermal state: ${thermalState}, system idle time: ${idleTime}s`);
82
} catch (error) {
83
this.logService.debug(`[Power] Failed to retrieve initial power state: ${error}`);
84
}
85
}
86
87
private async _toggleManualPowerSaveBlocker(): Promise<boolean> {
88
if (this._manualBlocker) {
89
this.logService.debug(`[Power] Stopping manual power save blocker, id: ${this._manualBlocker.id}`);
90
this._manualBlocker.dispose();
91
this._manualBlocker = undefined;
92
return false;
93
}
94
95
try {
96
// Check if the API is available (proposed API, desktop only)
97
if (typeof vscode.env.power?.startPowerSaveBlocker !== 'function') {
98
this.logService.debug('[Power] Power save blocker API not available');
99
return false;
100
}
101
102
this._manualBlocker = await vscode.env.power.startPowerSaveBlocker('prevent-app-suspension');
103
this.logService.debug(`[Power] Started manual power save blocker, id: ${this._manualBlocker.id}`);
104
return true;
105
} catch (err) {
106
this.logService.warn(`[Power] Failed to start manual power save blocker: ${err}`);
107
return false;
108
}
109
}
110
111
override dispose(): void {
112
if (this._manualBlocker) {
113
this._manualBlocker.dispose();
114
this._manualBlocker = undefined;
115
}
116
super.dispose();
117
}
118
}
119
120