Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/devtools_app/benchmark/test_infra/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/// found" in DevTools.
const _benchmarkInitialPage = '';

const _wasmQueryParameters = {'wasm': 'true'};
const _wasmQueryParameters = {'compiler': 'wasm'};

String benchmarkPath({required bool useWasm}) => Uri(
path: _benchmarkInitialPage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@ class PreferencesController extends DisposableController

Future<void> _initWasmEnabled() async {
wasmEnabled.value = kIsWasm;

// If the user forced the dart2js-compiled DevTools via query parameter,
// then set the storage value to match. This will persist across multiple
// sessions of DevTools.
if (DevToolsQueryParams.load().useJs) {
safeUnawaited(
storage.setValue(_ExperimentPreferences.wasm.storageKey, 'false'),
);
}

addAutoDisposeListener(wasmEnabled, () async {
final enabled = wasmEnabled.value;
_log.fine('preference update (wasmEnabled = $enabled)');
Expand All @@ -188,8 +198,8 @@ class PreferencesController extends DisposableController
'Reloading DevTools for Wasm preference update (enabled = $enabled)',
);
updateQueryParameter(
DevToolsQueryParams.wasmKey,
enabled ? 'true' : null,
DevToolsQueryParams.compilerKey,
enabled ? 'wasm' : null,
reload: true,
);
}
Expand All @@ -207,7 +217,7 @@ class PreferencesController extends DisposableController
// back to JS. We know this because the flutter_bootstrap.js logic always
// sets the 'wasm' query parameter to 'true' when attempting to load
// DevTools with wasm. Remove the wasm query parameter and return early.
updateQueryParameter(DevToolsQueryParams.wasmKey, null);
updateQueryParameter(DevToolsQueryParams.compilerKey, null);
ga.impression(gac.devToolsMain, gac.jsFallback);

// Do not show the JS fallback notification when embedded in VS Code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,14 @@ extension type DevToolsQueryParams(Map<String, String?> params) {

/// Whether DevTools should be loaded using dart2wasm + skwasm instead of
/// dart2js + canvaskit.
bool get useWasm => params[wasmKey] == 'true';
bool get useWasm => params[compilerKey] == 'wasm';

/// Whether DevTools should be loaded using dart2js + canvaskit instead of
/// dart2wasm + skwasm.
///
/// This should only ever be explicitly set by the user if their app fails to
/// load using wasm.
bool get useJs => params[compilerKey] == 'js';

static const vmServiceUriKey = 'uri';
static const hideScreensKey = 'hide';
Expand All @@ -75,10 +82,14 @@ extension type DevToolsQueryParams(Map<String, String?> params) {
static const ideKey = 'ide';
static const ideFeatureKey = 'ideFeature';

// This query parameter must match the String value in the Flutter bootstrap
// logic that is used to select a web renderer. See
// devtools/packages/devtools_app/web/flutter_bootstrap.js.
static const wasmKey = 'wasm';
/// Query parameter key to determine whether to use dart2wasm or dart2js.
///
/// This query parameter must match the String value in the Flutter bootstrap
/// logic that is used to select a web renderer. See
/// devtools/packages/devtools_app/web/flutter_bootstrap.js.
///
/// Valid values are "js" or "wasm".
static const compilerKey = 'compiler';

// TODO(kenz): remove legacy value in May of 2025 when all IDEs are not using
// these and 12 months have passed to allow users ample upgrade time.
Expand Down
34 changes: 25 additions & 9 deletions packages/devtools_app/web/flutter_bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ function unregisterDevToolsServiceWorker() {
}

// This query parameter must match the String value specified by
// `DevToolsQueryParameters.wasmKey`. See
// `DevToolsQueryParameters.compilerKey`. See
// devtools/packages/devtools_app/lib/src/shared/query_parameters.dart
const wasmQueryParameterKey = 'wasm';
const compilerQueryParameterKey = 'compiler';

// Returns the value for the given search param.
function getSearchParam(searchParamKey) {
const searchParams = new URLSearchParams(window.location.search);
return searchParams.get(searchParamKey);
}

// Calls the DevTools server API to read the user's wasm preference.
async function getDevToolsWasmPreference() {
Expand All @@ -49,12 +55,20 @@ async function getDevToolsWasmPreference() {
}
}

// The query parameter compiler=js gives us an escape hatch we can offer users if their
// dart2wasm app fails to load.
const forceUseJs = () => getSearchParam(compilerQueryParameterKey) === 'js';

// Returns whether DevTools should be loaded with the skwasm renderer based on the
// value of the 'wasm' query parameter or the wasm setting from the DevTools
// preference file.
async function shouldUseSkwasm() {
const searchParams = new URLSearchParams(window.location.search);
const wasmEnabledFromQueryParameter = searchParams.get(wasmQueryParameterKey) === 'true';
// If dart2js has specifically been requested via query parameter, then do not try to
// use skwasm (even if the local setting is for wasm).
if (forceUseJs()) {
return false;
}
const wasmEnabledFromQueryParameter = getSearchParam(compilerQueryParameterKey) === 'wasm';
const wasmEnabledFromDevToolsPreference = await getDevToolsWasmPreference();
return wasmEnabledFromQueryParameter === true || wasmEnabledFromDevToolsPreference === true;
}
Expand All @@ -64,9 +78,9 @@ async function shouldUseSkwasm() {
function updateWasmQueryParameter(useSkwasm) {
const url = new URL(window.location.href);
if (useSkwasm) {
url.searchParams.set(wasmQueryParameterKey, 'true');
url.searchParams.set(compilerQueryParameterKey, 'wasm');
} else {
url.searchParams.delete(wasmQueryParameterKey);
url.searchParams.delete(compilerQueryParameterKey);
}
// Update the browser's history without reloading. This is a no-op if the wasm
// query parameter does not actually need to be updated.
Expand All @@ -77,9 +91,11 @@ function updateWasmQueryParameter(useSkwasm) {
async function bootstrapAppFor3P() {
const useSkwasm = await shouldUseSkwasm();

// Ensure the 'wasm' query parameter in the URL is accurate for the renderer
// DevTools will be loaded with.
updateWasmQueryParameter(useSkwasm);
if (!forceUseJs()) {
// Ensure the 'wasm' query parameter in the URL is accurate for the renderer
// DevTools will be loaded with.
updateWasmQueryParameter(useSkwasm);
}

const rendererForLog = useSkwasm ? 'skwasm' : 'canvaskit';
console.log('Attempting to load DevTools with ' + rendererForLog + ' renderer.');
Expand Down
Loading