blob: 1696215fab333bedf374268155603092e7c0ede3 [file] [log] [blame] [edit]
// Copyright 2023 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
import 'dart:async';
import 'package:devtools_app_shared/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
import 'src/app.dart';
import 'src/framework/framework_core.dart';
import 'src/screens/debugger/syntax_highlighter.dart';
import 'src/shared/analytics/analytics_controller.dart';
import 'src/shared/config_specific/logger/logger_helpers.dart';
import 'src/shared/feature_flags.dart';
import 'src/shared/framework/app_error_handling.dart';
import 'src/shared/globals.dart';
import 'src/shared/primitives/url_utils.dart';
import 'src/shared/primitives/utils.dart';
/// Handles necessary initialization then runs DevTools.
///
/// Any initialization that needs to happen before running DevTools, regardless
/// of context, should happen here.
///
/// If any initialization is specific to running Devtools in google3 or
/// externally, then it should be added to that respective main.dart file.
/// Alternatively, the [onDevToolsInitialized] callback can be used to perform
/// additional logic that runs after DevTools initialization but before running
/// the app.
void runDevTools({
bool integrationTestMode = false,
bool shouldEnableExperiments = false,
List<DevToolsJsonFile> sampleData = const [],
List<DevToolsScreen>? screens,
Future<void> Function()? onDevToolsInitialized,
}) {
setupErrorHandling(() async {
await initializeDevTools(
integrationTestMode: integrationTestMode,
shouldEnableExperiments: shouldEnableExperiments,
);
// Load the Dart syntax highlighting grammar.
await SyntaxHighlighter.initialize();
await onDevToolsInitialized?.call();
// Run the app.
runApp(
DevToolsApp(
screens ?? defaultScreens(sampleData: sampleData),
await analyticsController,
),
);
});
}
@visibleForTesting
Future<void> initializeDevTools({
bool integrationTestMode = false,
bool shouldEnableExperiments = false,
}) async {
initDevToolsLogging();
// Before switching to URL path strategy, check if this URL is in the legacy
// fragment format and redirect if necessary.
if (_handleLegacyUrl()) return;
usePathUrlStrategy();
_maybeInitForIntegrationTestMode(
integrationTestMode: integrationTestMode,
enableExperiments: shouldEnableExperiments,
);
await FrameworkCore.init();
}
/// Initializes some DevTools global fields for our Flutter integration tests.
///
/// Since we call [runDevTools] from Dart code, we cannot set environment
/// variables before calling [runDevTools], and therefore have to pass in these
/// values manually to [runDevTools].
void _maybeInitForIntegrationTestMode({
required bool integrationTestMode,
required bool enableExperiments,
}) {
if (!integrationTestMode) return;
setIntegrationTestMode();
if (enableExperiments) {
setEnableExperiments();
}
}
/// Checks if the request is for a legacy URL and if so, redirects to the new
/// equivalent.
///
/// Returns `true` if a redirect was performed, in which case normal app
/// initialization should be skipped.
bool _handleLegacyUrl() {
final url = getWebUrl();
if (url == null) return false;
final newUrl = mapLegacyUrl(url);
if (newUrl != null) {
webRedirect(newUrl);
return true;
}
return false;
}