diff --git a/packages/devtools_app/lib/src/app.dart b/packages/devtools_app/lib/src/app.dart index 16a5731cc15..7301769943a 100644 --- a/packages/devtools_app/lib/src/app.dart +++ b/packages/devtools_app/lib/src/app.dart @@ -716,11 +716,10 @@ List defaultScreens({ AppSizeScreen(), createController: (_) => AppSizeController(), ), - if (FeatureFlags.deepLinkValidation) - DevToolsScreen( - DeepLinksScreen(), - createController: (_) => DeepLinksController(), - ), + DevToolsScreen( + DeepLinksScreen(), + createController: (_) => DeepLinksController(), + ), DevToolsScreen( VMDeveloperToolsScreen(), createController: (_) => VMDeveloperToolsController(), diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_link_list_view.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_link_list_view.dart index d7480ff11e3..bcecc8e937d 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_link_list_view.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_link_list_view.dart @@ -6,7 +6,6 @@ import 'package:devtools_app_shared/ui.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../../shared/feature_flags.dart'; import '../../shared/globals.dart'; import '../../shared/primitives/utils.dart'; import '../../shared/table/table.dart'; @@ -264,28 +263,27 @@ class _DeepLinkListViewTopPanel extends StatelessWidget { configurations: controller.selectedProject.value!.androidVariants, onChanged: controller.updateSelectedAndroidVariantIndex, ), - if (FeatureFlags.deepLinkIosCheck) ...[ - const SizedBox(width: denseSpacing), - _ConfigurationDropdown( - title: 'iOS Configuration:', - valueListenable: controller.selectedIosConfigurationIndex, - configurations: - controller - .selectedProject - .value! - .iosBuildOptions - .configurations, - onChanged: controller.updateSelectedIosConfigurationIndex, - ), - const SizedBox(width: denseSpacing), - _ConfigurationDropdown( - title: 'iOS Target:', - valueListenable: controller.selectedIosTargetIndex, - configurations: - controller.selectedProject.value!.iosBuildOptions.targets, - onChanged: controller.updateSelectedIosTargetIndex, - ), - ], + + const SizedBox(width: denseSpacing), + _ConfigurationDropdown( + title: 'iOS Configuration:', + valueListenable: controller.selectedIosConfigurationIndex, + configurations: + controller + .selectedProject + .value! + .iosBuildOptions + .configurations, + onChanged: controller.updateSelectedIosConfigurationIndex, + ), + const SizedBox(width: denseSpacing), + _ConfigurationDropdown( + title: 'iOS Target:', + valueListenable: controller.selectedIosTargetIndex, + configurations: + controller.selectedProject.value!.iosBuildOptions.targets, + onChanged: controller.updateSelectedIosTargetIndex, + ), ], ), ); diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_controller.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_controller.dart index 863d6cf6a8a..4d4ce4dec34 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_controller.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_controller.dart @@ -13,7 +13,6 @@ import 'package:flutter/material.dart'; import '../../shared/analytics/analytics.dart' as ga; import '../../shared/analytics/constants.dart' as gac; import '../../shared/analytics/metrics.dart'; -import '../../shared/feature_flags.dart'; import '../../shared/framework/screen.dart'; import '../../shared/framework/screen_controllers.dart'; import '../../shared/globals.dart'; @@ -281,16 +280,14 @@ class DeepLinksController extends DevToolsScreenController selectedProject.value!.androidVariants, containsString: 'release', ); - if (FeatureFlags.deepLinkIosCheck) { - _selectedIosConfigurationIndex.value = _getDefaultConfigurationIndex( - selectedProject.value!.iosBuildOptions.configurations, - containsString: 'release', - ); - _selectedIosTargetIndex.value = _getDefaultConfigurationIndex( - selectedProject.value!.iosBuildOptions.configurations, - containsString: 'runner', - ); - } + _selectedIosConfigurationIndex.value = _getDefaultConfigurationIndex( + selectedProject.value!.iosBuildOptions.configurations, + containsString: 'release', + ); + _selectedIosTargetIndex.value = _getDefaultConfigurationIndex( + selectedProject.value!.iosBuildOptions.configurations, + containsString: 'runner', + ); await loadLinksAndValidate(); } @@ -398,11 +395,9 @@ class DeepLinksController extends DevToolsScreenController if (pagePhase.value == PagePhase.validationErrorPage) { return; } - if (FeatureFlags.deepLinkIosCheck) { - await _loadIosLinks(); - if (pagePhase.value == PagePhase.validationErrorPage) { - return; - } + await _loadIosLinks(); + if (pagePhase.value == PagePhase.validationErrorPage) { + return; } await validateLinks(); } @@ -575,8 +570,7 @@ class DeepLinksController extends DevToolsScreenController googlePlayFingerprintsAvailability.value = androidResult.googlePlayFingerprintsAvailability; } - if (FeatureFlags.deepLinkIosCheck && - currentUniversalLinkSettings != null) { + if (currentUniversalLinkSettings != null) { ga.impression( gac.deeplink, gac.AnalyzeFlutterProject.iosValidateDomain.name, @@ -683,10 +677,7 @@ class DeepLinksController extends DevToolsScreenController return; } pagePhase.value = PagePhase.linksValidating; - List linkdata = [ - ..._rawAndroidLinkDatas, - if (FeatureFlags.deepLinkIosCheck) ..._rawIosLinkDatas, - ]; + List linkdata = [..._rawAndroidLinkDatas, ..._rawIosLinkDatas]; if (linkdata.isEmpty) { ga.select(gac.deeplink, gac.AnalyzeFlutterProject.flutterNoAppLink.name); pagePhase.value = PagePhase.noLinks; diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/select_project_view.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/select_project_view.dart index dd43ff0ddeb..3da6e205dba 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/select_project_view.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/select_project_view.dart @@ -10,7 +10,6 @@ import 'package:flutter/material.dart'; import '../../../shared/analytics/analytics.dart' as ga; import '../../../shared/analytics/constants.dart' as gac; -import '../../../shared/feature_flags.dart'; import '../../../shared/globals.dart'; import '../../../shared/primitives/utils.dart'; import '../../../shared/server/server.dart' as server; @@ -122,14 +121,11 @@ class _SelectProjectViewState extends State { return; } XcodeBuildOptions iosBuildOptions = XcodeBuildOptions.empty; - if (FeatureFlags.deepLinkIosCheck) { - iosBuildOptions = await _requestiOSBuildOptions(directory); - ga.select( - gac.deeplink, - gac.AnalyzeFlutterProject.flutterProjectSelected.name, - ); - } - + iosBuildOptions = await _requestiOSBuildOptions(directory); + ga.select( + gac.deeplink, + gac.AnalyzeFlutterProject.flutterProjectSelected.name, + ); if (androidVariants.isEmpty && iosBuildOptions.configurations.isEmpty) { ga.select( gac.deeplink, diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/validation_details_view.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/validation_details_view.dart index e34ed9a249f..b8f0915bb4e 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/validation_details_view.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/validation_details_view.dart @@ -7,7 +7,6 @@ import 'dart:async'; import 'package:devtools_app_shared/ui.dart'; import 'package:flutter/material.dart'; -import '../../shared/feature_flags.dart'; import '../../shared/ui/colors.dart'; import '../../shared/ui/common_widgets.dart'; import '../../shared/utils/utils.dart'; @@ -60,8 +59,7 @@ class ValidationDetailView extends StatelessWidget { if (viewType == TableViewType.pathView || viewType == TableViewType.singleUrlView) _PathCheckTable(controller: controller), - if (FeatureFlags.deepLinkIosCheck && - viewType == TableViewType.domainView) + if (viewType == TableViewType.domainView) _CrossCheckTable(controller: controller), const SizedBox(height: extraLargeSpacing), Align( @@ -167,8 +165,7 @@ class _DomainCheckTable extends StatelessWidget { ], ], ), - if (FeatureFlags.deepLinkIosCheck && - linkData.os.contains(PlatformOS.ios)) + if (linkData.os.contains(PlatformOS.ios)) _CheckExpansionTile( os: PlatformOS.ios, checkName: 'Apple-App-Site-Association file', diff --git a/packages/devtools_app/lib/src/screens/performance/panes/controls/more_debugging_options.dart b/packages/devtools_app/lib/src/screens/performance/panes/controls/more_debugging_options.dart index 43e693d6c0c..cdc358cf783 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/controls/more_debugging_options.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/controls/more_debugging_options.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import '../../../../service/service_extension_widgets.dart'; import '../../../../service/service_extensions.dart' as extensions; -import '../../../../shared/feature_flags.dart'; import '../../../../shared/globals.dart'; import 'performance_controls.dart'; @@ -29,7 +28,7 @@ class MoreDebuggingOptionsButton extends StatelessWidget { extensions.disableClipLayers, extensions.disableOpacityLayers, extensions.disablePhysicalShapeLayers, - if (FeatureFlags.widgetRebuildStats) extensions.countWidgetBuilds, + extensions.countWidgetBuilds, ], overlayDescription: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_analysis.dart b/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_analysis.dart index 0c4321f3aa4..4ebc6896ea3 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_analysis.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_analysis.dart @@ -9,7 +9,6 @@ import 'package:flutter/material.dart'; import '../../../../service/service_extension_widgets.dart'; import '../../../../service/service_extensions.dart' as extensions; -import '../../../../shared/feature_flags.dart'; import '../../../../shared/globals.dart'; import '../../../../shared/primitives/utils.dart'; import '../controls/enhance_tracing/enhance_tracing_controller.dart'; @@ -90,52 +89,50 @@ class FlutterFrameAnalysisView extends StatelessWidget { const PaddedDivider.noPadding(), FrameTimeVisualizer(frameAnalysis: frameAnalysis), ], - if (FeatureFlags.widgetRebuildStats) ...[ - if (rebuilds.isNullOrEmpty) ...[ - const PaddedDivider.noPadding(), - ValueListenableBuilder( - valueListenable: serviceConnection - .serviceManager - .serviceExtensionManager - .getServiceExtensionState( - extensions.countWidgetBuilds.extension, - ), - builder: (context, extensionState, _) { - if (!extensionState.enabled) { - return Row( - children: [ - const Text( - 'To see widget rebuilds for Flutter frames, enable', - ), - Flexible( - child: ServiceExtensionCheckbox( - serviceExtension: extensions.countWidgetBuilds, - showDescription: false, - ), + if (rebuilds.isNullOrEmpty) ...[ + const PaddedDivider.noPadding(), + ValueListenableBuilder( + valueListenable: serviceConnection + .serviceManager + .serviceExtensionManager + .getServiceExtensionState( + extensions.countWidgetBuilds.extension, + ), + builder: (context, extensionState, _) { + if (!extensionState.enabled) { + return Row( + children: [ + const Text( + 'To see widget rebuilds for Flutter frames, enable', + ), + Flexible( + child: ServiceExtensionCheckbox( + serviceExtension: extensions.countWidgetBuilds, + showDescription: false, ), - ], - ); - } - return const SizedBox(); - }, - ), - ], - if (rebuilds == null) - const Text('Rebuild information not available for this frame.') - else if (rebuilds.isEmpty) - const Text( - 'No widget rebuilds occurred for widgets that were directly ' - 'created in your project.', - ) - else ...[ - const SizedBox(height: defaultSpacing), - Expanded( - child: RebuildTable( - metricNames: const ['Rebuild Count'], - metrics: combineStats([rebuilds]), - ), + ), + ], + ); + } + return const SizedBox(); + }, + ), + ], + if (rebuilds == null) + const Text('Rebuild information not available for this frame.') + else if (rebuilds.isEmpty) + const Text( + 'No widget rebuilds occurred for widgets that were directly ' + 'created in your project.', + ) + else ...[ + const SizedBox(height: defaultSpacing), + Expanded( + child: RebuildTable( + metricNames: const ['Rebuild Count'], + metrics: combineStats([rebuilds]), ), - ], + ), ], ], ), diff --git a/packages/devtools_app/lib/src/screens/performance/performance_controller.dart b/packages/devtools_app/lib/src/screens/performance/performance_controller.dart index e538088d5ad..6f52f451267 100644 --- a/packages/devtools_app/lib/src/screens/performance/performance_controller.dart +++ b/packages/devtools_app/lib/src/screens/performance/performance_controller.dart @@ -145,8 +145,7 @@ class PerformanceController extends DevToolsScreenController final frame = FlutterFrame.fromJson(event.extensionData!.data); enhanceTracingController.assignStateForFrame(frame); flutterFramesController.addFrame(frame); - } else if (event.extensionKind == FlutterEvent.rebuiltWidgets && - FeatureFlags.widgetRebuildStats) { + } else if (event.extensionKind == FlutterEvent.rebuiltWidgets) { if (_currentRebuildWidgetsIsolate != event.isolate) { rebuildCountModel.clearFromRestart(); } diff --git a/packages/devtools_app/lib/src/screens/performance/tabbed_performance_view.dart b/packages/devtools_app/lib/src/screens/performance/tabbed_performance_view.dart index ca0e79fff0e..f9f15a924f8 100644 --- a/packages/devtools_app/lib/src/screens/performance/tabbed_performance_view.dart +++ b/packages/devtools_app/lib/src/screens/performance/tabbed_performance_view.dart @@ -9,7 +9,6 @@ import 'package:devtools_app_shared/utils.dart'; import 'package:flutter/material.dart'; import '../../shared/analytics/constants.dart' as gac; -import '../../shared/feature_flags.dart'; import '../../shared/globals.dart'; import '../../shared/ui/common_widgets.dart'; import '../../shared/ui/tab.dart'; @@ -58,7 +57,7 @@ class _TabbedPerformanceViewState extends State serviceConnection.serviceManager.connectedApp!.isFlutterAppNow!; var showFrameAnalysis = isFlutterApp; - var showRebuildStats = FeatureFlags.widgetRebuildStats && isFlutterApp; + var showRebuildStats = isFlutterApp; final offlineData = controller.offlinePerformanceData; if (isOffline) { final hasOfflineData = offlineData != null; diff --git a/packages/devtools_app/lib/src/shared/feature_flags.dart b/packages/devtools_app/lib/src/shared/feature_flags.dart index eb271be8de8..d3dc5730d6c 100644 --- a/packages/devtools_app/lib/src/shared/feature_flags.dart +++ b/packages/devtools_app/lib/src/shared/feature_flags.dart @@ -36,11 +36,6 @@ void setEnableExperiments() { @visibleForTesting bool get enableBeta => enableExperiments || !isExternalBuild; -const _kMemoryDisconnectExperience = bool.fromEnvironment( - 'memory_disconnect_experience', - defaultValue: true, -); - const _kNetworkDisconnectExperience = bool.fromEnvironment( 'network_disconnect_experience', defaultValue: true, @@ -53,29 +48,12 @@ const _kNetworkDisconnectExperience = bool.fromEnvironment( /// When adding a new feature flag, the developer is responsible for adding it /// to the [_allFlags] map for debugging purposes. abstract class FeatureFlags { - /// Example usage of a flag for a beta feature. - static bool myBetaFeature = enableBeta; - - /// Example usage of a flag for an experimental feature. - static bool myExperimentalFeature = enableExperiments; - /// Flag to enable the DevTools memory observer, which attempts to help users /// avoid OOM crashes. /// /// https://github.com/flutter/devtools/issues/7002 static bool memoryObserver = true; - /// Flag to enable widget rebuild stats ui. - /// - /// https://github.com/flutter/devtools/issues/4564. - static bool widgetRebuildStats = true; - - /// Flag to enable viewing offline data on the memory screen when an app - /// disconnects. - /// - /// https://github.com/flutter/devtools/issues/5606 - static const memoryDisconnectExperience = _kMemoryDisconnectExperience; - /// Flag to enable save/load for the Memory screen. /// /// https://github.com/flutter/devtools/issues/8019 @@ -92,17 +70,6 @@ abstract class FeatureFlags { /// https://github.com/flutter/devtools/issues/4470 static bool networkSaveLoad = true; - /// Flag to enable the deep link validation tooling in DevTools, both for the - /// DevTools screen and the standalone tool for IDE embedding. - /// - /// https://github.com/flutter/devtools/issues/6013 - static bool deepLinkValidation = true; - - /// Flag to enable ios checks in deep link validation. - /// - /// https://github.com/flutter/devtools/issues/7799 - static bool deepLinkIosCheck = true; - /// Flag to enable DevTools extensions. /// /// TODO(https://github.com/flutter/devtools/issues/6443): remove this flag @@ -134,9 +101,10 @@ abstract class FeatureFlags { /// When adding a new flag, you are responsible for adding it to this map as /// well. static final _allFlags = { - 'widgetRebuildStats': widgetRebuildStats, + 'memoryObserver': memoryObserver, 'memorySaveLoad': memorySaveLoad, - 'deepLinkIosCheck': deepLinkIosCheck, + 'networkDisconnectExperience': networkDisconnectExperience, + 'networkSaveLoad': networkSaveLoad, 'dapDebugging': dapDebugging, 'inspectorV2': inspectorV2, 'wasmOptInSetting': wasmOptInSetting, diff --git a/packages/devtools_app/lib/src/shared/framework/screen.dart b/packages/devtools_app/lib/src/shared/framework/screen.dart index 2027feef967..c13102ec25c 100644 --- a/packages/devtools_app/lib/src/shared/framework/screen.dart +++ b/packages/devtools_app/lib/src/shared/framework/screen.dart @@ -62,9 +62,9 @@ enum ScreenMetaData { title: 'Memory', iconAsset: 'icons/app_bar/memory.png', requiresDartVm: true, - requiresConnection: !FeatureFlags.memoryDisconnectExperience, + requiresConnection: false, tutorialVideoTimestamp: '?t=420', - worksWithOfflineData: FeatureFlags.memoryDisconnectExperience, + worksWithOfflineData: true, ), debugger( 'debugger', @@ -79,7 +79,6 @@ enum ScreenMetaData { iconAsset: 'icons/app_bar/network.png', requiresDartVm: true, tutorialVideoTimestamp: '?t=547', - // ignore: avoid_redundant_argument_values, false positive requiresConnection: false, // ignore: avoid_redundant_argument_values, false positive worksWithOfflineData: FeatureFlags.networkDisconnectExperience, diff --git a/packages/devtools_app/test/screens/deep_link_validation/deep_links_screen_test.dart b/packages/devtools_app/test/screens/deep_link_validation/deep_links_screen_test.dart index d62d92dfc12..e9d339d6b19 100644 --- a/packages/devtools_app/test/screens/deep_link_validation/deep_links_screen_test.dart +++ b/packages/devtools_app/test/screens/deep_link_validation/deep_links_screen_test.dart @@ -10,7 +10,6 @@ import 'package:devtools_app/src/screens/deep_link_validation/deep_links_model.d import 'package:devtools_app/src/screens/deep_link_validation/project_root_selection/root_selector.dart'; import 'package:devtools_app/src/screens/deep_link_validation/project_root_selection/select_project_view.dart'; import 'package:devtools_app/src/screens/deep_link_validation/validation_details_view.dart'; -import 'package:devtools_app/src/shared/feature_flags.dart'; import 'package:devtools_app_shared/service.dart'; import 'package:devtools_app_shared/ui.dart'; import 'package:devtools_app_shared/utils.dart'; @@ -53,7 +52,6 @@ void main() { return UriList(uris: mockProjectRootUris); }); setGlobal(DTDManager, mockDtdManager); - FeatureFlags.deepLinkIosCheck = true; }); late DeepLinksScreen screen; diff --git a/packages/devtools_app/test/shared/primitives/feature_flags_test.dart b/packages/devtools_app/test/shared/primitives/feature_flags_test.dart index 282b76d875b..cd745451118 100644 --- a/packages/devtools_app/test/shared/primitives/feature_flags_test.dart +++ b/packages/devtools_app/test/shared/primitives/feature_flags_test.dart @@ -11,11 +11,14 @@ void main() { expect(enableExperiments, false); expect(enableBeta, false); expect(isExternalBuild, true); + expect(FeatureFlags.memoryObserver, true); expect(FeatureFlags.memorySaveLoad, false); - expect(FeatureFlags.deepLinkIosCheck, true); + expect(FeatureFlags.networkDisconnectExperience, true); + expect(FeatureFlags.networkSaveLoad, true); + expect(FeatureFlags.devToolsExtensions, isExternalBuild); expect(FeatureFlags.dapDebugging, false); - expect(FeatureFlags.wasmOptInSetting, true); expect(FeatureFlags.inspectorV2, true); + expect(FeatureFlags.wasmOptInSetting, true); expect(FeatureFlags.propertyEditor, false); }); } diff --git a/packages/devtools_app/test/test_infra/scenes/performance/default.dart b/packages/devtools_app/test/test_infra/scenes/performance/default.dart index 73dfe704278..aec9c04b805 100644 --- a/packages/devtools_app/test/test_infra/scenes/performance/default.dart +++ b/packages/devtools_app/test/test_infra/scenes/performance/default.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'package:devtools_app/devtools_app.dart'; import 'package:devtools_app/src/shared/config_specific/import_export/import_export.dart'; -import 'package:devtools_app/src/shared/feature_flags.dart'; import 'package:devtools_app_shared/ui.dart'; import 'package:devtools_app_shared/utils.dart'; import 'package:devtools_test/helpers.dart'; @@ -29,8 +28,6 @@ class PerformanceDefaultScene extends Scene { @override Future setUp() async { - FeatureFlags.widgetRebuildStats = true; - setGlobal(OfflineDataController, OfflineDataController()); setGlobal(IdeTheme, IdeTheme()); setGlobal(NotificationService, NotificationService()); @@ -44,11 +41,6 @@ class PerformanceDefaultScene extends Scene { @override String get title => '$PerformanceDefaultScene'; - - // TODO(kenz): call tearDown on the scenes that use this scene - void tearDown() { - FeatureFlags.widgetRebuildStats = false; - } } Future _loadOfflineSnapshot() async {