Skip to content

Commit ea9d286

Browse files
bmeurerDevtools-frontend LUCI CQ
authored andcommitted
[cleanup] Move the host configuration to Root.Runtime.hostConfig.
Ideally the host configuration would live in `core/host`, but due to the current setup, this isn't possible. However it also doesn't make sense to bolt it into `Settings`, since this has nothing to do with settings. Rather, it makes sense to keep it together with the type definitions as part of `core/root`. This also simplifies the test handling and makes it more robust. Fixed: 396033932 Change-Id: I8f00fc84f62b180ede4407741d261544a13218da Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6257569 Reviewed-by: Alex Rudenko <[email protected]> Commit-Queue: Benedikt Meurer <[email protected]> Auto-Submit: Benedikt Meurer <[email protected]> Commit-Queue: Alex Rudenko <[email protected]>
1 parent f72b44b commit ea9d286

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+360
-397
lines changed

docs/contributing/settings-experiments-features.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ out/Default/chrome --enable-features="DevToolsNewFeature:string_param/foo/double
131131
132132
### In DevTools, use the new property added to HostConfig
133133
134-
* Update the type definition in [`Runtime.ts`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/root/Runtime.ts;l=326;drc=a1e6997df9503f1c29f84e7ffebcdadbaa91ed71).
135-
* Update the dummy value in [`InspectorFrontendHost.ts`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/host/InspectorFrontendHost.ts;l=401;drc=197a33e1793066c8d32b8670e06cd55364121537).
136-
* For tests, update the stub in [`EnvironmentHelpers.ts`](https://crsrc.org/c/third_party/devtools-frontend/src/front_end/testing/EnvironmentHelpers.ts;l=494;drc=f1699bd12f8a486c749a849561391d890208f613).
137-
* Access the host config via `Common.Settings.Settings.instance().getHostConfig()`.
134+
* Update the type definition in [`Runtime.ts`](https://crsrc.org/c/third_party/devtools-frontend/src/front_end/core/root/Runtime.ts).
135+
* Update the dummy value returned by `getHostConfig` in [`InspectorFrontendHost.ts`](https://crsrc.org/c/third_party/devtools-frontend/src/front_end/core/host/InspectorFrontendHost.ts).
136+
* For tests, update the `HOST_CONFIG` in [`EnvironmentHelpers.ts`](https://crsrc.org/c/third_party/devtools-frontend/src/front_end/testing/EnvironmentHelpers.ts).
137+
* Access the host config via `Root.Runtime.hostConfig`.
138138
139139
Please refer to this [example CL](https://crrev.com/c/5626314).

front_end/core/common/SettingRegistration.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from '../../testing/EnvironmentHelpers.js';
99
import * as QuickOpen from '../../ui/legacy/components/quick_open/quick_open.js';
1010
import * as i18n from '../i18n/i18n.js';
11-
import type * as Root from '../root/root.js';
11+
import * as Root from '../root/root.js';
1212

1313
import * as Common from './common.js';
1414

@@ -108,6 +108,13 @@ describe('SettingRegistration', () => {
108108

109109
it('can handle settings with condition which depends on host config', () => {
110110
const configSettingName = 'mock-setting-with-host-config';
111+
Object.assign(Root.Runtime.hostConfig, {
112+
devToolsConsoleInsights: {
113+
modelId: 'mockModel',
114+
temperature: -1,
115+
enabled: true,
116+
},
117+
});
111118
Common.Settings.registerSettingExtension({
112119
settingName: configSettingName,
113120
settingType: Common.Settings.SettingType.BOOLEAN,
@@ -124,13 +131,6 @@ describe('SettingRegistration', () => {
124131
syncedStorage: dummyStorage,
125132
globalStorage: dummyStorage,
126133
localStorage: dummyStorage,
127-
config: {
128-
devToolsConsoleInsights: {
129-
modelId: 'mockModel',
130-
temperature: -1,
131-
enabled: true,
132-
},
133-
} as Root.Runtime.HostConfig,
134134
});
135135
const setting = Common.Settings.Settings.instance().moduleSetting(configSettingName);
136136
assert.isNotNull(setting);

front_end/core/common/SettingRegistration.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,8 @@ export function registerSettingExtension(registration: SettingRegistration): voi
9393
registeredSettings.push(registration);
9494
}
9595

96-
export function getRegisteredSettings(config: Root.Runtime.HostConfig): Array<SettingRegistration> {
97-
return registeredSettings.filter(
98-
setting => Root.Runtime.Runtime.isDescriptorEnabled(
99-
{experiment: setting.experiment, condition: setting.condition}, config));
96+
export function getRegisteredSettings(): Array<SettingRegistration> {
97+
return registeredSettings.filter(setting => Root.Runtime.Runtime.isDescriptorEnabled(setting));
10098
}
10199

102100
export function registerSettingsForTest(settings: Array<SettingRegistration>, forceReset: boolean = false): void {

front_end/core/common/Settings.ts

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,12 @@ export class Settings {
5858
#eventSupport: ObjectWrapper<GenericEvents>;
5959
#registry: Map<string, Setting<unknown>>;
6060
readonly moduleSettings: Map<string, Setting<unknown>>;
61-
#config: Root.Runtime.HostConfig;
6261

6362
private constructor(
64-
readonly syncedStorage: SettingsStorage, readonly globalStorage: SettingsStorage,
65-
readonly localStorage: SettingsStorage, config?: Root.Runtime.HostConfig) {
63+
readonly syncedStorage: SettingsStorage,
64+
readonly globalStorage: SettingsStorage,
65+
readonly localStorage: SettingsStorage,
66+
) {
6667
this.#sessionStorage = new SettingsStorage({});
6768

6869
this.settingNameSet = new Set();
@@ -73,12 +74,12 @@ export class Settings {
7374
this.#registry = new Map();
7475
this.moduleSettings = new Map();
7576

76-
this.#config = config || {};
7777
for (const registration of this.getRegisteredSettings()) {
7878
const {settingName, defaultValue, storageType} = registration;
7979
const isRegex = registration.settingType === SettingType.REGEX;
8080

81-
const evaluatedDefaultValue = typeof defaultValue === 'function' ? defaultValue(this.#config) : defaultValue;
81+
const evaluatedDefaultValue =
82+
typeof defaultValue === 'function' ? defaultValue(Root.Runtime.hostConfig) : defaultValue;
8283
const setting = isRegex && typeof evaluatedDefaultValue === 'string' ?
8384
this.createRegExpSetting(settingName, evaluatedDefaultValue, undefined, storageType) :
8485
this.createSetting(settingName, evaluatedDefaultValue, storageType);
@@ -94,7 +95,7 @@ export class Settings {
9495
}
9596

9697
getRegisteredSettings(): SettingRegistration[] {
97-
return getRegisteredSettingsInternal(this.#config);
98+
return getRegisteredSettingsInternal();
9899
}
99100

100101
static hasInstance(): boolean {
@@ -106,15 +107,14 @@ export class Settings {
106107
syncedStorage: SettingsStorage|null,
107108
globalStorage: SettingsStorage|null,
108109
localStorage: SettingsStorage|null,
109-
config?: Root.Runtime.HostConfig,
110110
} = {forceNew: null, syncedStorage: null, globalStorage: null, localStorage: null}): Settings {
111-
const {forceNew, syncedStorage, globalStorage, localStorage, config} = opts;
111+
const {forceNew, syncedStorage, globalStorage, localStorage} = opts;
112112
if (!settingsInstance || forceNew) {
113113
if (!syncedStorage || !globalStorage || !localStorage) {
114114
throw new Error(`Unable to create settings: global and local storage must be provided: ${new Error().stack}`);
115115
}
116116

117-
settingsInstance = new Settings(syncedStorage, globalStorage, localStorage, config);
117+
settingsInstance = new Settings(syncedStorage, globalStorage, localStorage);
118118
}
119119

120120
return settingsInstance;
@@ -124,14 +124,6 @@ export class Settings {
124124
settingsInstance = undefined;
125125
}
126126

127-
getHostConfig(): Root.Runtime.HostConfig {
128-
return this.#config;
129-
}
130-
131-
setHostConfig(config: Root.Runtime.HostConfig): void {
132-
this.#config = config;
133-
}
134-
135127
private registerModuleSetting(setting: Setting<unknown>): void {
136128
const settingName = setting.name;
137129
const category = setting.category();
@@ -421,7 +413,7 @@ export class Setting<V> {
421413

422414
disabled(): boolean {
423415
if (this.#registration?.disabledCondition) {
424-
const {disabled} = this.#registration.disabledCondition(Settings.instance().getHostConfig());
416+
const {disabled} = this.#registration.disabledCondition(Root.Runtime.hostConfig);
425417
// If registration does not disable it, pass through to #disabled
426418
// attribute check.
427419
if (disabled) {
@@ -433,7 +425,7 @@ export class Setting<V> {
433425

434426
disabledReasons(): string[] {
435427
if (this.#registration?.disabledCondition) {
436-
const result = this.#registration.disabledCondition(Settings.instance().getHostConfig());
428+
const result = this.#registration.disabledCondition(Root.Runtime.hostConfig);
437429
if (result.disabled) {
438430
return result.reasons;
439431
}

front_end/core/host/AidaClient.test.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,27 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import {describeWithEnvironment, getGetHostConfigStub} from '../../testing/EnvironmentHelpers.js';
5+
import {describeWithEnvironment} from '../../testing/EnvironmentHelpers.js';
6+
import * as Root from '../root/root.js';
67

78
import * as Host from './host.js';
89

910
const TEST_MODEL_ID = 'testModelId';
1011

1112
describeWithEnvironment('AidaClient', () => {
1213
it('adds no model temperature if console insights is not enabled', () => {
13-
const stub = getGetHostConfigStub({});
14+
Object.assign(Root.Runtime.hostConfig, {});
1415
const request = Host.AidaClient.AidaClient.buildConsoleInsightsRequest('foo');
1516
assert.deepEqual(request, {
1617
current_message: {parts: [{text: 'foo'}], role: Host.AidaClient.Role.USER},
1718
client: 'CHROME_DEVTOOLS',
1819
client_feature: 1,
1920
functionality_type: 2,
2021
});
21-
stub.restore();
2222
});
2323

2424
it('adds a model temperature', () => {
25-
const stub = getGetHostConfigStub({
25+
Object.assign(Root.Runtime.hostConfig, {
2626
devToolsConsoleInsights: {
2727
enabled: true,
2828
temperature: 0.5,
@@ -38,11 +38,10 @@ describeWithEnvironment('AidaClient', () => {
3838
client_feature: 1,
3939
functionality_type: 2,
4040
});
41-
stub.restore();
4241
});
4342

4443
it('adds a model temperature of 0', () => {
45-
const stub = getGetHostConfigStub({
44+
Object.assign(Root.Runtime.hostConfig, {
4645
devToolsConsoleInsights: {
4746
enabled: true,
4847
temperature: 0,
@@ -58,11 +57,10 @@ describeWithEnvironment('AidaClient', () => {
5857
client_feature: 1,
5958
functionality_type: 2,
6059
});
61-
stub.restore();
6260
});
6361

6462
it('ignores a negative model temperature', () => {
65-
const stub = getGetHostConfigStub({
63+
Object.assign(Root.Runtime.hostConfig, {
6664
devToolsConsoleInsights: {
6765
enabled: true,
6866
temperature: -1,
@@ -75,11 +73,10 @@ describeWithEnvironment('AidaClient', () => {
7573
client_feature: 1,
7674
functionality_type: 2,
7775
});
78-
stub.restore();
7976
});
8077

8178
it('adds a model id and temperature', () => {
82-
const stub = getGetHostConfigStub({
79+
Object.assign(Root.Runtime.hostConfig, {
8380
devToolsConsoleInsights: {
8481
enabled: true,
8582
modelId: TEST_MODEL_ID,
@@ -97,11 +94,10 @@ describeWithEnvironment('AidaClient', () => {
9794
client_feature: 1,
9895
functionality_type: 2,
9996
});
100-
stub.restore();
10197
});
10298

10399
it('adds metadata to disallow logging', () => {
104-
const stub = getGetHostConfigStub({
100+
Object.assign(Root.Runtime.hostConfig, {
105101
aidaAvailability: {
106102
disallowLogging: true,
107103
},
@@ -123,7 +119,6 @@ describeWithEnvironment('AidaClient', () => {
123119
client_feature: 1,
124120
functionality_type: 2,
125121
});
126-
stub.restore();
127122
});
128123

129124
async function getAllResults(provider: Host.AidaClient.AidaClient): Promise<Host.AidaClient.AidaResponse[]> {

front_end/core/host/AidaClient.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// found in the LICENSE file.
44

55
import * as Common from '../common/common.js';
6-
import type * as Root from '../root/root.js';
6+
import * as Root from '../root/root.js';
77

88
import {InspectorFrontendHostInstance} from './InspectorFrontendHost.js';
99
import type {AidaClientResult, SyncInformation} from './InspectorFrontendHostAPI.js';
@@ -268,14 +268,14 @@ export class AidaClient {
268268
functionality_type: FunctionalityType.EXPLAIN_ERROR,
269269
client_feature: ClientFeature.CHROME_CONSOLE_INSIGHTS,
270270
};
271-
const config = Common.Settings.Settings.instance().getHostConfig();
271+
const {hostConfig} = Root.Runtime;
272272
let temperature = -1;
273273
let modelId = '';
274-
if (config.devToolsConsoleInsights?.enabled) {
275-
temperature = config.devToolsConsoleInsights.temperature ?? -1;
276-
modelId = config.devToolsConsoleInsights.modelId || '';
274+
if (hostConfig.devToolsConsoleInsights?.enabled) {
275+
temperature = hostConfig.devToolsConsoleInsights.temperature ?? -1;
276+
modelId = hostConfig.devToolsConsoleInsights.modelId || '';
277277
}
278-
const disallowLogging = config.aidaAvailability?.disallowLogging ?? true;
278+
const disallowLogging = hostConfig.aidaAvailability?.disallowLogging ?? true;
279279

280280
if (temperature >= 0) {
281281
request.options ??= {};
@@ -498,9 +498,9 @@ export class HostConfigTracker extends Common.ObjectWrapper.ObjectWrapper<EventT
498498
const currentAidaAvailability = await AidaClient.checkAccessPreconditions();
499499
if (currentAidaAvailability !== this.#aidaAvailability) {
500500
this.#aidaAvailability = currentAidaAvailability;
501-
const config = await new Promise<Root.Runtime.HostConfig>(
502-
resolve => InspectorFrontendHostInstance.getHostConfig(config => resolve(config)));
503-
Common.Settings.Settings.instance().setHostConfig(config);
501+
const config =
502+
await new Promise<Root.Runtime.HostConfig>(resolve => InspectorFrontendHostInstance.getHostConfig(resolve));
503+
Object.assign(Root.Runtime.hostConfig, config);
504504
this.dispatchEventToListeners(Events.AIDA_AVAILABILITY_CHANGED);
505505
}
506506
}

front_end/core/root/Runtime.ts

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,7 @@ export class Runtime {
8080
return runtimePlatform;
8181
}
8282

83-
static isDescriptorEnabled(
84-
descriptor: {
85-
experiment: ((string | undefined)|null),
86-
condition?: Condition,
87-
},
88-
config?: HostConfig): boolean {
83+
static isDescriptorEnabled(descriptor: {experiment?: string|null, condition?: Condition}): boolean {
8984
const {experiment} = descriptor;
9085
if (experiment === '*') {
9186
return true;
@@ -97,7 +92,7 @@ export class Runtime {
9792
return false;
9893
}
9994
const {condition} = descriptor;
100-
return condition ? condition(config) : true;
95+
return condition ? condition(hostConfig) : true;
10196
}
10297

10398
loadLegacyModule(modulePath: string): Promise<void> {
@@ -412,13 +407,19 @@ export interface HostConfigThirdPartyCookieControls {
412407
managedBlockThirdPartyCookies: string|boolean;
413408
}
414409

415-
// We use `RecursivePartial` here to enforce that DevTools code is able to
416-
// handle `HostConfig` objects of an unexpected shape. This can happen if
417-
// the implementation in the Chromium backend is changed without correctly
418-
// updating the DevTools frontend. Or if remote debugging a different version
419-
// of Chrome, resulting in the local browser window and the local DevTools
420-
// window being of different versions, and consequently potentially having
421-
// differently shaped `HostConfig`s.
410+
/**
411+
* The host configuration that we expect from the DevTools back-end.
412+
*
413+
* We use `RecursivePartial` here to enforce that DevTools code is able to
414+
* handle `HostConfig` objects of an unexpected shape. This can happen if
415+
* the implementation in the Chromium backend is changed without correctly
416+
* updating the DevTools frontend. Or if remote debugging a different version
417+
* of Chrome, resulting in the local browser window and the local DevTools
418+
* window being of different versions, and consequently potentially having
419+
* differently shaped `HostConfig`s.
420+
*
421+
* @see hostConfig
422+
*/
422423
export type HostConfig = Platform.TypeScriptUtilities.RecursivePartial<{
423424
aidaAvailability: AidaAvailability,
424425
devToolsConsoleInsights: HostConfigConsoleInsights,
@@ -440,6 +441,22 @@ export type HostConfig = Platform.TypeScriptUtilities.RecursivePartial<{
440441
thirdPartyCookieControls: HostConfigThirdPartyCookieControls,
441442
}>;
442443

444+
/**
445+
* The host configuration for this DevTools instance.
446+
*
447+
* This is initialized early during app startup and should not be modified
448+
* afterwards. In some cases it can be necessary to re-request the host
449+
* configuration from Chrome while DevTools is already running. In these
450+
* cases, the new host configuration should be reflected here, e.g.:
451+
*
452+
* ```js
453+
* const config = await new Promise<Root.Runtime.HostConfig>(
454+
* resolve => InspectorFrontendHostInstance.getHostConfig(resolve));
455+
* Object.assign(Root.runtime.hostConfig, config);
456+
* ```
457+
*/
458+
export const hostConfig: HostConfig = Object.create(null);
459+
443460
/**
444461
* When defining conditions make sure that objects used by the function have
445462
* been instantiated.

front_end/core/sdk/CSSModel.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import * as TextUtils from '../../models/text_utils/text_utils.js';
3838
import * as Common from '../common/common.js';
3939
import * as Host from '../host/host.js';
4040
import * as Platform from '../platform/platform.js';
41+
import * as Root from '../root/root.js';
4142

4243
import {CSSFontFace} from './CSSFontFace.js';
4344
import {CSSMatchedStyles} from './CSSMatchedStyles.js';
@@ -355,8 +356,7 @@ export class CSSModel extends SDKModel<EventTypes> {
355356
return null;
356357
}
357358

358-
const shouldGetAnimatedStyles =
359-
Common.Settings.Settings.instance().getHostConfig().devToolsAnimationStylesInStylesTab?.enabled;
359+
const shouldGetAnimatedStyles = Root.Runtime.hostConfig.devToolsAnimationStylesInStylesTab?.enabled;
360360
const [matchedStylesResponse, animatedStylesResponse] = await Promise.all([
361361
this.agent.invoke_getMatchedStylesForNode({nodeId}),
362362
shouldGetAnimatedStyles ? this.agent.invoke_getAnimatedStylesForNode({nodeId}) : undefined,

0 commit comments

Comments
 (0)