mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 04:55:42 +09:00
feat(desktop): add a setting and flag to disable updates (#3483)
This commit is contained in:
1 parent
3a74a6f97a
commit
674b4d26d1
58 files changed
+1477
-42
No files matched your search
@@ -70,6 +70,7 @@ interface PersistedDesktopWindowBehaviorSettings {
|
||||
|
||||
interface PersistedDesktopTroubleshootingSettings {
|
||||
disableHardwareAcceleration?: boolean;
|
||||
disableModuleUpdates?: boolean;
|
||||
}
|
||||
|
||||
const INSTANCE_ENDPOINT_ARGS = ['--fluxer-instance'];
|
||||
@@ -82,6 +83,7 @@ let configPath: string | null = null;
|
||||
function getDefaultDesktopTroubleshootingSettings(): DesktopTroubleshootingSettings {
|
||||
return {
|
||||
disableHardwareAcceleration: false,
|
||||
disableModuleUpdates: false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -156,6 +158,9 @@ function sanitizePersistedDesktopTroubleshootingSettings(
|
||||
if (typeof value.disableHardwareAcceleration === 'boolean') {
|
||||
settings.disableHardwareAcceleration = value.disableHardwareAcceleration;
|
||||
}
|
||||
if (typeof value.disableModuleUpdates === 'boolean') {
|
||||
settings.disableModuleUpdates = value.disableModuleUpdates;
|
||||
}
|
||||
return Object.keys(settings).length > 0 ? settings : undefined;
|
||||
}
|
||||
|
||||
@@ -425,6 +430,10 @@ function normalizeDesktopTroubleshootingSettings(
|
||||
typeof settings?.disableHardwareAcceleration === 'boolean'
|
||||
? settings.disableHardwareAcceleration
|
||||
: defaults.disableHardwareAcceleration,
|
||||
disableModuleUpdates:
|
||||
typeof settings?.disableModuleUpdates === 'boolean'
|
||||
? settings.disableModuleUpdates
|
||||
: defaults.disableModuleUpdates,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -433,6 +442,7 @@ function serializeDesktopTroubleshootingSettings(
|
||||
): PersistedDesktopTroubleshootingSettings {
|
||||
return {
|
||||
disableHardwareAcceleration: settings.disableHardwareAcceleration,
|
||||
disableModuleUpdates: settings.disableModuleUpdates,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import type {
|
||||
NativeAudioStartResult,
|
||||
NativeScreenCaptureLifecycleMessage,
|
||||
SetDesktopTroubleshootingDisableHardwareAccelerationOptions,
|
||||
SetDesktopTroubleshootingDisableModuleUpdatesOptions,
|
||||
SpellcheckBundledDictionary,
|
||||
SpellcheckEngine,
|
||||
SpellcheckResolvedEngineInfo,
|
||||
@@ -261,6 +262,9 @@ export interface ElectronAPI {
|
||||
setDesktopDisableHardwareAcceleration: (
|
||||
options: SetDesktopTroubleshootingDisableHardwareAccelerationOptions,
|
||||
) => Promise<DesktopTroubleshootingSettings>;
|
||||
setDesktopDisableModuleUpdates: (
|
||||
options: SetDesktopTroubleshootingDisableModuleUpdatesOptions,
|
||||
) => Promise<DesktopTroubleshootingSettings>;
|
||||
onUpdaterEvent: (callback: (event: UpdaterEvent) => void) => () => void;
|
||||
updaterCheck: (context: UpdaterContext) => Promise<void>;
|
||||
windowMinimize: () => void;
|
||||
|
||||
@@ -159,7 +159,8 @@ async function runModuleBootstrap(): Promise<void> {
|
||||
const {configureUserDataPath} = await import('@electron/common/UserDataPath');
|
||||
const {armNativeProbeCache} = await import('@electron/main/NativeProbeCache');
|
||||
const {isStartMinimizedLaunch} = await import('@electron/main/AutostartLaunch');
|
||||
const {areModuleUpdatesDisabled, isDesktopUpdateRequested} = await import('@electron/main/LaunchOptions');
|
||||
const {areModuleUpdatesDisabled} = await import('@electron/main/DesktopDebugInfo');
|
||||
const {isDesktopUpdateRequested, shouldDisableModuleUpdatesForLaunch} = await import('@electron/main/LaunchOptions');
|
||||
const {relaunchStableLaunchPath} = await import('@electron/main/LinuxLaunchPath');
|
||||
const {getDesktopLocalAppProtocol} = await import('@electron/main/LocalAppProtocol');
|
||||
const {
|
||||
@@ -410,9 +411,10 @@ async function runModuleBootstrap(): Promise<void> {
|
||||
logger.warn('Failed to record whether an update is waiting', error);
|
||||
}
|
||||
};
|
||||
const moduleUpdatesForcedOff = shouldDisableModuleUpdatesForLaunch();
|
||||
const moduleUpdatesDisabled = areModuleUpdatesDisabled();
|
||||
if (moduleUpdatesDisabled) {
|
||||
logger.info('Module updates are disabled by FLUXER_DISABLE_MODULE_UPDATES');
|
||||
logger.info('Module updates are disabled for this launch');
|
||||
}
|
||||
const updater = new ModuleUpdater({
|
||||
store,
|
||||
@@ -421,7 +423,8 @@ async function runModuleBootstrap(): Promise<void> {
|
||||
bundledRendererVersion: BUNDLED_RENDERER_VERSION,
|
||||
preferUnversionedBundle: app.isPackaged,
|
||||
forceStartupUpdate: store.shellVersionChanged || updateWasPending || isDesktopUpdateRequested(),
|
||||
moduleUpdatesDisabled,
|
||||
moduleUpdatesDisabled: moduleUpdatesForcedOff,
|
||||
moduleUpdatesDisabledBySetting: moduleUpdatesDisabled && !moduleUpdatesForcedOff,
|
||||
selfUpdateShellFirst:
|
||||
shellUpdatePlan.capability === ShellUpdateCapability.SELF_UPDATE
|
||||
? async (latestVersion) => {
|
||||
|
||||
@@ -275,26 +275,3 @@ describe('Bootstrap entry point', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('FLUXER_DISABLE_MODULE_UPDATES', () => {
|
||||
test('reads the environment variable like the other FLUXER_DISABLE switches', async () => {
|
||||
const {areModuleUpdatesDisabled} = await import('./LaunchOptions.ts');
|
||||
const previous = process.env.FLUXER_DISABLE_MODULE_UPDATES;
|
||||
try {
|
||||
delete process.env.FLUXER_DISABLE_MODULE_UPDATES;
|
||||
assert.equal(areModuleUpdatesDisabled(), false);
|
||||
for (const value of ['1', 'true', 'YES', 'on']) {
|
||||
process.env.FLUXER_DISABLE_MODULE_UPDATES = value;
|
||||
assert.equal(areModuleUpdatesDisabled(), true);
|
||||
}
|
||||
process.env.FLUXER_DISABLE_MODULE_UPDATES = '0';
|
||||
assert.equal(areModuleUpdatesDisabled(), false);
|
||||
} finally {
|
||||
if (previous === undefined) {
|
||||
delete process.env.FLUXER_DISABLE_MODULE_UPDATES;
|
||||
} else {
|
||||
process.env.FLUXER_DISABLE_MODULE_UPDATES = previous;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -12,7 +12,12 @@ import {
|
||||
readDesktopAccountStoreTelemetry,
|
||||
} from '@electron/main/DesktopAccountStoreTelemetry';
|
||||
import {type DesktopAppStoreState, readDesktopAppStoreState} from '@electron/main/DesktopAppStoreHealth';
|
||||
import {getArgValue, hasFlag, isSafeModeLaunch} from '@electron/main/LaunchOptions';
|
||||
import {
|
||||
getArgValue,
|
||||
hasFlag,
|
||||
isSafeModeLaunch,
|
||||
shouldDisableModuleUpdatesForLaunch,
|
||||
} from '@electron/main/LaunchOptions';
|
||||
import {getDesktopInfo} from '@electron/main/PlatformInfo';
|
||||
import {
|
||||
formatDesktopOsName,
|
||||
@@ -86,6 +91,7 @@ export function resolveEffectiveDesktopTroubleshootingSettings(
|
||||
disableHardwareAcceleration:
|
||||
platform !== 'darwin' &&
|
||||
(settings.disableHardwareAcceleration || shouldDisableHardwareAccelerationForLaunch(argv)),
|
||||
disableModuleUpdates: settings.disableModuleUpdates || shouldDisableModuleUpdatesForLaunch(argv),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -100,6 +106,10 @@ export function getLaunchDesktopTroubleshootingSettings(): DesktopTroubleshootin
|
||||
return launchTroubleshootingSettings;
|
||||
}
|
||||
|
||||
export function areModuleUpdatesDisabled(): boolean {
|
||||
return getLaunchDesktopTroubleshootingSettings().disableModuleUpdates;
|
||||
}
|
||||
|
||||
export function shouldOpenDevToolsOnLaunch(argv: ReadonlyArray<string>): boolean {
|
||||
return hasFlag(argv, OPEN_DEVTOOLS_ARGS);
|
||||
}
|
||||
@@ -265,7 +275,7 @@ export function formatDesktopDebugInfo(info: DesktopDebugInfo): string {
|
||||
`Account store: ${formatAccountStoreState(info.accountStore)}`,
|
||||
`Account store telemetry: ${formatDesktopAccountStoreTelemetry(info.accountStoreTelemetry)}`,
|
||||
`Logs: ${info.logFilePath ?? info.logsPath ?? '(unavailable)'}`,
|
||||
`Troubleshooting: disableHardwareAcceleration=${info.troubleshooting.disableHardwareAcceleration}`,
|
||||
`Troubleshooting: disableHardwareAcceleration=${info.troubleshooting.disableHardwareAcceleration}, disableModuleUpdates=${info.troubleshooting.disableModuleUpdates}`,
|
||||
`Window behavior: ${formatWindowBehavior(info.windowBehavior)}`,
|
||||
`Runtime: packaged=${info.packaged}, portable=${info.portable}, pid=${info.pid}, cwd=${info.cwd}`,
|
||||
`Sandbox: flatpak=${info.desktopInfo.flatpak}, flatpakAppId=${info.desktopInfo.flatpakAppId ?? '(none)'}`,
|
||||
|
||||
@@ -11,9 +11,9 @@ import type {
|
||||
TrayActionPayload,
|
||||
TrayRuntimeStatePayload,
|
||||
} from '@electron/common/Types';
|
||||
import {areModuleUpdatesDisabled} from '@electron/main/DesktopDebugInfo';
|
||||
import {getDesktopUpdateState, observeDesktopUpdateState} from '@electron/main/DesktopUpdateGate';
|
||||
import {checkForUpdatesFromShell, startDesktopUpdateFromShell} from '@electron/main/DesktopUpdatePrompt';
|
||||
import {areModuleUpdatesDisabled} from '@electron/main/LaunchOptions';
|
||||
import {relaunchStableLaunchPath} from '@electron/main/LinuxLaunchPath';
|
||||
import {onLocaleChange, t} from '@electron/main/MainI18n';
|
||||
import {renderTrayIcon, resolveTrayIconAppearance} from '@electron/main/TrayIconImage';
|
||||
|
||||
@@ -19,7 +19,8 @@ globalThis.__fluxerDesktopTrayIconTestSettings__ = settings;
|
||||
|
||||
installTestModuleStub(
|
||||
'@electron/common/DesktopConfig',
|
||||
'export const getDesktopWindowBehaviorSettings = () => ({...globalThis.__fluxerDesktopTrayIconTestSettings__});',
|
||||
`export const getDesktopWindowBehaviorSettings = () => ({...globalThis.__fluxerDesktopTrayIconTestSettings__});
|
||||
export const getDesktopTroubleshootingSettings = () => ({disableHardwareAcceleration: false, disableModuleUpdates: false});`,
|
||||
);
|
||||
installTestModuleStub(
|
||||
'@electron/main/DesktopUpdatePrompt',
|
||||
|
||||
@@ -73,6 +73,7 @@ import {
|
||||
relaunchAndExit,
|
||||
setHardwareAccelerationDisabled,
|
||||
setHardwareAccelerationDisabledAndRestart,
|
||||
setModuleUpdatesDisabledAndRestart,
|
||||
} from '@electron/main/Troubleshooting';
|
||||
import {parseUnreadBadge, UNREAD_BADGE_DOT} from '@electron/main/UnreadBadge';
|
||||
import {registerVoiceBackgroundMediaCacheHandlers} from '@electron/main/VoiceBackgroundMediaCache';
|
||||
@@ -243,6 +244,13 @@ export function registerIpcHandlers(): void {
|
||||
return getLaunchDesktopTroubleshootingSettings();
|
||||
},
|
||||
);
|
||||
ipcMain.handle(
|
||||
'desktop-troubleshooting-set-disable-module-updates',
|
||||
(_event, payload: {disable: boolean}): DesktopTroubleshootingSettings => {
|
||||
setModuleUpdatesDisabledAndRestart(Boolean(payload?.disable));
|
||||
return getLaunchDesktopTroubleshootingSettings();
|
||||
},
|
||||
);
|
||||
ipcMain.on('streaming-priority-acquire', (event) => {
|
||||
acquireStreamingPriority(event.sender);
|
||||
});
|
||||
|
||||
@@ -24,6 +24,7 @@ const SPELLCHECK_MODE_ARGS = new Set(['--fluxer-spellcheck']);
|
||||
const DISABLE_V8_CODE_CACHE_ARGS = new Set(['--fluxer-disable-v8-code-cache']);
|
||||
const DISABLE_NATIVE_GATEWAY_ARGS = new Set(['--fluxer-disable-native-gateway']);
|
||||
const DESKTOP_UPDATE_ARGS = new Set(['--fluxer-update']);
|
||||
const DISABLE_MODULE_UPDATES_ARGS = new Set(['--fluxer-disable-module-updates', '--disable-module-updates']);
|
||||
|
||||
export function hasFlag(argv: ReadonlyArray<string>, flags: ReadonlySet<string>): boolean {
|
||||
return argv.some((arg) => flags.has(arg) || [...flags].some((flag) => arg.startsWith(`${flag}=`)));
|
||||
@@ -159,12 +160,12 @@ export function describeLaunchDiagnosticOptions(argv: ReadonlyArray<string> = pr
|
||||
spellcheck: getSpellcheckLaunchMode(argv),
|
||||
v8CodeCacheDisabled: shouldDisableV8CodeCache(argv),
|
||||
nativeGatewayDisableReason: getNativeGatewayDisableReason(argv),
|
||||
moduleUpdatesDisabled: areModuleUpdatesDisabled(),
|
||||
moduleUpdatesDisabled: shouldDisableModuleUpdatesForLaunch(argv),
|
||||
};
|
||||
}
|
||||
|
||||
export function areModuleUpdatesDisabled(): boolean {
|
||||
return truthyEnv('FLUXER_DISABLE_MODULE_UPDATES');
|
||||
export function shouldDisableModuleUpdatesForLaunch(argv: ReadonlyArray<string> = process.argv): boolean {
|
||||
return hasFlag(argv, DISABLE_MODULE_UPDATES_ARGS) || truthyEnv('FLUXER_DISABLE_MODULE_UPDATES');
|
||||
}
|
||||
|
||||
export function isDesktopUpdateRequested(argv: ReadonlyArray<string> = process.argv): boolean {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {DESKTOP_APP_NAME} from '@electron/common/DesktopIdentity';
|
||||
import {areModuleUpdatesDisabled} from '@electron/main/DesktopDebugInfo';
|
||||
import {checkForUpdatesFromShell} from '@electron/main/DesktopUpdatePrompt';
|
||||
import {areModuleUpdatesDisabled} from '@electron/main/LaunchOptions';
|
||||
import {onLocaleChange, t} from '@electron/main/MainI18n';
|
||||
import {openExternalDeduped} from '@electron/main/OpenExternal';
|
||||
import {buildTroubleshootingMenuItems} from '@electron/main/Troubleshooting';
|
||||
|
||||
@@ -128,6 +128,7 @@ function createUpdater(store, modules, options = {}) {
|
||||
bundledRendererVersion: options.bundledRendererVersion ?? null,
|
||||
forceStartupUpdate: options.forceStartupUpdate ?? false,
|
||||
moduleUpdatesDisabled: options.moduleUpdatesDisabled ?? false,
|
||||
moduleUpdatesDisabledBySetting: options.moduleUpdatesDisabledBySetting ?? false,
|
||||
selfUpdateShellFirst: options.selfUpdateShellFirst,
|
||||
onState: options.onState,
|
||||
fetch: async (url, init) => {
|
||||
@@ -574,6 +575,41 @@ describe('ModuleUpdater with module updates disabled', () => {
|
||||
assert.deepEqual(requests, []);
|
||||
assert.deepEqual(sleeps, []);
|
||||
});
|
||||
|
||||
test('the saved setting launches the verified set without fetching', async () => {
|
||||
const userDataPath = createUserData();
|
||||
const store = await openStore(userDataPath);
|
||||
installModuleOnDisk(getModuleStoreRoot(userDataPath), 'fluxer_renderer', RENDERER_SHA, [['index.js', 'renderer']]);
|
||||
await store.commit({fluxer_renderer: RENDERER_SHA});
|
||||
assert.equal((await createUpdater(store, {fluxer_renderer: RENDERER_SHA}).updater.run()).status, 'launching');
|
||||
const {updater, requests} = createUpdater(
|
||||
store,
|
||||
{fluxer_renderer: NEXT_RENDERER_SHA},
|
||||
{moduleUpdatesDisabledBySetting: true},
|
||||
);
|
||||
|
||||
const outcome = await updater.run();
|
||||
|
||||
assert.equal(outcome.status, 'unreachable-launch');
|
||||
assert.deepEqual(outcome.committed, {fluxer_renderer: RENDERER_SHA});
|
||||
assert.deepEqual(requests, []);
|
||||
});
|
||||
|
||||
test('the saved setting goes to the update server when nothing can launch', async () => {
|
||||
const store = await openStore(createUserData());
|
||||
const {updater, requests} = createUpdater(
|
||||
store,
|
||||
{fluxer_renderer: RENDERER_SHA},
|
||||
{moduleUpdatesDisabledBySetting: true, respond: missingPackages()},
|
||||
);
|
||||
|
||||
const outcome = await updater.run();
|
||||
|
||||
assert.equal(outcome.status, 'blocked-update-required');
|
||||
assert.equal(outcome.reason, 'required-module-unavailable');
|
||||
assert.equal(outcome.updateServerUnreachable, false);
|
||||
assert.ok(requests.some((url) => String(url).endsWith('/modules.json')));
|
||||
});
|
||||
});
|
||||
|
||||
describe('ModuleUpdater checks without downloading and installs only when asked', () => {
|
||||
|
||||
@@ -268,6 +268,7 @@ interface ModuleUpdaterOptions {
|
||||
readonly preferUnversionedBundle?: boolean;
|
||||
readonly forceStartupUpdate?: boolean;
|
||||
readonly moduleUpdatesDisabled?: boolean;
|
||||
readonly moduleUpdatesDisabledBySetting?: boolean;
|
||||
readonly selfUpdateShellFirst?: (latestVersion: string) => Promise<{readonly reason: string}>;
|
||||
readonly onState?: (state: ModuleUpdaterSplashState) => void;
|
||||
readonly report?: (report: ModuleUpdaterReport) => void;
|
||||
@@ -288,6 +289,7 @@ export class ModuleUpdater {
|
||||
private readonly hasOfflineRenderer: boolean;
|
||||
private readonly forceStartupUpdate: boolean;
|
||||
private readonly moduleUpdatesDisabled: boolean;
|
||||
private readonly moduleUpdatesDisabledBySetting: boolean;
|
||||
private readonly selfUpdateShellFirst: ((latestVersion: string) => Promise<{readonly reason: string}>) | null;
|
||||
private readonly shellFirstAttempts = new Map<string, {readonly reason: string} | null>();
|
||||
private readonly manifestFeed: ModuleManifestFeedIdentity;
|
||||
@@ -317,6 +319,7 @@ export class ModuleUpdater {
|
||||
this.hasOfflineRenderer = options.hasOfflineRenderer ?? false;
|
||||
this.forceStartupUpdate = options.forceStartupUpdate ?? false;
|
||||
this.moduleUpdatesDisabled = options.moduleUpdatesDisabled ?? false;
|
||||
this.moduleUpdatesDisabledBySetting = options.moduleUpdatesDisabledBySetting ?? false;
|
||||
this.selfUpdateShellFirst = options.selfUpdateShellFirst ?? null;
|
||||
const releaseChannel = options.releaseChannel ?? BUILD_CHANNEL;
|
||||
this.platform = options.platform ?? process.platform;
|
||||
@@ -421,17 +424,16 @@ export class ModuleUpdater {
|
||||
return reverted;
|
||||
}
|
||||
}
|
||||
if (this.moduleUpdatesDisabled) {
|
||||
if (this.moduleUpdatesDisabled || this.moduleUpdatesDisabledBySetting) {
|
||||
const decision = await this.planner.evaluateUnreachableLaunch(this.startupUpdateEnforced);
|
||||
if (decision.kind === ModuleUnreachableLaunchDecision.LAUNCH) {
|
||||
return await this.launchUnreachable();
|
||||
}
|
||||
return this.blockUpdateRequired(
|
||||
decision.reason,
|
||||
[],
|
||||
'module updates are disabled by FLUXER_DISABLE_MODULE_UPDATES',
|
||||
{updateServerUnreachable: true},
|
||||
);
|
||||
if (this.moduleUpdatesDisabled) {
|
||||
return this.blockUpdateRequired(decision.reason, [], 'module updates are disabled', {
|
||||
updateServerUnreachable: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this.platform === 'linux' && !(await this.startupUpdateRequired())) {
|
||||
return await this.launchIfAtFloor();
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import {describe, test} from 'node:test';
|
||||
import {installElectronStub} from './LocalAppTestSupport.test.mjs';
|
||||
|
||||
installElectronStub();
|
||||
|
||||
const {getDesktopTroubleshootingSettings, loadDesktopConfig, setDesktopTroubleshootingSettings} = await import(
|
||||
'../common/DesktopConfig.ts'
|
||||
);
|
||||
const {shouldDisableModuleUpdatesForLaunch} = await import('./LaunchOptions.ts');
|
||||
const {areModuleUpdatesDisabled, resolveEffectiveDesktopTroubleshootingSettings} = await import(
|
||||
'./DesktopDebugInfo.ts'
|
||||
);
|
||||
|
||||
function loadSettings(troubleshooting) {
|
||||
const userDataPath = fs.mkdtempSync(path.join(os.tmpdir(), 'fluxer-desktop-module-updates-setting-test-'));
|
||||
fs.writeFileSync(path.join(userDataPath, 'settings.json'), JSON.stringify({troubleshooting}));
|
||||
loadDesktopConfig(userDataPath);
|
||||
return userDataPath;
|
||||
}
|
||||
|
||||
function readPersisted(userDataPath) {
|
||||
return JSON.parse(fs.readFileSync(path.join(userDataPath, 'settings.json'), 'utf8')).troubleshooting;
|
||||
}
|
||||
|
||||
function withModuleUpdatesEnv(value, run) {
|
||||
const previous = process.env.FLUXER_DISABLE_MODULE_UPDATES;
|
||||
try {
|
||||
if (value === undefined) {
|
||||
delete process.env.FLUXER_DISABLE_MODULE_UPDATES;
|
||||
} else {
|
||||
process.env.FLUXER_DISABLE_MODULE_UPDATES = value;
|
||||
}
|
||||
run();
|
||||
} finally {
|
||||
if (previous === undefined) {
|
||||
delete process.env.FLUXER_DISABLE_MODULE_UPDATES;
|
||||
} else {
|
||||
process.env.FLUXER_DISABLE_MODULE_UPDATES = previous;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe('disabling module updates', () => {
|
||||
test('reads the environment variable like the other FLUXER_DISABLE switches', () => {
|
||||
withModuleUpdatesEnv(undefined, () => assert.equal(shouldDisableModuleUpdatesForLaunch([]), false));
|
||||
for (const value of ['1', 'true', 'YES', 'on']) {
|
||||
withModuleUpdatesEnv(value, () => assert.equal(shouldDisableModuleUpdatesForLaunch([]), true, value));
|
||||
}
|
||||
withModuleUpdatesEnv('0', () => assert.equal(shouldDisableModuleUpdatesForLaunch([]), false));
|
||||
});
|
||||
|
||||
test('honours the launch flag with or without the fluxer prefix', () => {
|
||||
withModuleUpdatesEnv(undefined, () => {
|
||||
for (const flag of [
|
||||
'--disable-module-updates',
|
||||
'--fluxer-disable-module-updates',
|
||||
'--disable-module-updates=1',
|
||||
]) {
|
||||
assert.equal(shouldDisableModuleUpdatesForLaunch([flag]), true, flag);
|
||||
}
|
||||
assert.equal(shouldDisableModuleUpdatesForLaunch(['--fluxer-update']), false);
|
||||
});
|
||||
});
|
||||
|
||||
test('defaults to updating and drops values that are not booleans', () => {
|
||||
loadSettings(undefined);
|
||||
assert.equal(getDesktopTroubleshootingSettings().disableModuleUpdates, false);
|
||||
for (const value of ['true', 1, null, {}]) {
|
||||
loadSettings({disableModuleUpdates: value});
|
||||
assert.equal(getDesktopTroubleshootingSettings().disableModuleUpdates, false, String(value));
|
||||
}
|
||||
});
|
||||
|
||||
test('the launch flag or the persisted setting disables updates for the launch', () => {
|
||||
withModuleUpdatesEnv(undefined, () => {
|
||||
const settings = {disableHardwareAcceleration: false, disableModuleUpdates: false};
|
||||
assert.equal(resolveEffectiveDesktopTroubleshootingSettings(settings, [], 'win32').disableModuleUpdates, false);
|
||||
assert.equal(
|
||||
resolveEffectiveDesktopTroubleshootingSettings(settings, ['--disable-module-updates'], 'darwin')
|
||||
.disableModuleUpdates,
|
||||
true,
|
||||
);
|
||||
assert.equal(
|
||||
resolveEffectiveDesktopTroubleshootingSettings({...settings, disableModuleUpdates: true}, [], 'linux')
|
||||
.disableModuleUpdates,
|
||||
true,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('turning the setting back off restores updating without touching hardware acceleration', () => {
|
||||
const userDataPath = loadSettings({disableHardwareAcceleration: true, disableModuleUpdates: true});
|
||||
assert.equal(getDesktopTroubleshootingSettings().disableModuleUpdates, true);
|
||||
setDesktopTroubleshootingSettings({disableModuleUpdates: false});
|
||||
assert.deepEqual(readPersisted(userDataPath), {disableHardwareAcceleration: true, disableModuleUpdates: false});
|
||||
loadDesktopConfig(userDataPath);
|
||||
withModuleUpdatesEnv(undefined, () => {
|
||||
assert.equal(
|
||||
resolveEffectiveDesktopTroubleshootingSettings(getDesktopTroubleshootingSettings(), [], 'win32')
|
||||
.disableModuleUpdates,
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('keeps the launch answer when the persisted setting changes without a restart', () => {
|
||||
withModuleUpdatesEnv(undefined, () => {
|
||||
loadSettings({disableModuleUpdates: true});
|
||||
assert.equal(areModuleUpdatesDisabled(), true);
|
||||
setDesktopTroubleshootingSettings({disableModuleUpdates: false});
|
||||
assert.equal(areModuleUpdatesDisabled(), true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -44,6 +44,12 @@ export function setHardwareAccelerationDisabledAndRestart(disable: boolean): voi
|
||||
relaunchAndExit();
|
||||
}
|
||||
|
||||
export function setModuleUpdatesDisabledAndRestart(disable: boolean): void {
|
||||
setDesktopTroubleshootingSettings({disableModuleUpdates: disable});
|
||||
logger.info('Restarting to apply module updates change', {disable});
|
||||
relaunchAndExit();
|
||||
}
|
||||
|
||||
function reloadMainWindow(): void {
|
||||
const mainWindow = getMainWindow();
|
||||
if (!mainWindow || mainWindow.isDestroyed()) {
|
||||
|
||||
@@ -49,6 +49,7 @@ import {
|
||||
recordDesktopAppStoreSuccess,
|
||||
} from '@electron/main/DesktopAppStoreHealth';
|
||||
import {
|
||||
areModuleUpdatesDisabled,
|
||||
formatDesktopDebugInfo,
|
||||
getDesktopDebugInfo,
|
||||
getLaunchNetLogPath,
|
||||
@@ -73,7 +74,7 @@ import {
|
||||
registerIpcHandlers,
|
||||
} from '@electron/main/IpcHandlers';
|
||||
import {initializeJumpList} from '@electron/main/JumpList';
|
||||
import {areModuleUpdatesDisabled, describeLaunchDiagnosticOptions} from '@electron/main/LaunchOptions';
|
||||
import {describeLaunchDiagnosticOptions} from '@electron/main/LaunchOptions';
|
||||
import {cleanupLegacyHarvestHandlers, registerLegacyHarvestHandlers} from '@electron/main/LegacyHarvestIpc';
|
||||
import {initializeLegacyOriginHarvest} from '@electron/main/LegacyOriginHarvest';
|
||||
import {cleanupVirtmic, registerVirtmicHandlers} from '@electron/main/LinuxAudioCapture';
|
||||
|
||||
@@ -45,6 +45,7 @@ import type {
|
||||
NotificationOptions,
|
||||
NotificationResult,
|
||||
SetDesktopTroubleshootingDisableHardwareAccelerationOptions,
|
||||
SetDesktopTroubleshootingDisableModuleUpdatesOptions,
|
||||
SpellcheckBundledDictionary,
|
||||
SpellcheckResolvedEngineInfo,
|
||||
SpellcheckState,
|
||||
@@ -443,6 +444,10 @@ const api: ElectronAPI = {
|
||||
options: SetDesktopTroubleshootingDisableHardwareAccelerationOptions,
|
||||
): Promise<DesktopTroubleshootingSettings> =>
|
||||
ipcRenderer.invoke('desktop-troubleshooting-set-disable-hardware-acceleration', options),
|
||||
setDesktopDisableModuleUpdates: (
|
||||
options: SetDesktopTroubleshootingDisableModuleUpdatesOptions,
|
||||
): Promise<DesktopTroubleshootingSettings> =>
|
||||
ipcRenderer.invoke('desktop-troubleshooting-set-disable-module-updates', options),
|
||||
onUpdaterEvent: (callback: (event: UpdaterEvent) => void): (() => void) => {
|
||||
const handler = (_event: Electron.IpcRendererEvent, data: UpdaterEvent) => callback(data);
|
||||
ipcRenderer.on('updater-event', handler);
|
||||
|
||||
Reference in new issue
Block a user