blob: 83127496483cb41ae9289a90ab6f4ef16b9748fa [file] [log] [blame] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as vscode from 'vscode';
import {isChromiumosRoot} from '../common/chromiumos/fs';
import {hints} from '../services/config';
import * as sudo from '../services/sudo';
import {Metrics} from './metrics/metrics';
/**
* Activates the hint handlers.
*
* When adding hints on user actions, instead of embedding hint logic into
* individual modules, you can provide event emitters there and subscribe
* to them here, by which you can decouple hint logic and individual modules.
*/
export function activate(context: vscode.ExtensionContext): void {
context.subscriptions.push(
sudo.onDidRunSudoWithPassword(onDidRunSudoWithPassword),
vscode.workspace.onDidChangeWorkspaceFolders(onDidChangeWorkspaceFolders)
);
void onDidChangeWorkspaceFolders({
added: vscode.workspace.workspaceFolders ?? [],
removed: [],
});
}
const maxSudoPasswordIntervalInMilli = 3 * 60 * 60 * 1000; // 3 hours
let lastDidRunSudoWithPassword: Date | undefined = undefined;
let didShowSudoHint = false;
/**
* Show a hint to set up sudo to request passwords less frequently
* when the user needed to type passwords twice in a row.
*/
function onDidRunSudoWithPassword(): void {
const now = new Date();
if (lastDidRunSudoWithPassword !== undefined) {
const elapsed = now.getTime() - lastDidRunSudoWithPassword.getTime();
if (elapsed < maxSudoPasswordIntervalInMilli) {
if (!didShowSudoHint) {
void (async () => {
const choice = await vscode.window.showInformationMessage(
'You can set up sudo to request passwords less frequently.',
'Open Documentation'
);
if (choice) {
void vscode.env.openExternal(
vscode.Uri.parse(
'https://chromium.googlesource.com/chromiumos/docs/+/HEAD/tips-and-tricks.md#how-to-make-sudo-a-little-more-permissive'
)
);
}
})();
didShowSudoHint = true;
}
}
}
lastDidRunSudoWithPassword = now;
}
const onDidHandleChangeWorkspaceFoldersEmitter =
new vscode.EventEmitter<void>();
export const onDidHandleChangeWorkspaceFolders =
onDidHandleChangeWorkspaceFoldersEmitter.event;
async function onDidChangeWorkspaceFolders({
added,
}: vscode.WorkspaceFoldersChangeEvent): Promise<void> {
for (const dir of added) {
if (
hints.tooLargeWorkspace.get() &&
(await isChromiumosRoot(dir.uri.fsPath))
) {
Metrics.send({
category: 'background',
group: 'hints',
description: 'show chromiumos workspace warning',
name: 'hints_show_chromiumos_workspace_warning',
});
const openSubdirectory = 'Open subdirectory';
const dontAskAgain = "Don't ask again";
const choice = await vscode.window.showWarningMessage(
'Opening the entire chromiumos directory can cause performance problem; we recommend to open a subdirectory',
openSubdirectory,
dontAskAgain
);
if (choice === openSubdirectory) {
const folderUri = await vscode.window.showOpenDialog({
defaultUri: dir.uri,
canSelectMany: false,
openLabel: 'Select',
canSelectFiles: false,
canSelectFolders: true,
});
if (folderUri) {
void vscode.commands.executeCommand(
'vscode.openFolder',
folderUri[0]
);
}
} else if (choice === dontAskAgain) {
await hints.tooLargeWorkspace.update(false);
Metrics.send({
category: 'interactive',
group: 'hints',
description: 'show chromiumos workspace warning',
name: 'hints_ignore_chromiumos_workspace_warning',
});
}
}
}
onDidHandleChangeWorkspaceFoldersEmitter.fire();
}