diff --git a/packages/devtools_app/lib/main.dart b/packages/devtools_app/lib/main.dart index 1c161954f2b..ef6b68c2c72 100644 --- a/packages/devtools_app/lib/main.dart +++ b/packages/devtools_app/lib/main.dart @@ -4,8 +4,8 @@ import 'package:flutter/material.dart'; -import 'src/config_specific/flutter/framework_initialize/framework_initialize.dart'; -import 'src/flutter/app.dart'; +import 'src/app.dart'; +import 'src/config_specific/framework_initialize/framework_initialize.dart'; void main() async { await initializeFramework(); diff --git a/packages/devtools_app/lib/src/flutter/app.dart b/packages/devtools_app/lib/src/app.dart similarity index 93% rename from packages/devtools_app/lib/src/flutter/app.dart rename to packages/devtools_app/lib/src/app.dart index 51aaa86ce18..7937e303086 100644 --- a/packages/devtools_app/lib/src/flutter/app.dart +++ b/packages/devtools_app/lib/src/app.dart @@ -7,32 +7,32 @@ import 'package:flutter/material.dart'; import 'package:pedantic/pedantic.dart'; import 'package:provider/provider.dart'; -import '../../devtools.dart' as devtools; -import '../debugger/flutter/debugger_controller.dart'; -import '../debugger/flutter/debugger_screen.dart'; -import '../framework/framework_core.dart'; -import '../globals.dart'; -import '../inspector/flutter/inspector_screen.dart'; -import '../logging/flutter/logging_screen.dart'; -import '../logging/logging_controller.dart'; -import '../memory/flutter/memory_controller.dart'; -import '../memory/flutter/memory_screen.dart'; -import '../network/flutter/network_screen.dart'; -import '../network/network_controller.dart'; -import '../performance/flutter/performance_screen.dart'; -import '../performance/performance_controller.dart'; -import '../timeline/flutter/timeline_controller.dart'; -import '../timeline/flutter/timeline_screen.dart'; -import '../ui/flutter/service_extension_widgets.dart'; +import '../devtools.dart' as devtools; import 'common_widgets.dart'; import 'connect_screen.dart'; +import 'debugger/debugger_controller.dart'; +import 'debugger/debugger_screen.dart'; +import 'framework/framework_core.dart'; +import 'globals.dart'; import 'initializer.dart'; +import 'inspector/inspector_screen.dart'; +import 'logging/logging_controller.dart'; +import 'logging/logging_screen.dart'; +import 'memory/memory_controller.dart'; +import 'memory/memory_screen.dart'; +import 'network/network_controller.dart'; +import 'network/network_screen.dart'; import 'notifications.dart'; +import 'performance/performance_controller.dart'; +import 'performance/performance_screen.dart'; import 'preferences.dart'; import 'scaffold.dart'; import 'screen.dart'; import 'snapshot_screen.dart'; import 'theme.dart'; +import 'timeline/timeline_controller.dart'; +import 'timeline/timeline_screen.dart'; +import 'ui/service_extension_widgets.dart'; import 'utils.dart'; const homeRoute = '/'; diff --git a/packages/devtools_app/lib/src/flutter/auto_dispose_mixin.dart b/packages/devtools_app/lib/src/auto_dispose_mixin.dart similarity index 97% rename from packages/devtools_app/lib/src/flutter/auto_dispose_mixin.dart rename to packages/devtools_app/lib/src/auto_dispose_mixin.dart index c1f1da0a84b..bd5cec3b4be 100644 --- a/packages/devtools_app/lib/src/flutter/auto_dispose_mixin.dart +++ b/packages/devtools_app/lib/src/auto_dispose_mixin.dart @@ -6,7 +6,7 @@ import 'dart:async'; import 'package:flutter/widgets.dart'; -import '../auto_dispose.dart'; +import 'auto_dispose.dart'; /// Mixin to simplifying managing the lifetime of listeners used by a /// [StatefulWidget]. diff --git a/packages/devtools_app/lib/src/flutter/banner_messages.dart b/packages/devtools_app/lib/src/banner_messages.dart similarity index 99% rename from packages/devtools_app/lib/src/flutter/banner_messages.dart rename to packages/devtools_app/lib/src/banner_messages.dart index 90322f1f0dc..89548e3c3f7 100644 --- a/packages/devtools_app/lib/src/flutter/banner_messages.dart +++ b/packages/devtools_app/lib/src/banner_messages.dart @@ -7,8 +7,8 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../globals.dart'; import 'common_widgets.dart'; +import 'globals.dart'; import 'screen.dart'; import 'theme.dart'; import 'utils.dart'; diff --git a/packages/devtools_app/lib/src/flutter/blocking_action_mixin.dart b/packages/devtools_app/lib/src/blocking_action_mixin.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/blocking_action_mixin.dart rename to packages/devtools_app/lib/src/blocking_action_mixin.dart diff --git a/packages/devtools_app/lib/src/charts/flutter/flame_chart.dart b/packages/devtools_app/lib/src/charts/flame_chart.dart similarity index 99% rename from packages/devtools_app/lib/src/charts/flutter/flame_chart.dart rename to packages/devtools_app/lib/src/charts/flame_chart.dart index f0308301e53..ffb3791dc4e 100644 --- a/packages/devtools_app/lib/src/charts/flutter/flame_chart.dart +++ b/packages/devtools_app/lib/src/charts/flame_chart.dart @@ -11,13 +11,13 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/extent_delegate_list.dart'; -import '../../flutter/flutter_widgets/linked_scroll_controller.dart'; -import '../../flutter/theme.dart'; -import '../../ui/colors.dart'; -import '../../utils.dart'; +import '../auto_dispose_mixin.dart'; +import '../common_widgets.dart'; +import '../extent_delegate_list.dart'; +import '../flutter_widgets/linked_scroll_controller.dart'; +import '../theme.dart'; +import '../ui/colors.dart'; +import '../utils.dart'; const double rowPadding = 2.0; const double rowHeight = 25.0; diff --git a/packages/devtools_app/lib/src/flutter/collapsible_mixin.dart b/packages/devtools_app/lib/src/collapsible_mixin.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/collapsible_mixin.dart rename to packages/devtools_app/lib/src/collapsible_mixin.dart diff --git a/packages/devtools_app/lib/src/flutter/common_widgets.dart b/packages/devtools_app/lib/src/common_widgets.dart similarity index 99% rename from packages/devtools_app/lib/src/flutter/common_widgets.dart rename to packages/devtools_app/lib/src/common_widgets.dart index e582063012e..757d8ced173 100644 --- a/packages/devtools_app/lib/src/flutter/common_widgets.dart +++ b/packages/devtools_app/lib/src/common_widgets.dart @@ -9,9 +9,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -import '../ui/flutter/label.dart'; import 'scaffold.dart'; import 'theme.dart'; +import 'ui/label.dart'; const tooltipWait = Duration(milliseconds: 500); diff --git a/packages/devtools_app/lib/src/config_specific/flutter/drag_and_drop/_drag_and_drop_desktop.dart b/packages/devtools_app/lib/src/config_specific/drag_and_drop/_drag_and_drop_desktop.dart similarity index 100% rename from packages/devtools_app/lib/src/config_specific/flutter/drag_and_drop/_drag_and_drop_desktop.dart rename to packages/devtools_app/lib/src/config_specific/drag_and_drop/_drag_and_drop_desktop.dart diff --git a/packages/devtools_app/lib/src/config_specific/flutter/drag_and_drop/_drag_and_drop_stub.dart b/packages/devtools_app/lib/src/config_specific/drag_and_drop/_drag_and_drop_stub.dart similarity index 100% rename from packages/devtools_app/lib/src/config_specific/flutter/drag_and_drop/_drag_and_drop_stub.dart rename to packages/devtools_app/lib/src/config_specific/drag_and_drop/_drag_and_drop_stub.dart diff --git a/packages/devtools_app/lib/src/config_specific/flutter/drag_and_drop/_drag_and_drop_web.dart b/packages/devtools_app/lib/src/config_specific/drag_and_drop/_drag_and_drop_web.dart similarity index 100% rename from packages/devtools_app/lib/src/config_specific/flutter/drag_and_drop/_drag_and_drop_web.dart rename to packages/devtools_app/lib/src/config_specific/drag_and_drop/_drag_and_drop_web.dart diff --git a/packages/devtools_app/lib/src/config_specific/flutter/drag_and_drop/drag_and_drop.dart b/packages/devtools_app/lib/src/config_specific/drag_and_drop/drag_and_drop.dart similarity index 97% rename from packages/devtools_app/lib/src/config_specific/flutter/drag_and_drop/drag_and_drop.dart rename to packages/devtools_app/lib/src/config_specific/drag_and_drop/drag_and_drop.dart index 7e993ec009d..561d21277d6 100644 --- a/packages/devtools_app/lib/src/config_specific/flutter/drag_and_drop/drag_and_drop.dart +++ b/packages/devtools_app/lib/src/config_specific/drag_and_drop/drag_and_drop.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; -import '../../../flutter/notifications.dart'; +import '../../notifications.dart'; import '_drag_and_drop_stub.dart' if (dart.library.html) '_drag_and_drop_web.dart' if (dart.library.io) '_drag_and_drop_desktop.dart'; diff --git a/packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/_framework_initialize_desktop.dart b/packages/devtools_app/lib/src/config_specific/framework_initialize/_framework_initialize_desktop.dart similarity index 94% rename from packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/_framework_initialize_desktop.dart rename to packages/devtools_app/lib/src/config_specific/framework_initialize/_framework_initialize_desktop.dart index 215e9d8e254..b981f0d3c7b 100644 --- a/packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/_framework_initialize_desktop.dart +++ b/packages/devtools_app/lib/src/config_specific/framework_initialize/_framework_initialize_desktop.dart @@ -8,9 +8,9 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:path/path.dart' as path; -import '../../../globals.dart'; -import '../../../storage.dart'; -import '../../logger/logger.dart'; +import '../../globals.dart'; +import '../../storage.dart'; +import '../logger/logger.dart'; /// Return the url the application is launched from. Future initializePlatform() async { diff --git a/packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/_framework_initialize_stub.dart b/packages/devtools_app/lib/src/config_specific/framework_initialize/_framework_initialize_stub.dart similarity index 100% rename from packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/_framework_initialize_stub.dart rename to packages/devtools_app/lib/src/config_specific/framework_initialize/_framework_initialize_stub.dart diff --git a/packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/_framework_initialize_web.dart b/packages/devtools_app/lib/src/config_specific/framework_initialize/_framework_initialize_web.dart similarity index 95% rename from packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/_framework_initialize_web.dart rename to packages/devtools_app/lib/src/config_specific/framework_initialize/_framework_initialize_web.dart index 70c835b9c4a..6d8fb3e1b59 100644 --- a/packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/_framework_initialize_web.dart +++ b/packages/devtools_app/lib/src/config_specific/framework_initialize/_framework_initialize_web.dart @@ -4,9 +4,9 @@ import 'dart:html' hide Storage; -import '../../../globals.dart'; -import '../../../server_api_client.dart'; -import '../../../storage.dart'; +import '../../globals.dart'; +import '../../server_api_client.dart'; +import '../../storage.dart'; /// Return the url the application is launched from. Future initializePlatform() async { diff --git a/packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/framework_initialize.dart b/packages/devtools_app/lib/src/config_specific/framework_initialize/framework_initialize.dart similarity index 90% rename from packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/framework_initialize.dart rename to packages/devtools_app/lib/src/config_specific/framework_initialize/framework_initialize.dart index ea263235122..7e243ed3f9d 100644 --- a/packages/devtools_app/lib/src/config_specific/flutter/framework_initialize/framework_initialize.dart +++ b/packages/devtools_app/lib/src/config_specific/framework_initialize/framework_initialize.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import '../../../framework/framework_core.dart'; +import '../../framework/framework_core.dart'; import '_framework_initialize_stub.dart' if (dart.library.html) '_framework_initialize_web.dart' if (dart.library.io) '_framework_initialize_desktop.dart'; diff --git a/packages/devtools_app/lib/src/config_specific/flutter/import_export/_export_desktop.dart b/packages/devtools_app/lib/src/config_specific/import_export/_export_desktop.dart similarity index 94% rename from packages/devtools_app/lib/src/config_specific/flutter/import_export/_export_desktop.dart rename to packages/devtools_app/lib/src/config_specific/import_export/_export_desktop.dart index e822b00907d..a4a868c8943 100644 --- a/packages/devtools_app/lib/src/config_specific/flutter/import_export/_export_desktop.dart +++ b/packages/devtools_app/lib/src/config_specific/import_export/_export_desktop.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import '../../file/file.dart'; +import '../file/file.dart'; import 'import_export.dart'; ExportControllerDesktop createExportController() { diff --git a/packages/devtools_app/lib/src/config_specific/flutter/import_export/_export_stub.dart b/packages/devtools_app/lib/src/config_specific/import_export/_export_stub.dart similarity index 100% rename from packages/devtools_app/lib/src/config_specific/flutter/import_export/_export_stub.dart rename to packages/devtools_app/lib/src/config_specific/import_export/_export_stub.dart diff --git a/packages/devtools_app/lib/src/config_specific/flutter/import_export/_export_web.dart b/packages/devtools_app/lib/src/config_specific/import_export/_export_web.dart similarity index 100% rename from packages/devtools_app/lib/src/config_specific/flutter/import_export/_export_web.dart rename to packages/devtools_app/lib/src/config_specific/import_export/_export_web.dart diff --git a/packages/devtools_app/lib/src/config_specific/flutter/import_export/import_export.dart b/packages/devtools_app/lib/src/config_specific/import_export/import_export.dart similarity index 94% rename from packages/devtools_app/lib/src/config_specific/flutter/import_export/import_export.dart rename to packages/devtools_app/lib/src/config_specific/import_export/import_export.dart index ce8a1c54058..374d7d57fd4 100644 --- a/packages/devtools_app/lib/src/config_specific/flutter/import_export/import_export.dart +++ b/packages/devtools_app/lib/src/config_specific/import_export/import_export.dart @@ -4,11 +4,11 @@ import 'dart:convert'; -import '../../../../devtools.dart'; -import '../../../flutter/notifications.dart'; -import '../../../globals.dart'; -import '../../../timeline/flutter/timeline_model.dart'; -import '../../../timeline/flutter/timeline_screen.dart'; +import '../../../devtools.dart'; +import '../../globals.dart'; +import '../../notifications.dart'; +import '../../timeline/timeline_model.dart'; +import '../../timeline/timeline_screen.dart'; import '_export_stub.dart' if (dart.library.html) '_export_web.dart' if (dart.library.io) '_export_desktop.dart'; diff --git a/packages/devtools_app/lib/src/flutter/connect_screen.dart b/packages/devtools_app/lib/src/connect_screen.dart similarity index 97% rename from packages/devtools_app/lib/src/flutter/connect_screen.dart rename to packages/devtools_app/lib/src/connect_screen.dart index b29747426c7..6c2bb7d14a3 100644 --- a/packages/devtools_app/lib/src/flutter/connect_screen.dart +++ b/packages/devtools_app/lib/src/connect_screen.dart @@ -6,14 +6,14 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:pedantic/pedantic.dart'; -import '../../src/framework/framework_core.dart'; -import '../globals.dart'; -import '../url_utils.dart'; -import '../utils.dart'; import 'common_widgets.dart'; +import 'framework/framework_core.dart'; +import 'globals.dart'; import 'navigation.dart'; import 'notifications.dart'; import 'theme.dart'; +import 'url_utils.dart'; +import 'utils.dart'; /// The screen in the app responsible for connecting to the Dart VM. /// diff --git a/packages/devtools_app/lib/src/flutter/console.dart b/packages/devtools_app/lib/src/console.dart similarity index 99% rename from packages/devtools_app/lib/src/flutter/console.dart rename to packages/devtools_app/lib/src/console.dart index 52f77f94790..fe0ec2e9af8 100644 --- a/packages/devtools_app/lib/src/flutter/console.dart +++ b/packages/devtools_app/lib/src/console.dart @@ -5,8 +5,8 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../debugger/flutter/codeview.dart'; import 'common_widgets.dart'; +import 'debugger/codeview.dart'; import 'theme.dart'; import 'utils.dart'; diff --git a/packages/devtools_app/lib/src/flutter/custom_pointer_scroll_view.dart b/packages/devtools_app/lib/src/custom_pointer_scroll_view.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/custom_pointer_scroll_view.dart rename to packages/devtools_app/lib/src/custom_pointer_scroll_view.dart diff --git a/packages/devtools_app/lib/src/debugger/flutter/breakpoints.dart b/packages/devtools_app/lib/src/debugger/breakpoints.dart similarity index 97% rename from packages/devtools_app/lib/src/debugger/flutter/breakpoints.dart rename to packages/devtools_app/lib/src/debugger/breakpoints.dart index ff4722c1edb..58271013f6a 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/breakpoints.dart +++ b/packages/devtools_app/lib/src/debugger/breakpoints.dart @@ -5,9 +5,9 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/theme.dart'; -import '../../utils.dart'; +import '../common_widgets.dart'; +import '../theme.dart'; +import '../utils.dart'; import 'common.dart'; import 'debugger_controller.dart'; import 'debugger_model.dart'; diff --git a/packages/devtools_app/lib/src/debugger/flutter/call_stack.dart b/packages/devtools_app/lib/src/debugger/call_stack.dart similarity index 97% rename from packages/devtools_app/lib/src/debugger/flutter/call_stack.dart rename to packages/devtools_app/lib/src/debugger/call_stack.dart index ace3780b8e3..44c142a7330 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/call_stack.dart +++ b/packages/devtools_app/lib/src/debugger/call_stack.dart @@ -6,9 +6,9 @@ import 'package:flutter/material.dart' hide Stack; import 'package:provider/provider.dart'; import 'package:vm_service/vm_service.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/theme.dart'; -import '../../utils.dart'; +import '../common_widgets.dart'; +import '../theme.dart'; +import '../utils.dart'; import 'debugger_controller.dart'; import 'debugger_model.dart'; diff --git a/packages/devtools_app/lib/src/debugger/flutter/codeview.dart b/packages/devtools_app/lib/src/debugger/codeview.dart similarity index 98% rename from packages/devtools_app/lib/src/debugger/flutter/codeview.dart rename to packages/devtools_app/lib/src/debugger/codeview.dart index 9000ebbcff0..4c6854aedfb 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/codeview.dart +++ b/packages/devtools_app/lib/src/debugger/codeview.dart @@ -7,12 +7,12 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:vm_service/vm_service.dart' hide Stack; -import '../../config_specific/logger/logger.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/flutter_widgets/linked_scroll_controller.dart'; -import '../../flutter/theme.dart'; -import '../../utils.dart'; +import '../auto_dispose_mixin.dart'; +import '../common_widgets.dart'; +import '../config_specific/logger/logger.dart'; +import '../flutter_widgets/linked_scroll_controller.dart'; +import '../theme.dart'; +import '../utils.dart'; import 'breakpoints.dart'; import 'common.dart'; import 'debugger_controller.dart'; diff --git a/packages/devtools_app/lib/src/debugger/flutter/common.dart b/packages/devtools_app/lib/src/debugger/common.dart similarity index 98% rename from packages/devtools_app/lib/src/debugger/flutter/common.dart rename to packages/devtools_app/lib/src/debugger/common.dart index dc06c0a4d4f..74c5394241c 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/common.dart +++ b/packages/devtools_app/lib/src/debugger/common.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; -import '../../flutter/theme.dart'; +import '../theme.dart'; import 'debugger_screen.dart'; /// Create a header area for a debugger component. diff --git a/packages/devtools_app/lib/src/debugger/flutter/console.dart b/packages/devtools_app/lib/src/debugger/console.dart similarity index 95% rename from packages/devtools_app/lib/src/debugger/flutter/console.dart rename to packages/devtools_app/lib/src/debugger/console.dart index 531078f7728..45b634a6dba 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/console.dart +++ b/packages/devtools_app/lib/src/debugger/console.dart @@ -5,9 +5,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/console.dart'; -import '../../utils.dart'; +import '../common_widgets.dart'; +import '../console.dart'; +import '../utils.dart'; import 'common.dart'; import 'debugger_controller.dart'; diff --git a/packages/devtools_app/lib/src/debugger/flutter/controls.dart b/packages/devtools_app/lib/src/debugger/controls.dart similarity index 98% rename from packages/devtools_app/lib/src/debugger/flutter/controls.dart rename to packages/devtools_app/lib/src/debugger/controls.dart index dd902d12397..9130260739b 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/controls.dart +++ b/packages/devtools_app/lib/src/debugger/controls.dart @@ -5,9 +5,9 @@ import 'package:flutter/material.dart' hide Stack; import 'package:vm_service/vm_service.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/theme.dart'; -import '../../ui/flutter/label.dart'; +import '../common_widgets.dart'; +import '../theme.dart'; +import '../ui/label.dart'; import 'debugger_controller.dart'; import 'scripts.dart'; diff --git a/packages/devtools_app/lib/src/debugger/flutter/debugger_controller.dart b/packages/devtools_app/lib/src/debugger/debugger_controller.dart similarity index 99% rename from packages/devtools_app/lib/src/debugger/flutter/debugger_controller.dart rename to packages/devtools_app/lib/src/debugger/debugger_controller.dart index fba5fb387eb..8f46bb53025 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/debugger_controller.dart +++ b/packages/devtools_app/lib/src/debugger/debugger_controller.dart @@ -9,10 +9,10 @@ import 'package:flutter/material.dart' hide Stack; import 'package:pedantic/pedantic.dart'; import 'package:vm_service/vm_service.dart'; -import '../../auto_dispose.dart'; -import '../../core/message_bus.dart'; -import '../../globals.dart'; -import '../../utils.dart'; +import '../auto_dispose.dart'; +import '../core/message_bus.dart'; +import '../globals.dart'; +import '../utils.dart'; import 'debugger_model.dart'; // TODO(devoncarew): Add some delayed resume value notifiers (to be used to diff --git a/packages/devtools_app/lib/src/debugger/flutter/debugger_model.dart b/packages/devtools_app/lib/src/debugger/debugger_model.dart similarity index 99% rename from packages/devtools_app/lib/src/debugger/flutter/debugger_model.dart rename to packages/devtools_app/lib/src/debugger/debugger_model.dart index e7bdc8a20be..1bdffd965bb 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/debugger_model.dart +++ b/packages/devtools_app/lib/src/debugger/debugger_model.dart @@ -6,8 +6,8 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart' hide Stack; import 'package:vm_service/vm_service.dart'; -import '../../trees.dart'; -import '../../utils.dart'; +import '../trees.dart'; +import '../utils.dart'; /// A tuple of a script and an optional location. class ScriptLocation { diff --git a/packages/devtools_app/lib/src/debugger/flutter/debugger_screen.dart b/packages/devtools_app/lib/src/debugger/debugger_screen.dart similarity index 96% rename from packages/devtools_app/lib/src/debugger/flutter/debugger_screen.dart rename to packages/devtools_app/lib/src/debugger/debugger_screen.dart index 0aebf5ed344..e156a09b3e4 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/debugger_screen.dart +++ b/packages/devtools_app/lib/src/debugger/debugger_screen.dart @@ -9,15 +9,15 @@ import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import 'package:vm_service/vm_service.dart'; -import '../../config_specific/host_platform/host_platform.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/flex_split_column.dart'; -import '../../flutter/octicons.dart'; -import '../../flutter/screen.dart'; -import '../../flutter/split.dart'; -import '../../flutter/theme.dart'; -import '../../globals.dart'; +import '../auto_dispose_mixin.dart'; +import '../common_widgets.dart'; +import '../config_specific/host_platform/host_platform.dart'; +import '../flex_split_column.dart'; +import '../globals.dart'; +import '../octicons.dart'; +import '../screen.dart'; +import '../split.dart'; +import '../theme.dart'; import 'breakpoints.dart'; import 'call_stack.dart'; import 'codeview.dart'; diff --git a/packages/devtools_app/lib/src/debugger/flutter/debugger_service.dart b/packages/devtools_app/lib/src/debugger/debugger_service.dart similarity index 98% rename from packages/devtools_app/lib/src/debugger/flutter/debugger_service.dart rename to packages/devtools_app/lib/src/debugger/debugger_service.dart index 7931a3e5bd5..76b77b4047a 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/debugger_service.dart +++ b/packages/devtools_app/lib/src/debugger/debugger_service.dart @@ -1,6 +1,6 @@ import 'package:vm_service/vm_service.dart'; -import '../../globals.dart'; +import '../globals.dart'; class DebuggerService { Stream get onDebugEvent => serviceManager.service.onDebugEvent; diff --git a/packages/devtools_app/lib/src/debugger/flutter/scripts.dart b/packages/devtools_app/lib/src/debugger/scripts.dart similarity index 96% rename from packages/devtools_app/lib/src/debugger/flutter/scripts.dart rename to packages/devtools_app/lib/src/debugger/scripts.dart index ffa8a555bdf..a8267c934f3 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/scripts.dart +++ b/packages/devtools_app/lib/src/debugger/scripts.dart @@ -5,11 +5,10 @@ import 'package:flutter/material.dart'; import 'package:vm_service/vm_service.dart'; -import '../../config_specific/host_platform/host_platform.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/theme.dart'; -import '../../flutter/utils.dart'; -import '../../utils.dart'; +import '../common_widgets.dart'; +import '../config_specific/host_platform/host_platform.dart'; +import '../theme.dart'; +import '../utils.dart'; import 'debugger_controller.dart'; import 'debugger_model.dart'; import 'debugger_screen.dart'; diff --git a/packages/devtools_app/lib/src/debugger/flutter/variables.dart b/packages/devtools_app/lib/src/debugger/variables.dart similarity index 95% rename from packages/devtools_app/lib/src/debugger/flutter/variables.dart rename to packages/devtools_app/lib/src/debugger/variables.dart index 896bbe4283c..c6fae516693 100644 --- a/packages/devtools_app/lib/src/debugger/flutter/variables.dart +++ b/packages/devtools_app/lib/src/debugger/variables.dart @@ -5,8 +5,8 @@ import 'package:flutter/material.dart' hide Stack; import 'package:provider/provider.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/tree.dart'; +import '../common_widgets.dart'; +import '../tree.dart'; import 'debugger_controller.dart'; import 'debugger_model.dart'; diff --git a/packages/devtools_app/lib/src/flutter/device_dialog.dart b/packages/devtools_app/lib/src/device_dialog.dart similarity index 97% rename from packages/devtools_app/lib/src/flutter/device_dialog.dart rename to packages/devtools_app/lib/src/device_dialog.dart index 6587fdbb77b..ca7b3ceba92 100644 --- a/packages/devtools_app/lib/src/flutter/device_dialog.dart +++ b/packages/devtools_app/lib/src/device_dialog.dart @@ -7,16 +7,16 @@ import 'package:meta/meta.dart'; import 'package:pedantic/pedantic.dart'; import 'package:vm_service/vm_service.dart'; -import '../connected_app.dart'; -import '../globals.dart'; -import '../info/info_controller.dart'; -import '../table_data.dart'; -import '../utils.dart'; -import '../version.dart'; import 'auto_dispose_mixin.dart'; import 'common_widgets.dart'; +import 'connected_app.dart'; +import 'globals.dart'; +import 'info/info_controller.dart'; import 'table.dart'; +import 'table_data.dart'; import 'theme.dart'; +import 'utils.dart'; +import 'version.dart'; class DeviceDialog extends StatelessWidget { const DeviceDialog({ diff --git a/packages/devtools_app/lib/src/example/flutter/conditional_screen.dart b/packages/devtools_app/lib/src/example/conditional_screen.dart similarity index 97% rename from packages/devtools_app/lib/src/example/flutter/conditional_screen.dart rename to packages/devtools_app/lib/src/example/conditional_screen.dart index 839bd7cd9cd..1d20000b6f7 100644 --- a/packages/devtools_app/lib/src/example/flutter/conditional_screen.dart +++ b/packages/devtools_app/lib/src/example/conditional_screen.dart @@ -7,8 +7,8 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../../flutter/screen.dart'; -import '../../globals.dart'; +import '../globals.dart'; +import '../screen.dart'; /// This is an example implementation of a conditional screen that supports /// offline mode and uses a provided controller [ExampleController]. diff --git a/packages/devtools_app/lib/src/flutter/extent_delegate_list.dart b/packages/devtools_app/lib/src/extent_delegate_list.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/extent_delegate_list.dart rename to packages/devtools_app/lib/src/extent_delegate_list.dart diff --git a/packages/devtools_app/lib/src/flutter/flex_split_column.dart b/packages/devtools_app/lib/src/flex_split_column.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/flex_split_column.dart rename to packages/devtools_app/lib/src/flex_split_column.dart diff --git a/packages/devtools_app/lib/src/flutter/utils.dart b/packages/devtools_app/lib/src/flutter/utils.dart deleted file mode 100644 index dea47a4d193..00000000000 --- a/packages/devtools_app/lib/src/flutter/utils.dart +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:ansi_up/ansi_up.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; -import 'package:url_launcher/url_launcher.dart' as url_launcher; - -import 'notifications.dart'; - -Future launchUrl(String url, BuildContext context) async { - if (await url_launcher.canLaunch(url)) { - await url_launcher.launch(url); - } else { - Notifications.of(context).push('Unable to open $url.'); - } -} - -/// Attempts to copy a String of `data` to the clipboard. -/// -/// Shows a `successMessage` [Notification] on the passed in `context`. -Future copyToClipboard( - String data, - String successMessage, - BuildContext context, -) async { - await Clipboard.setData(ClipboardData( - text: data, - )); - - if (successMessage != null) { - Notifications.of(context)?.push(successMessage); - } -} - -List processAnsiTerminalCodes(String input, TextStyle defaultStyle) { - if (input == null) { - return []; - } - return decodeAnsiColorEscapeCodes(input, AnsiUp()) - .map( - (entry) => TextSpan( - text: entry.text, - style: entry.style.isEmpty - ? defaultStyle - : TextStyle( - color: entry.fgColor != null - ? colorFromAnsi(entry.fgColor) - : null, - backgroundColor: entry.bgColor != null - ? colorFromAnsi(entry.bgColor) - : null, - fontWeight: entry.bold ? FontWeight.bold : FontWeight.normal, - ), - ), - ) - .toList(); -} - -Color colorFromAnsi(List ansiInput) { - assert(ansiInput.length == 3, 'Ansi color list should contain 3 elements'); - return Color.fromRGBO(ansiInput[0], ansiInput[1], ansiInput[2], 1); -} - -/// An extension on [LogicalKeySet] to provide user-facing names for key -/// bindings. -extension LogicalKeySetExtension on LogicalKeySet { - static final Set _modifiers = { - LogicalKeyboardKey.alt, - LogicalKeyboardKey.control, - LogicalKeyboardKey.meta, - LogicalKeyboardKey.shift, - }; - - static final Map _modifierNames = { - LogicalKeyboardKey.alt: 'Alt', - LogicalKeyboardKey.control: 'Control', - LogicalKeyboardKey.meta: 'Meta', - LogicalKeyboardKey.shift: 'Shift', - }; - - /// Return a user-facing name for the [LogicalKeySet]. - String describeKeys({bool isMacOS = false}) { - // Put the modifiers first. If it has a synonym, then it's something like - // shiftLeft, altRight, etc. - final List sortedKeys = keys.toList() - ..sort((a, b) { - final aIsModifier = a.synonyms.isNotEmpty || _modifiers.contains(a); - final bIsModifier = b.synonyms.isNotEmpty || _modifiers.contains(b); - if (aIsModifier && !bIsModifier) { - return -1; - } else if (bIsModifier && !aIsModifier) { - return 1; - } - return a.keyLabel.compareTo(b.keyLabel); - }); - - return sortedKeys.map((key) { - if (_modifiers.contains(key)) { - if (isMacOS && key == LogicalKeyboardKey.meta) { - return '⌘'; - } - return '${_modifierNames[key]}-'; - } else { - return key.keyLabel.toUpperCase(); - } - }).join(); - } -} diff --git a/packages/devtools_app/lib/src/flutter/flutter_widgets/linked_scroll_controller.dart b/packages/devtools_app/lib/src/flutter_widgets/linked_scroll_controller.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/flutter_widgets/linked_scroll_controller.dart rename to packages/devtools_app/lib/src/flutter_widgets/linked_scroll_controller.dart diff --git a/packages/devtools_app/lib/src/flutter/initializer.dart b/packages/devtools_app/lib/src/initializer.dart similarity index 96% rename from packages/devtools_app/lib/src/flutter/initializer.dart rename to packages/devtools_app/lib/src/initializer.dart index 41e70cd194b..7991e00d2c6 100644 --- a/packages/devtools_app/lib/src/flutter/initializer.dart +++ b/packages/devtools_app/lib/src/initializer.dart @@ -7,12 +7,12 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import '../framework/framework_core.dart'; -import '../globals.dart'; -import '../inspector/flutter_widget.dart'; -import '../url_utils.dart'; import 'auto_dispose_mixin.dart'; +import 'framework/framework_core.dart'; +import 'globals.dart'; +import 'inspector/flutter_widget.dart'; import 'notifications.dart'; +import 'url_utils.dart'; /// Widget that requires business logic to be loaded before building its /// [builder]. diff --git a/packages/devtools_app/lib/src/inspector/flutter/diagnostics.dart b/packages/devtools_app/lib/src/inspector/diagnostics.dart similarity index 95% rename from packages/devtools_app/lib/src/inspector/flutter/diagnostics.dart rename to packages/devtools_app/lib/src/inspector/diagnostics.dart index ed3cee31e56..56f4727a60a 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/diagnostics.dart +++ b/packages/devtools_app/lib/src/inspector/diagnostics.dart @@ -5,12 +5,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../../inspector/diagnostics_node.dart'; -import '../../inspector/inspector_controller.dart'; -import '../../inspector/inspector_text_styles.dart' as inspector_text_styles; -import '../../inspector/inspector_tree.dart'; -import '../../ui/icons.dart'; -import '../../utils.dart'; +import '../ui/icons.dart'; +import '../utils.dart'; +import 'diagnostics_node.dart'; +import 'inspector_controller.dart'; +import 'inspector_text_styles.dart' as inspector_text_styles; +import 'inspector_tree.dart'; final ColorIconMaker _colorIconMaker = ColorIconMaker(); final CustomIconMaker _customIconMaker = CustomIconMaker(); diff --git a/packages/devtools_app/lib/src/inspector/flutter/inspector_data_models.dart b/packages/devtools_app/lib/src/inspector/inspector_data_models.dart similarity index 99% rename from packages/devtools_app/lib/src/inspector/flutter/inspector_data_models.dart rename to packages/devtools_app/lib/src/inspector/inspector_data_models.dart index a798eb98548..2356248b2b4 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/inspector_data_models.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_data_models.dart @@ -7,9 +7,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import '../../enum_utils.dart'; -import '../../utils.dart'; -import '../diagnostics_node.dart'; +import '../enum_utils.dart'; +import '../utils.dart'; +import 'diagnostics_node.dart'; import 'layout_explorer/flex/utils.dart'; const overflowEpsilon = 0.1; diff --git a/packages/devtools_app/lib/src/inspector/flutter/inspector_screen.dart b/packages/devtools_app/lib/src/inspector/inspector_screen.dart similarity index 93% rename from packages/devtools_app/lib/src/inspector/flutter/inspector_screen.dart rename to packages/devtools_app/lib/src/inspector/inspector_screen.dart index 5d073b6973e..e1c33c320c7 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/inspector_screen.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_screen.dart @@ -5,21 +5,21 @@ import 'package:flutter/material.dart'; import 'package:vm_service/vm_service.dart' hide Stack; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/blocking_action_mixin.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/initializer.dart'; -import '../../flutter/octicons.dart'; -import '../../flutter/screen.dart'; -import '../../flutter/split.dart'; -import '../../flutter/theme.dart'; -import '../../globals.dart'; -import '../../service_extensions.dart' as extensions; -import '../../ui/flutter/label.dart'; -import '../../ui/flutter/service_extension_widgets.dart'; -import '../inspector_controller.dart'; -import '../inspector_service.dart'; +import '../auto_dispose_mixin.dart'; +import '../blocking_action_mixin.dart'; +import '../common_widgets.dart'; +import '../globals.dart'; +import '../initializer.dart'; +import '../octicons.dart'; +import '../screen.dart'; +import '../service_extensions.dart' as extensions; +import '../split.dart'; +import '../theme.dart'; +import '../ui/label.dart'; +import '../ui/service_extension_widgets.dart'; +import 'inspector_controller.dart'; import 'inspector_screen_details_tab.dart'; +import 'inspector_service.dart'; import 'inspector_tree_flutter.dart'; class InspectorScreen extends Screen { diff --git a/packages/devtools_app/lib/src/inspector/flutter/inspector_screen_details_tab.dart b/packages/devtools_app/lib/src/inspector/inspector_screen_details_tab.dart similarity index 96% rename from packages/devtools_app/lib/src/inspector/flutter/inspector_screen_details_tab.dart rename to packages/devtools_app/lib/src/inspector/inspector_screen_details_tab.dart index c0e8b4da71a..5725876fdf6 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/inspector_screen_details_tab.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_screen_details_tab.dart @@ -6,9 +6,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/theme.dart'; -import '../inspector_controller.dart'; +import '../auto_dispose_mixin.dart'; +import '../theme.dart'; +import 'inspector_controller.dart'; import 'layout_explorer/layout_explorer.dart'; class InspectorDetailsTabController extends StatefulWidget { diff --git a/packages/devtools_app/lib/src/inspector/flutter/inspector_service_flutter_extension.dart b/packages/devtools_app/lib/src/inspector/inspector_service_flutter_extension.dart similarity index 94% rename from packages/devtools_app/lib/src/inspector/flutter/inspector_service_flutter_extension.dart rename to packages/devtools_app/lib/src/inspector/inspector_service_flutter_extension.dart index de4ed3469aa..ba55589ce75 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/inspector_service_flutter_extension.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_service_flutter_extension.dart @@ -2,10 +2,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; -import '../../globals.dart'; -import '../diagnostics_node.dart'; -import '../inspector_service.dart'; -import '../inspector_service_polyfill.dart'; +import '../globals.dart'; +import 'diagnostics_node.dart'; +import 'inspector_service.dart'; +import 'inspector_service_polyfill.dart'; extension InspectorFlutterService on ObjectGroup { Future invokeSetFlexProperties( diff --git a/packages/devtools_app/lib/src/inspector/flutter/inspector_tree_flutter.dart b/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart similarity index 98% rename from packages/devtools_app/lib/src/inspector/flutter/inspector_tree_flutter.dart rename to packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart index 31a1d72e0e8..1b13ea136ae 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/inspector_tree_flutter.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart @@ -9,13 +9,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:pedantic/pedantic.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/collapsible_mixin.dart'; -import '../../flutter/theme.dart'; -import '../../ui/colors.dart'; -import '../diagnostics_node.dart'; -import '../inspector_tree.dart'; +import '../auto_dispose_mixin.dart'; +import '../collapsible_mixin.dart'; +import '../theme.dart'; +import '../ui/colors.dart'; import 'diagnostics.dart'; +import 'diagnostics_node.dart'; +import 'inspector_tree.dart'; /// Presents a [TreeNode]. class _InspectorTreeRowWidget extends StatefulWidget { diff --git a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/arrow.dart b/packages/devtools_app/lib/src/inspector/layout_explorer/flex/arrow.dart similarity index 99% rename from packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/arrow.dart rename to packages/devtools_app/lib/src/inspector/layout_explorer/flex/arrow.dart index 7ea0e93051e..0a975ca4008 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/arrow.dart +++ b/packages/devtools_app/lib/src/inspector/layout_explorer/flex/arrow.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import '../../../../flutter/theme.dart'; +import '../../../theme.dart'; const defaultArrowColor = Colors.white; const defaultArrowStrokeWidth = 2.0; diff --git a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/flex.dart b/packages/devtools_app/lib/src/inspector/layout_explorer/flex/flex.dart similarity index 99% rename from packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/flex.dart rename to packages/devtools_app/lib/src/inspector/layout_explorer/flex/flex.dart index a48eaa0a39e..c65107e065d 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/flex.dart +++ b/packages/devtools_app/lib/src/inspector/layout_explorer/flex/flex.dart @@ -9,14 +9,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import '../../../../flutter/theme.dart'; -import '../../../../ui/colors.dart'; -import '../../../../ui/theme.dart'; -import '../../../../utils.dart'; -import '../../../diagnostics_node.dart'; -import '../../../inspector_controller.dart'; -import '../../../inspector_service.dart'; +import '../../../theme.dart'; +import '../../../ui/colors.dart'; +import '../../../ui/theme.dart'; +import '../../../utils.dart'; +import '../../diagnostics_node.dart'; +import '../../inspector_controller.dart'; import '../../inspector_data_models.dart'; +import '../../inspector_service.dart'; import '../../inspector_service_flutter_extension.dart'; import 'arrow.dart'; import 'free_space.dart'; diff --git a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/free_space.dart b/packages/devtools_app/lib/src/inspector/layout_explorer/flex/free_space.dart similarity index 98% rename from packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/free_space.dart rename to packages/devtools_app/lib/src/inspector/layout_explorer/flex/free_space.dart index 22e7e86406e..0c2bc6b14a9 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/free_space.dart +++ b/packages/devtools_app/lib/src/inspector/layout_explorer/flex/free_space.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import '../../../../utils.dart'; +import '../../../utils.dart'; import '../../inspector_data_models.dart'; import 'arrow.dart'; import 'flex.dart'; diff --git a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/overflow_indicator_painter.dart b/packages/devtools_app/lib/src/inspector/layout_explorer/flex/overflow_indicator_painter.dart similarity index 100% rename from packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/overflow_indicator_painter.dart rename to packages/devtools_app/lib/src/inspector/layout_explorer/flex/overflow_indicator_painter.dart diff --git a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/utils.dart b/packages/devtools_app/lib/src/inspector/layout_explorer/flex/utils.dart similarity index 99% rename from packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/utils.dart rename to packages/devtools_app/lib/src/inspector/layout_explorer/flex/utils.dart index 6d7272b502f..6f652f6cd5c 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/flex/utils.dart +++ b/packages/devtools_app/lib/src/inspector/layout_explorer/flex/utils.dart @@ -10,8 +10,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import '../../../../utils.dart'; -import '../../../diagnostics_node.dart'; +import '../../../utils.dart'; +import '../../diagnostics_node.dart'; import '../../inspector_data_models.dart'; import 'overflow_indicator_painter.dart'; diff --git a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/layout_explorer.dart b/packages/devtools_app/lib/src/inspector/layout_explorer/layout_explorer.dart similarity index 95% rename from packages/devtools_app/lib/src/inspector/flutter/layout_explorer/layout_explorer.dart rename to packages/devtools_app/lib/src/inspector/layout_explorer/layout_explorer.dart index 883279b247a..bacf90a6d03 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/layout_explorer/layout_explorer.dart +++ b/packages/devtools_app/lib/src/inspector/layout_explorer/layout_explorer.dart @@ -1,7 +1,7 @@ import 'package:flutter/widgets.dart'; -import '../../diagnostics_node.dart'; -import '../../inspector_controller.dart'; +import '../diagnostics_node.dart'; +import '../inspector_controller.dart'; import 'flex/flex.dart'; /// Tab that acts as a proxy to decide which widget to be displayed diff --git a/packages/devtools_app/lib/src/logging/flutter/logging_screen.dart b/packages/devtools_app/lib/src/logging/logging_screen.dart similarity index 94% rename from packages/devtools_app/lib/src/logging/flutter/logging_screen.dart rename to packages/devtools_app/lib/src/logging/logging_screen.dart index 46edda0cc13..f616551b7c0 100644 --- a/packages/devtools_app/lib/src/logging/flutter/logging_screen.dart +++ b/packages/devtools_app/lib/src/logging/logging_screen.dart @@ -7,20 +7,19 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/console.dart'; -import '../../flutter/octicons.dart'; -import '../../flutter/screen.dart'; -import '../../flutter/split.dart'; -import '../../flutter/table.dart'; -import '../../flutter/theme.dart'; -import '../../flutter/utils.dart'; -import '../../globals.dart'; -import '../../table_data.dart'; -import '../../ui/flutter/service_extension_widgets.dart'; -import '../../utils.dart'; -import '../logging_controller.dart'; +import '../auto_dispose_mixin.dart'; +import '../common_widgets.dart'; +import '../console.dart'; +import '../globals.dart'; +import '../octicons.dart'; +import '../screen.dart'; +import '../split.dart'; +import '../table.dart'; +import '../table_data.dart'; +import '../theme.dart'; +import '../ui/service_extension_widgets.dart'; +import '../utils.dart'; +import 'logging_controller.dart'; /// Presents logs from the connected app. class LoggingScreen extends Screen { diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_controller.dart b/packages/devtools_app/lib/src/memory/flutter/memory_controller.dart deleted file mode 100644 index 903d17d479d..00000000000 --- a/packages/devtools_app/lib/src/memory/flutter/memory_controller.dart +++ /dev/null @@ -1,1293 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; -import 'dart:ui' as dart_ui; - -import 'package:devtools_shared/devtools_shared.dart'; -import 'package:flutter/foundation.dart'; -import 'package:intl/intl.dart'; -import 'package:meta/meta.dart'; -import 'package:mp_chart/mp/core/entry/entry.dart'; -import 'package:vm_service/vm_service.dart'; - -import '../../auto_dispose.dart'; -import '../../config_specific/file/file.dart'; -import '../../config_specific/logger/logger.dart'; -import '../../flutter/table.dart'; -import '../../globals.dart'; -import '../../service_manager.dart'; -import '../../ui/flutter/utils.dart'; -import '../../utils.dart'; -import '../memory_service.dart'; -import 'memory_filter.dart'; -import 'memory_graph_model.dart'; -import 'memory_protocol.dart'; -import 'memory_snapshot_models.dart'; - -enum ChartType { - DartHeaps, - AndroidHeaps, -} - -typedef chartStateListener = void Function(); - -// TODO(terry): Consider supporting more than one file since app was launched. -// Memory Log filename. -final String _memoryLogFilename = - '${MemoryController.logFilenamePrefix}${DateFormat("yyyyMMdd_hh_mm").format(DateTime.now())}'; - -/// This class contains the business logic for [memory.dart]. -/// -/// This class must not have direct dependencies on dart:html. This allows tests -/// of the complicated logic in this class to run on the VM and will help -/// simplify porting this code to work with Flutter Web. -class MemoryController extends DisposableController - with AutoDisposeControllerMixin { - MemoryController() { - memoryTimeline = MemoryTimeline(this); - memoryLog = MemoryLog(this); - } - - static const logFilenamePrefix = 'memory_log_'; - - bool showHeatMap = true; - - final snapshots = []; - - Snapshot get lastSnapshot => snapshots.safeLast; - - /// Root nodes names that contains nodes of either libraries or classes depending on - /// group by library or group by class. - static const libraryRootNode = '___LIBRARY___'; - static const classRootNode = '___CLASSES___'; - - /// Notifies that the source of the memory feed has changed. - ValueListenable get selectedSnapshotNotifier => - _selectedSnapshotNotifier; - - /// Stored value is pretty timestamp when the snapshot was done. - final _selectedSnapshotNotifier = ValueNotifier(''); - - set selectedSnapshotTimestamp(String snapshotTimestamp) { - _selectedSnapshotNotifier.value = snapshotTimestamp; - } - - String get selectedSnapshotTimestamp => _selectedSnapshotNotifier.value; - - HeapGraph heapGraph; - - /// Leaf node of tabletree snapshot selected? If selected then the instance - /// view is displayed to view the fields of an instance. - final _leafSelectedNotifier = ValueNotifier(null); - - ValueListenable get leafSelectedNotifier => - _leafSelectedNotifier; - - HeapGraphElementLive get selectedLeaf => _leafSelectedNotifier.value; - - set selectedLeaf(HeapGraphElementLive selected) { - _leafSelectedNotifier.value = selected; - } - - bool get isLeafSelected => selectedLeaf != null; - - void computeRoot() { - if (selectedLeaf != null) { - final root = instanceToFieldNodes(this, selectedLeaf); - _instanceRoot = root.isNotEmpty ? root : [FieldReference.empty]; - } else { - _instanceRoot = [FieldReference.empty]; - } - } - - List _instanceRoot; - - List get instanceRoot => _instanceRoot; - - /// Leaf node of analysis selected? If selected then the field - /// view is displayed to view an abbreviated fields of an instance. - final _leafAnalysisSelectedNotifier = ValueNotifier(null); - - ValueListenable get leafAnalysisSelectedNotifier => - _leafAnalysisSelectedNotifier; - - AnalysisInstance get selectedAnalysisLeaf => - _leafAnalysisSelectedNotifier.value; - - set selectedAnalysisLeaf(AnalysisInstance selected) { - _leafAnalysisSelectedNotifier.value = selected; - } - - bool get isAnalysisLeafSelected => selectedAnalysisLeaf != null; - - void computeAnalysisInstanceRoot() { - if (selectedAnalysisLeaf != null) { - final analysisFields = selectedAnalysisLeaf.fieldsRoot.children; - _analysisInstanceRoot = - analysisFields.isNotEmpty ? analysisFields : [AnalysisField.empty]; - } else { - _analysisInstanceRoot = [AnalysisField.empty]; - } - } - - List _analysisInstanceRoot; - - List get analysisInstanceRoot => _analysisInstanceRoot; - - // List of completed Analysis of Snapshots. - final List completedAnalyses = []; - - bool enableAnalyzeButton() { - if (snapshots.isNotEmpty) { - final lastSnapshot = snapshots.last; - if (completedAnalyses.isNotEmpty) { - final result = completedAnalyses.last.dateTime.compareTo( - lastSnapshot.collectedTimestamp, - ) != - 0; - return result; - } - return true; - } - - return false; - } - - MemoryTimeline memoryTimeline; - - MemoryLog memoryLog; - - /// Source of memory heap samples. False live data, True loaded from a - /// memory_log file. - bool offline = false; - - HeapSample _selectedDartSample; - - HeapSample _selectedAndroidSample; - - HeapSample getSelectedSample(ChartType type) => type == ChartType.DartHeaps - ? _selectedDartSample - : _selectedAndroidSample; - - void setSelectedSample(ChartType type, HeapSample sample) { - if (type == ChartType.DartHeaps) - _selectedDartSample = sample; - else - _selectedAndroidSample = sample; - } - - static const liveFeed = 'Live Feed'; - - String memorySourcePrefix; - - /// Notifies that the source of the memory feed has changed. - ValueListenable get memorySourceNotifier => _memorySourceNotifier; - - final _memorySourceNotifier = ValueNotifier(liveFeed); - - set memorySource(String source) { - _memorySourceNotifier.value = source; - } - - String get memorySource => _memorySourceNotifier.value; - - /// Starting chunk for slider based on the intervalDurationInMs. - double sliderValue = 1.0; - - /// Number of interval stops for the timeline slider e.g., for 15 minutes of - /// collected data, displayed at a 5 minute interval there will be 3 stops, - /// each stop would be 5 minutes prior to the previous stop. - int numberOfStops = 0; - - /// Compute total timeline stops used by Timeline slider. - int computeStops() { - int stops = 0; - if (memoryTimeline.data.isNotEmpty) { - final lastSampleTimestamp = memoryTimeline.data.last.timestamp.toDouble(); - final firstSampleTimestamp = - memoryTimeline.data.first.timestamp.toDouble(); - stops = - ((lastSampleTimestamp - firstSampleTimestamp) / intervalDurationInMs) - .round(); - } - return stops == 0 ? 1 : stops; - } - - /// Automatic pruning of memory statistics (plotted) full data is still retained. - static const displayOneMinute = '1'; - static const displayFiveMinutes = '5'; - static const displayTenMinutes = '10'; - static const displayAllMinutes = 'All'; - - /// Default is to display last minute of collected data in the chart. - final _displayIntervalNotifier = ValueNotifier(displayOneMinute); - - ValueListenable get displayIntervalNotifier => - _displayIntervalNotifier; - - set displayInterval(String interval) { - _displayIntervalNotifier.value = interval; - } - - String get displayInterval => _displayIntervalNotifier.value; - - /// 1 minute in milliseconds. - static const int minuteInMs = 60 * 1000; - - /// Return the pruning interval in milliseconds. - int get intervalDurationInMs => (displayInterval == displayAllMinutes) - ? maxJsInt - : int.parse(displayInterval) * minuteInMs; - - /// MemorySource has changed update the view. - void updatedMemorySource() { - if (memorySource == MemoryController.liveFeed) { - if (offline) { - // User is switching back to 'Live Feed'. - memoryTimeline.offlineData.clear(); - offline = false; // We're live again... - } else { - // Still a live feed - keep collecting. - assert(!offline); - } - } else { - // Switching to an offline memory log (JSON file in /tmp). - memoryLog.loadOffline(memorySource); - } - - // The memory source has changed, clear all plotted values. - memoryTimeline.dartChartData.reset(); - memoryTimeline.androidChartData.reset(); - } - - void recomputeOfflineData() { - final args = memoryTimeline.recomputeOfflineData(intervalDurationInMs); - processDataset(args); - } - - void recomputeData() { - final args = memoryTimeline.recomputeLiveData(intervalDurationInMs); - processDataset(args); - // TODO(terry): need to recomputeOffline data? - } - - void processDataset(List args) { - // Add entries of entries plotted in the chart. Entries plotted - // may not match data collected (based on display interval). - for (var arg in args) { - memoryTimeline.dartChartData.addTraceEntries( - capacityValue: arg[MemoryTimeline.capcityValueKey], - usedValue: arg[MemoryTimeline.usedValueKey], - externalValue: arg[MemoryTimeline.externalValueKey], - minutesToDisplay: intervalDurationInMs, - ); - memoryTimeline.androidChartData.addTraceEntries( - javaValue: arg[MemoryTimeline.javaHeapValueKey], - nativeValue: arg[MemoryTimeline.nativeHeapValueKey], - codeValue: arg[MemoryTimeline.codeValueKey], - stackValue: arg[MemoryTimeline.stackValueKey], - graphicsValue: arg[MemoryTimeline.graphicsValueKey], - otherValue: arg[MemoryTimeline.otherValueKey], - systemValue: arg[MemoryTimeline.systemValueKey], - totalValue: arg[MemoryTimeline.totalValueKey], - minutesToDisplay: intervalDurationInMs, - ); - - if (memoryTimeline.dartChartData.pruned) { - memoryTimeline.startingIndex++; - } - } - } - - void processData([bool reloadAllData = false]) { - final args = offline - ? memoryTimeline.fetchMemoryLogFileData() - : memoryTimeline.fetchLiveData(reloadAllData); - - processDataset(args); - } - - final _paused = ValueNotifier(false); - - ValueListenable get paused => _paused; - - void pauseLiveFeed() { - _paused.value = true; - } - - void resumeLiveFeed() { - _paused.value = false; - } - - bool _androidChartVisible = false; - - bool get isAndroidChartVisible => _androidChartVisible; - - bool toggleAndroidChartVisibility() => - _androidChartVisible = !_androidChartVisible; - - final SettingsModel settings = SettingsModel(); - - final selectionNotifier = - ValueNotifier>(Selection()); - - /// Tree to view Libary/Class/Instance (grouped by) - TreeTable groupByTreeTable; - - /// Tree to view fields of an instance. - TreeTable instanceFieldsTreeTable; - - /// Tree to view fields of an analysis. - TreeTable analysisFieldsTreeTable; - - /// State of filters used by filter dialog (create/modify) and used - /// by filtering in grouping. - final FilteredLibraries libraryFilters = FilteredLibraries(); - - /// Root of all known libraries. - LibraryReference libraryRoot; - - /// Root of known classes (used for group by class). - LibraryReference classRoot; - - /// Used by the filter dialog, grouped name displayed in filter dialog - /// e.g., dart:*, package:flutter/* - /// - /// The key is the group name (displayed in dialog), value is list of - /// libraries associated to the group. Structure is used to: - /// - allow user to hide/show a library when filtering a snapshot. - /// - create the hide list of libraries to drive the UX on when showing - /// list of libraries/classes/objects in a snapshot table. - final filteredLibrariesByGroupName = >{}; - - /// Notify that the filtering has changed. - ValueListenable get filterNotifier => _filterNotifier; - - final _filterNotifier = ValueNotifier(0); - - void updateFilter() { - _filterNotifier.value++; - } - - /// Hide any class that hasn't been constructed (zero instances). - final filterZeroInstances = CheckboxValueNotifier(true); - - ValueListenable get filterZeroInstancesListenable => - filterZeroInstances; - - /// Hide any private class, prefixed with an underscore. - final filterPrivateClasses = CheckboxValueNotifier(true); - - ValueListenable get filterPrivateClassesListenable => - filterPrivateClasses; - - /// Hide any library with no constructed class instances. - final filterLibraryNoInstances = CheckboxValueNotifier(true); - - ValueListenable get filterLibraryNoInstancesListenable => - filterLibraryNoInstances; - - /// Table ordered by library, class or instance - static const groupByLibrary = 'Library'; - static const groupByClass = 'Class'; - static const groupByInstance = 'Instance'; - - final groupingBy = ValueNotifier(groupByLibrary); - - ValueListenable get groupingByNotifier => groupingBy; - - final selectTheSearchNotifier = ValueNotifier(false); - - bool get selectTheSearch => selectTheSearchNotifier.value; - - /// Search is very dynamic, with auto-complete or programmatic searching, - /// setting the value to true will fire off searching through a snapshot. - set selectTheSearch(bool v) { - selectTheSearchNotifier.value = v; - } - - final _searchNotifier = ValueNotifier(''); - - /// Notify that the search has changed. - ValueListenable get searchNotifier => _searchNotifier; - - set search(String value) { - _searchNotifier.value = value; - } - - String get search => _searchNotifier.value; - - final searchAutoComplete = ValueNotifier>([]); - - ValueListenable> get searchAutoCompleteNotifier => - searchAutoComplete; - - void clearSearchAutoComplete() { - searchAutoComplete.value = []; - } - - String get _isolateId => serviceManager.isolateManager.selectedIsolate.id; - - final StreamController _memoryTrackerController = - StreamController.broadcast(); - - Stream get onMemory => _memoryTrackerController.stream; - - Stream get onDisconnect => _disconnectController.stream; - final _disconnectController = StreamController.broadcast(); - - MemoryTracker _memoryTracker; - - MemoryTracker get memoryTracker => _memoryTracker; - - bool get hasStarted => _memoryTracker != null; - - bool hasStopped; - - void _handleIsolateChanged() { - // TODO(terry): Need an event on the controller for this too? - } - - void _handleConnectionStart(ServiceConnectionManager serviceManager) { - _memoryTracker = MemoryTracker(serviceManager, this); - _memoryTracker.start(); - - autoDispose( - _memoryTracker.onChange.listen((_) { - _memoryTrackerController.add(_memoryTracker); - }), - ); - autoDispose( - _memoryTracker.onChange.listen((_) { - _memoryTrackerController.add(_memoryTracker); - }), - ); - - // TODO(terry): Used to detect stream being closed from the - // memoryController dispose method. Needed when a HOT RELOAD - // will call dispose however, spinup (initState) doesn't seem - // to happen David is working on scaffolding. - _memoryTrackerController.stream.listen((_) {}, onDone: () { - // Stop polling and reset memoryTracker. - _memoryTracker.stop(); - _memoryTracker = null; - }); - } - - void _handleConnectionStop(dynamic event) { - _memoryTracker?.stop(); - _memoryTrackerController.add(_memoryTracker); - - _disconnectController.add(null); - hasStopped = true; - } - - Future startTimeline() async { - autoDispose( - serviceManager.isolateManager.onSelectedIsolateChanged.listen((_) { - _handleIsolateChanged(); - }), - ); - - autoDispose( - serviceManager.onConnectionAvailable - .listen((_) => _handleConnectionStart(serviceManager)), - ); - if (serviceManager.hasConnection) { - _handleConnectionStart(serviceManager); - } - autoDispose( - serviceManager.onConnectionClosed.listen(_handleConnectionStop), - ); - } - - Future snapshotMemory() async { - return await serviceManager.service - .getHeapSnapshotGraph(serviceManager.isolateManager.selectedIsolate); - } - - Future> resetAllocationProfile() => - getAllocationProfile(reset: true); - - // 'reset': true to reset the object allocation accumulators - Future> getAllocationProfile({ - bool reset = false, - }) async { - AllocationProfile allocationProfile; - try { - allocationProfile = await serviceManager.service.getAllocationProfile( - _isolateId, - reset: reset, - ); - } on SentinelException catch (_) { - return []; - } - return allocationProfile.members - .map((ClassHeapStats stats) => ClassHeapDetailStats(stats.json)) - .where((ClassHeapDetailStats stats) { - return stats.instancesCurrent > 0 || stats.instancesAccumulated > 0; - }).toList(); - } - - bool get isConnectedDeviceAndroid { - return serviceManager.vm.operatingSystem == 'android'; - } - - Future> getInstances( - String classRef, - String className, - int maxInstances, - ) async { - // TODO(terry): Expose as a stream to reduce stall when querying for 1000s - // TODO(terry): of instances. - InstanceSet instanceSet; - try { - instanceSet = await serviceManager.service.getInstances( - _isolateId, - classRef, - maxInstances, - classId: classRef, - ); - } on SentinelException catch (_) { - return []; - } - return instanceSet.instances - .map((ObjRef ref) => InstanceSummary(classRef, className, ref.id)) - .toList(); - } - - /// When new snapshot occurs entire libraries should be rebuilt then rebuild should be true. - LibraryReference computeAllLibraries([ - bool filtered = true, - bool rebuild = false, - ]) { - if (snapshots.isEmpty) return null; - - if (filtered && libraryRoot != null && !rebuild) return libraryRoot; - - // Group by library - libraryRoot = LibraryReference(this, libraryRootNode, null); - - final analysesRoot = AnalysesReference(); - analysesRoot.addChild(AnalysisReference('')); - libraryRoot.addChild(analysesRoot); - - // Group by class (under root library __CLASSES__). - classRoot = LibraryReference(this, classRootNode, null); - - final snapshotgraph = snapshots.last.snapshotGraph; - final externalReferences = - ExternalReferences(this, snapshotgraph.externalSize); - for (final liveExternal in heapGraph.externals) { - final HeapGraphClassLive classLive = liveExternal.live.theClass; - - ExternalReference externalReference; - - if (externalReferences.children.isNotEmpty) { - externalReference = externalReferences.children.singleWhere( - (knownClass) => knownClass.name == classLive.name, - orElse: () => null, - ); - } - - if (externalReference == null) { - externalReference = - ExternalReference(this, classLive.name, liveExternal); - externalReferences.addChild(externalReference); - } - - final classInstance = ExternalObjectReference( - this, - externalReference.children.length, - liveExternal.live, - liveExternal.externalProperty.externalSize, - ); - - // Sum up the externalSize of the children, under the externalReference group. - externalReference.sumExternalSizes += - liveExternal.externalProperty.externalSize; - - externalReference.addChild(classInstance); - } - - libraryRoot.addChild(externalReferences); - - // Add our filtered items under the 'Filtered' node. - if (filtered) { - final filteredReference = FilteredReference(this); - final filtered = heapGraph.filteredLibraries; - addAllToNode(filteredReference, filtered); - - libraryRoot.addChild(filteredReference); - } - - // Compute all libraries. - final groupBy = - filtered ? heapGraph.groupByLibrary : heapGraph.rawGroupByLibrary; - - groupBy.forEach((libraryName, classes) { - LibraryReference libReference = - libraryRoot.children.singleWhere((library) { - return libraryName == library.name; - }, orElse: () => null); - - // Library not found add to list of children. - if (libReference == null) { - libReference = LibraryReference(this, libraryName, classes); - libraryRoot.addChild(libReference); - } - - for (var actualClass in libReference.actualClasses) { - monitorClass( - className: actualClass.name, - message: 'computeAllLibraries', - ); - final classRef = ClassReference(this, actualClass); - classRef.addChild(Reference.empty); - - libReference.addChild(classRef); - - // TODO(terry): Consider adding the ability to clear the table tree cache - // (root) to reset the level/depth values. - final classRefClassGroupBy = ClassReference(this, actualClass); - classRefClassGroupBy.addChild(Reference.empty); - classRoot.addChild(classRefClassGroupBy); - } - }); - - return libraryRoot; - } - - // TODO(terry): Change to Set of known libraries so it's O(n) instead of O(n^2). - void addAllToNode( - Reference root, Map> allItems) { - allItems.forEach((libraryName, classes) { - LibraryReference libReference = root.children.singleWhere((library) { - return libraryName == library.name; - }, orElse: () => null); - - // Library not found add to list of children. - libReference ??= LibraryReference(this, libraryName, classes); - root.addChild(libReference); - - for (var actualClass in libReference.actualClasses) { - monitorClass( - className: actualClass.name, - message: 'computeAllLibraries', - ); - final classRef = ClassReference(this, actualClass); - classRef.addChild(Reference.empty); - - libReference.addChild(classRef); - - // TODO(terry): Consider adding the ability to clear the table tree cache - // (root) to reset the level/depth values. - final classRefClassGroupBy = ClassReference(this, actualClass); - classRefClassGroupBy.addChild(Reference.empty); - classRoot.addChild(classRefClassGroupBy); - } - }); - } - - Future getObject(String objectRef) async => - await serviceManager.service.getObject( - _isolateId, - objectRef, - ); - - bool _gcing = false; - bool get isGcing => _gcing; - - Future gc() async { - _gcing = true; - - try { - await serviceManager.service.getAllocationProfile( - _isolateId, - gc: true, - ); - } finally { - _gcing = false; - } - } - - // Temporary hack to allow accessing private fields(e.g., _extra) using eval - // of '_extra.hashCode' to fetch the hashCode of the object of that field. - // Used to find the object which allocated/references the object being viewed. - Future matchObject( - String objectRef, String fieldName, int instanceHashCode) async { - final dynamic object = await getObject(objectRef); - if (object is Instance) { - final Instance instance = object; - final List fields = instance.fields; - for (var field in fields) { - if (field.decl.name == fieldName) { - final InstanceRef ref = field.value; - - if (ref == null) continue; - - final evalResult = await evaluate(ref.id, 'hashCode'); - final int objHashCode = int.parse(evalResult?.valueAsString); - if (objHashCode == instanceHashCode) { - return true; - } - } - } - } - - if (object is Sentinel) { - // TODO(terry): Need more graceful handling of sentinels. - log( - 'Trying to matchObject with a Sentinel $objectRef', - LogLevel.error, - ); - } - - return false; - } - - List snapshotByLibraryData; - - void createSnapshotByLibrary() { - snapshotByLibraryData ??= lastSnapshot?.librariesToList(); - } - - void storeSnapshot(DateTime timestamp, HeapSnapshotGraph graph) { - snapshots.add(Snapshot(timestamp, this, graph)); - } - - @override - void dispose() { - super.dispose(); - _displayIntervalNotifier.dispose(); - _memorySourceNotifier.dispose(); - _disconnectController.close(); - _memoryTrackerController.close(); - } -} - -/// Settings dialog model. -class SettingsModel { - /// Pattern is of the form: - /// - empty string implies no matching. - /// - NNN* implies match anything starting with NNN. - /// - *NNN implies match anything ending with NNN. - String pattern = ''; - - /// If true hide Class names that begin with an underscore. - bool hidePrivateClasses = true; - - /// If true enable the memory experiment that following a object instance via - /// inbound references instances. Compares hashCodes (using eval causing - /// memory shaking). Only works in debug mode. - bool experiment = false; -} - -/// Prepare data to plot in MPChart. -class MPChartData { - bool _pruning = false; - - /// Signal that every addTrace will cause a prune. - bool get pruned => _pruning; - - /// Datapoint entries for each used heap value. - final List used = []; - - /// Datapoint entries for each capacity heap value. - final List capacity = []; - - /// Datapoint entries for each external memory value. - final List externalHeap = []; - - /// Add each entry to its corresponding trace. - void addTraceEntries({ - Entry capacityValue, - Entry usedValue, - Entry externalValue, - int minutesToDisplay, - }) { - if (!_pruning && - externalHeap.isNotEmpty && - (externalValue.x - externalHeap.first.x) > minutesToDisplay) { - _pruning = true; - assert(externalValue.x - externalHeap.last.x <= minutesToDisplay); - } - - // TODO(terry): Any way have a kind of trace order safe way to so we - // can keep an list of the entries (remoteAt and add). - if (_pruning) { - externalHeap.removeAt(0); - used.removeAt(0); - capacity.removeAt(0); - } - - externalHeap.add(externalValue); - used.add(usedValue); - capacity.add(capacityValue); - } - - /// Remove all plotted entries in all traces. - void reset() { - // TODO(terry): Any way have a kind of trace order safe way to so we - // can keep an list of the entries (clear). - used.clear(); - capacity.clear(); - externalHeap.clear(); - _pruning = false; - } -} - -/// Prepare Engine (ADB memory info) data to plot in MPChart. -class MPEngineChartData { - bool _pruning = false; - - /// Datapoint entries for each Java heap value. - final List javaHeap = []; - - /// Datapoint entries for each native heap value. - final List nativeHeap = []; - - /// Datapoint entries for code size value. - final List code = []; - - /// Datapoint entries for stack size value. - final List stack = []; - - /// Datapoint entries for graphics size value. - final List graphics = []; - - /// Datapoint entries for other size value. - final List other = []; - - /// Datapoint entries for system size value. - final List system = []; - - /// Datapoint entries for total size value. - final List total = []; - - /// Add each entry to its corresponding trace. - void addTraceEntries({ - Entry javaValue, - Entry nativeValue, - Entry codeValue, - Entry stackValue, - Entry graphicsValue, - Entry otherValue, - Entry systemValue, - Entry totalValue, - int minutesToDisplay, - }) { - if (!_pruning && - javaHeap.isNotEmpty && - (javaValue.x - javaHeap.first.x) > minutesToDisplay) { - _pruning = true; - - assert(javaValue.x - javaHeap.last.x <= minutesToDisplay); - } - - // TODO(terry): Any way have a kind of trace order safe way to so we - // can keep an list of the entries (remoteAt and add). - if (_pruning) { - javaHeap.removeAt(0); - nativeHeap.removeAt(0); - code.removeAt(0); - stack.removeAt(0); - graphics.removeAt(0); - other.removeAt(0); - system.removeAt(0); - total.removeAt(0); - } - - javaHeap.add(javaValue); - nativeHeap.add(nativeValue); - code.add(codeValue); - stack.add(stackValue); - graphics.add(graphicsValue); - other.add(otherValue); - system.add(systemValue); - total.add(totalValue); - } - - /// Remove all plotted entries in all traces. - void reset() { - // TODO(terry): Any way have a kind of trace order safe way to so we - // can keep an list of the entries (clear). - javaHeap.clear(); - nativeHeap.clear(); - code.clear(); - stack.clear(); - graphics.clear(); - other.clear(); - system.clear(); - total.clear(); - _pruning = false; - } -} - -/// All Raw data received from the VM and offline data loaded from a memory log file. -class MemoryTimeline { - MemoryTimeline(this.controller); - - /// Version of timeline data (HeapSample) JSON payload. - static const version = 1; - - /// Keys used in a map to store all the MPChart Entries we construct to be plotted. - static const capcityValueKey = 'capacityValue'; - static const usedValueKey = 'usedValue'; - static const externalValueKey = 'externalValue'; - static const rssValueKey = 'rssValue'; - - /// Keys used in a map to store all the MPEngineChart Entries we construct to be plotted, - /// ADB memory info. - static const javaHeapValueKey = 'javaHeapValue'; - static const nativeHeapValueKey = 'nativeHeapValue'; - static const codeValueKey = 'codeValue'; - static const stackValueKey = 'stackValue'; - static const graphicsValueKey = 'graphicsValue'; - static const otherValueKey = 'otherValue'; - static const systemValueKey = 'systemValue'; - static const totalValueKey = 'totalValue'; - - final MemoryController controller; - - /// Flutter Framework information (Dart heaps). - final dartChartData = MPChartData(); - - /// Flutter Engine (ADB memory information). - final androidChartData = MPEngineChartData(); - - /// Return the data payload that is active. - List get data => controller.offline ? offlineData : liveData; - - int get startingIndex => - controller.offline ? offlineStartingIndex : liveStartingIndex; - - set startingIndex(int value) { - controller.offline - ? offlineStartingIndex = value - : liveStartingIndex = value; - } - - int get endingIndex => data.isNotEmpty ? data.length - 1 : -1; - - /// Raw Heap sampling data from the VM. - final List liveData = []; - - /// Start index of liveData plotted for MPChartData/MPEngineChartData sets. - int liveStartingIndex = 0; - - /// Data of the last selected offline memory source (JSON file in /tmp). - final List offlineData = []; - - /// Start index of offlineData plotted for MPChartData/MPEngineChartData sets. - int offlineStartingIndex = 0; - - /// Notifies that a new Heap sample has been added to the timeline. - final _sampleAddedNotifier = ValueNotifier(null); - - ValueListenable get sampleAddedNotifier => _sampleAddedNotifier; - - /// Whether the timeline has been manually paused via the Pause button. - bool manuallyPaused = false; - - /// Notifies that the timeline has been paused. - final _pausedNotifier = ValueNotifier(false); - - ValueNotifier get pausedNotifier => _pausedNotifier; - - void pause({bool manual = false}) { - manuallyPaused = manual; - _pausedNotifier.value = true; - } - - void resume() { - manuallyPaused = false; - _pausedNotifier.value = false; - } - - /// Notifies any visible marker for a particular chart should be hidden. - final _markerHiddenNotifier = ValueNotifier(false); - - ValueListenable get markerHiddenNotifier => _markerHiddenNotifier; - - void hideMarkers() { - _markerHiddenNotifier.value = !_markerHiddenNotifier.value; - } - - /// dart_ui.Image Image asset displayed for each entry plotted in a chart. - // ignore: unused_field - dart_ui.Image _img; - - // TODO(terry): Look at using _img for each data point (at least last N). - dart_ui.Image get dataPointImage => null; - - set image(dart_ui.Image img) { - _img = img; - } - - void reset() { - liveData.clear(); - startingIndex = 0; - dartChartData.reset(); - androidChartData.reset(); - } - - /// Common utility function to handle loading of the data into the - /// chart for either offline or live Feed. - List _processData(int index) { - final result = >[]; - - for (var lastIndex = index; lastIndex < data.length; lastIndex++) { - final sample = data[lastIndex]; - final timestamp = sample.timestamp.toDouble(); - - // Flutter Framework memory (Dart VM Heaps) - final capacity = sample.capacity.toDouble(); - final used = sample.used.toDouble(); - final external = sample.external.toDouble(); - - // TOOD(terry): Need to plot. - final rss = (sample.rss ?? 0).toDouble(); - - final extEntry = Entry(x: timestamp, y: external, icon: dataPointImage); - final usedEntry = - Entry(x: timestamp, y: used + external, icon: dataPointImage); - final capacityEntry = - Entry(x: timestamp, y: capacity, icon: dataPointImage); - final rssEntry = Entry(x: timestamp, y: rss, icon: dataPointImage); - - // Engine memory values (ADB Android): - final javaHeap = sample.adbMemoryInfo.javaHeap.toDouble(); - final nativeHeap = sample.adbMemoryInfo.nativeHeap.toDouble(); - final code = sample.adbMemoryInfo.code.toDouble(); - final stack = sample.adbMemoryInfo.stack.toDouble(); - final graphics = sample.adbMemoryInfo.graphics.toDouble(); - final other = sample.adbMemoryInfo.other.toDouble(); - final system = sample.adbMemoryInfo.system.toDouble(); - final total = sample.adbMemoryInfo.total.toDouble(); - - final graphicsEntry = Entry( - x: timestamp, - y: graphics, - icon: dataPointImage, - ); - final stackEntry = Entry( - x: timestamp, - y: stack + graphics, - icon: dataPointImage, - ); - final javaHeapEntry = Entry( - x: timestamp, - y: javaHeap + graphics + stack, - icon: dataPointImage, - ); - final nativeHeapEntry = Entry( - x: timestamp, - y: nativeHeap + javaHeap + graphics + stack, - icon: dataPointImage, - ); - final codeEntry = Entry( - x: timestamp, - y: code + nativeHeap + javaHeap + graphics + stack, - icon: dataPointImage, - ); - final otherEntry = Entry( - x: timestamp, - y: other + code + nativeHeap + javaHeap + graphics + stack, - icon: dataPointImage, - ); - final systemEntry = Entry( - x: timestamp, - y: system + other + code + nativeHeap + javaHeap + graphics + stack, - icon: dataPointImage, - ); - final totalEntry = Entry( - x: timestamp, - y: total, - icon: dataPointImage, - ); - - result.add({ - capcityValueKey: capacityEntry, - usedValueKey: usedEntry, - externalValueKey: extEntry, - rssValueKey: rssEntry, - javaHeapValueKey: javaHeapEntry, - nativeHeapValueKey: nativeHeapEntry, - codeValueKey: codeEntry, - stackValueKey: stackEntry, - graphicsValueKey: graphicsEntry, - otherValueKey: otherEntry, - systemValueKey: systemEntry, - totalValueKey: totalEntry, - }); - } - - return result; - } - - /// Fetch all the data in the loaded from a memory log (JSON file in /tmp). - List fetchMemoryLogFileData() { - assert(controller.offline); - assert(offlineData.isNotEmpty); - return _processData(startingIndex); - } - - List fetchLiveData([bool reloadAllData = false]) { - assert(!controller.offline); - assert(liveData.isNotEmpty); - - if (endingIndex - startingIndex != liveData.length || reloadAllData) { - // Process the data received (startingDataIndex is the last sample). - final args = _processData(endingIndex < 0 ? 0 : endingIndex); - - // Debugging data - to enable remove logical not operator. - if (!true) { - final DateFormat mFormat = DateFormat('hh:mm:ss.mmm'); - final startDT = mFormat.format(DateTime.fromMillisecondsSinceEpoch( - liveData[startingIndex].timestamp.toInt())); - final endDT = mFormat.format(DateTime.fromMillisecondsSinceEpoch( - liveData[endingIndex].timestamp.toInt())); - log('Time range Live data start: $startDT, end: $endDT'); - } - - return args; - } - - return []; - } - - List recomputeOfflineData(int displayInterval) { - assert(displayInterval > 0); - - _computeStartingIndex(displayInterval); - - // Start from the first sample to display in this time interval. - return _processData(startingIndex); - } - - List recomputeLiveData(int displayInterval) { - assert(displayInterval > 0); - - _computeStartingIndex(displayInterval); - - // Start from the first sample to display in this time interval. - return _processData(startingIndex); - } - - void _computeStartingIndex(int displayInterval) { - // Compute a new starting index from length - N minutes. - final timeLastSample = data.last.timestamp; - var dataIndex = data.length - 1; - for (; dataIndex > 0; dataIndex--) { - final sample = data[dataIndex]; - final timestamp = sample.timestamp; - - if ((timeLastSample - timestamp) > displayInterval) break; - } - - startingIndex = dataIndex; - - // Debugging data - to enable remove logical not operator. - if (!true) { - final DateFormat mFormat = DateFormat('hh:mm:ss.mmm'); - final startDT = mFormat.format(DateTime.fromMillisecondsSinceEpoch( - data[startingIndex].timestamp.toInt())); - final endDT = mFormat.format(DateTime.fromMillisecondsSinceEpoch( - data[endingIndex].timestamp.toInt())); - log('Recompute Time range Offline data start: $startDT, end: $endDT'); - } - } - - void addSample(HeapSample sample) { - // Always record the heap sample in the raw set of data (liveFeed). - liveData.add(sample); - - // Only notify that new sample has arrived if the - // memory source is 'Live Feed'. - if (!controller.offline) { - _sampleAddedNotifier.value = sample; - } - } -} - -/// Supports saving and loading memory samples. -class MemoryLog { - MemoryLog(this.controller); - - /// Use in memory or local file system based on Flutter Web/Desktop. - static final _fs = FileIO(); - - MemoryController controller; - - /// Persist the the live memory data to a JSON file in the /tmp directory. - void exportMemory() async { - final liveData = controller.memoryTimeline.liveData; - - bool pseudoData = false; - if (liveData.isEmpty) { - // TODO(terry): Can eliminate once I add loading a canned data source - // see the todo in memory_screen_test. - // Used to create empty memory log for test. - pseudoData = true; - liveData.add(HeapSample( - DateTime.now().microsecondsSinceEpoch, - 0, - 0, - 0, - 0, - false, - AdbMemoryInfo.empty(), - )); - } - - final jsonPayload = MemoryJson.encodeHeapSamples(liveData); - if (kDebugMode) { - // TODO(terry): Remove this check add a unit test instead. - // Reload the file just created and validate that the saved data matches - // the live data. - final memoryJson = MemoryJson.decode(jsonPayload); - assert(memoryJson.isMatchedVersion); - assert(memoryJson.isMemoryPayload); - assert(memoryJson.data.length == liveData.length); - } - - _fs.writeStringToFile(_memoryLogFilename, jsonPayload); - - // TODO(terry): Display filename created in a toast. - - if (pseudoData) liveData.clear(); - } - - /// Return a list of offline memory logs filenames in the /tmp directory - /// that are available to open. - List offlineFiles() { - final memoryLogs = _fs.list(prefix: MemoryController.logFilenamePrefix); - - // Sort by newest file top-most (DateTime is in the filename). - memoryLogs.sort((a, b) => b.compareTo(a)); - - return memoryLogs; - } - - /// Load the memory profile data from a saved memory log file. - void loadOffline(String filename) async { - controller.offline = true; - - final jsonPayload = _fs.readStringFromFile(filename); - final memoryJson = MemoryJson.decode(jsonPayload); - - // TODO(terry): Display notification JSON file isn't version isn't - // supported or if the payload isn't an exported memory file. - assert(memoryJson.isMatchedVersion); - assert(memoryJson.isMemoryPayload); - - controller.memoryTimeline.offlineData.clear(); - controller.memoryTimeline.offlineData.addAll(memoryJson.data); - } - - @visibleForTesting - bool removeOfflineFile(String filename) => _fs.deleteFile(filename); -} diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_protocol.dart b/packages/devtools_app/lib/src/memory/flutter/memory_protocol.dart deleted file mode 100644 index 6c408dabafe..00000000000 --- a/packages/devtools_app/lib/src/memory/flutter/memory_protocol.dart +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; -import 'dart:math' as math; - -import 'package:devtools_shared/devtools_shared.dart'; -import 'package:vm_service/vm_service.dart'; - -import '../../globals.dart'; -import '../../service_manager.dart'; -import '../../version.dart'; -import '../../vm_service_wrapper.dart'; -import 'memory_controller.dart'; - -class MemoryTracker { - MemoryTracker(this.serviceManager, this.memoryController); - - static const Duration _updateDelay = Duration(milliseconds: 500); - - ServiceConnectionManager serviceManager; - - final MemoryController memoryController; - - VmServiceWrapper get service => serviceManager?.service; - - Timer _pollingTimer; - - final List samples = []; - final Map isolateHeaps = {}; - - /// Polled VM current RSS. - int processRss; - - /// Polled adb dumpsys meminfo values. - AdbMemoryInfo adbMemoryInfo; - - bool get hasConnection => service != null; - - Stream get onChange => _changeController.stream; - final _changeController = StreamController.broadcast(); - - int get currentCapacity => samples.last.capacity; - - int get currentUsed => samples.last.used; - - int get currentExternal => samples.last.external; - - StreamSubscription _gcStreamListener; - - void start() { - _updateLiveDataPolling(memoryController.paused.value); - memoryController.paused.addListener(_updateLiveDataPolling); - } - - void _updateLiveDataPolling([bool paused]) { - paused ??= memoryController.paused.value; - - if (paused) { - _pollingTimer?.cancel(); - _gcStreamListener?.cancel(); - } else { - _pollingTimer = Timer(Duration.zero, _pollMemory); - _gcStreamListener = service.onGCEvent.listen(_handleGCEvent); - } - } - - void stop() { - _updateLiveDataPolling(false); - memoryController.paused.removeListener(_updateLiveDataPolling); - serviceManager = null; - } - - void _handleGCEvent(Event event) { - final HeapSpace newHeap = HeapSpace.parse(event.json['new']); - final HeapSpace oldHeap = HeapSpace.parse(event.json['old']); - - final MemoryUsage memoryUsage = MemoryUsage( - externalUsage: newHeap.external + oldHeap.external, - heapCapacity: newHeap.capacity + oldHeap.capacity, - heapUsage: newHeap.used + oldHeap.used, - ); - - _updateGCEvent(event.isolate.id, memoryUsage); - // TODO(terry): expose when GC occured as markers in memory timeline. - } - - // TODO(terry): Discuss need a record/stop record for memory? Unless expensive probably not. - Future _pollMemory() async { - if (!hasConnection || memoryController.memoryTracker == null) { - return; - } - - final isolateMemory = {}; - for (IsolateRef isolateRef in serviceManager.isolateManager.isolates) { - isolateMemory[isolateRef] = await service.getMemoryUsage(isolateRef.id); - } - - // Polls for current Android meminfo using: - // > adb shell dumpsys meminfo -d - if (hasConnection && serviceManager.vm.operatingSystem == 'android') { - adbMemoryInfo = await _fetchAdbInfo(); - } else { - // TODO(terry): TBD alternative for iOS memory info - all values zero. - adbMemoryInfo = AdbMemoryInfo.empty(); - } - - // Polls for current RSS size. - _update(await service.getVM(), isolateMemory); - - _pollingTimer = Timer(_updateDelay, _pollMemory); - } - - void _update(VM vm, Map isolateMemory) { - processRss = vm.json['_currentRSS']; - - isolateHeaps.clear(); - - for (IsolateRef isolateRef in isolateMemory.keys) { - isolateHeaps[isolateRef.id] = isolateMemory[isolateRef]; - } - - _recalculate(); - } - - void _updateGCEvent(String isolateId, MemoryUsage memoryUsage) { - isolateHeaps[isolateId] = memoryUsage; - _recalculate(true); - } - - // Poll ADB meminfo - Future _fetchAdbInfo() async => - AdbMemoryInfo.fromJson((await serviceManager.getAdbMemoryInfo()).json); - - void _recalculate([bool fromGC = false]) async { - int used = 0; - int capacity = 0; - int external = 0; - - for (MemoryUsage memoryUsage in isolateHeaps.values) { - used += memoryUsage.heapUsage; - capacity += memoryUsage.heapCapacity; - external += memoryUsage.externalUsage; - } - - int time = DateTime.now().millisecondsSinceEpoch; - if (samples.isNotEmpty) { - time = math.max(time, samples.last.timestamp); - } - - final HeapSample sample = HeapSample( - time, - processRss, - capacity + external, - used, - external, - fromGC, - adbMemoryInfo, - ); - - _addSample(sample); - memoryController.memoryTimeline.addSample(sample); - } - - void _addSample(HeapSample sample) { - samples.add(sample); - - _changeController.add(null); - } -} - -// Heap Statistics - -// Wrapper for ClassHeapStats. -// -// Pre VM Service Protocol 3.18: -// { -// type: ClassHeapStats, -// class: {type: @Class, fixedId: true, id: classes/5, name: Class}, -// new: [0, 0, 0, 0, 0, 0, 0, 0], -// old: [3892, 809536, 3892, 809536, 0, 0, 0, 0], -// promotedInstances: 0, -// promotedBytes: 0 -// } -// -// VM Service Protocol 3.18 and later: -// { -// type: ClassHeapStats, -// class: {type: @Class, fixedId: true, id: classes/5, name: Class}, -// accumulatedSize: 809536 -// bytesCurrent: 809536 -// instancesAccumulated: 3892 -// instancesCurrent: 3892 -// } -class ClassHeapDetailStats { - ClassHeapDetailStats(this.json) { - classRef = ClassRef.parse(json['class']); - if (serviceManager.service.protocolVersionSupported( - supportedVersion: SemanticVersion(major: 3, minor: 18))) { - instancesCurrent = json['instancesCurrent']; - instancesAccumulated = json['instancesAccumulated']; - bytesCurrent = json['bytesCurrent']; - bytesAccumulated = json['bytesAccumulated']; - } else { - _update(json['new']); - _update(json['old']); - } - } - - static const int ALLOCATED_BEFORE_GC = 0; - static const int ALLOCATED_BEFORE_GC_SIZE = 1; - static const int LIVE_AFTER_GC = 2; - static const int LIVE_AFTER_GC_SIZE = 3; - static const int ALLOCATED_SINCE_GC = 4; - static const int ALLOCATED_SINCE_GC_SIZE = 5; - static const int ACCUMULATED = 6; - static const int ACCUMULATED_SIZE = 7; - - final Map json; - - int instancesCurrent = 0; - int instancesAccumulated = 0; - int bytesCurrent = 0; - int bytesAccumulated = 0; - - ClassRef classRef; - - String get type => json['type']; - - void _update(List stats) { - instancesAccumulated += stats[ACCUMULATED]; - bytesAccumulated += stats[ACCUMULATED_SIZE]; - instancesCurrent += stats[LIVE_AFTER_GC] + stats[ALLOCATED_SINCE_GC]; - bytesCurrent += stats[LIVE_AFTER_GC_SIZE] + stats[ALLOCATED_SINCE_GC_SIZE]; - } - - @override - String toString() => '[ClassHeapStats type: $type, class: ${classRef.name}, ' - 'count: $instancesCurrent, bytes: $bytesCurrent]'; -} - -class InstanceSummary { - InstanceSummary(this.classRef, this.className, this.objectRef); - - final String classRef; - final String className; - final String objectRef; - - @override - String toString() => '[InstanceSummary id: $objectRef, class: $classRef]'; -} - -class InstanceData { - InstanceData(this.instance, this.name, this.value); - - final InstanceSummary instance; - final String name; - final dynamic value; - - @override - String toString() => '[InstanceData name: $name, value: $value]'; -} diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_analyzer.dart b/packages/devtools_app/lib/src/memory/memory_analyzer.dart similarity index 99% rename from packages/devtools_app/lib/src/memory/flutter/memory_analyzer.dart rename to packages/devtools_app/lib/src/memory/memory_analyzer.dart index 7f45a0e3424..e73191cd878 100644 --- a/packages/devtools_app/lib/src/memory/flutter/memory_analyzer.dart +++ b/packages/devtools_app/lib/src/memory/memory_analyzer.dart @@ -8,12 +8,11 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:vm_service/vm_service.dart'; -import '../../config_specific/logger/logger.dart' as logger; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/table.dart'; -import '../../table_data.dart'; -import '../../utils.dart'; - +import '../auto_dispose_mixin.dart'; +import '../config_specific/logger/logger.dart' as logger; +import '../table.dart'; +import '../table_data.dart'; +import '../utils.dart'; import 'memory_controller.dart'; import 'memory_graph_model.dart'; import 'memory_heap_tree_view.dart'; diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_chart.dart b/packages/devtools_app/lib/src/memory/memory_chart.dart similarity index 99% rename from packages/devtools_app/lib/src/memory/flutter/memory_chart.dart rename to packages/devtools_app/lib/src/memory/memory_chart.dart index 92a71a04393..7166d099fcf 100644 --- a/packages/devtools_app/lib/src/memory/flutter/memory_chart.dart +++ b/packages/devtools_app/lib/src/memory/memory_chart.dart @@ -29,9 +29,9 @@ import 'package:mp_chart/mp/core/value_formatter/large_value_formatter.dart'; import 'package:mp_chart/mp/core/value_formatter/value_formatter.dart'; import 'package:provider/provider.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/theme.dart'; -import '../../ui/theme.dart'; +import '../auto_dispose_mixin.dart'; +import '../theme.dart'; +import '../ui/theme.dart'; import 'memory_controller.dart'; class MemoryChart extends StatefulWidget { diff --git a/packages/devtools_app/lib/src/memory/memory_controller.dart b/packages/devtools_app/lib/src/memory/memory_controller.dart index 5e63f301731..8fb7e6cdd2a 100644 --- a/packages/devtools_app/lib/src/memory/memory_controller.dart +++ b/packages/devtools_app/lib/src/memory/memory_controller.dart @@ -2,33 +2,431 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(terry): File is deprecated (HTML only app) and should be removed -// when the DevTools app is the package:flutter version. - import 'dart:async'; +import 'dart:ui' as dart_ui; -import 'package:pedantic/pedantic.dart'; +import 'package:devtools_shared/devtools_shared.dart'; +import 'package:flutter/foundation.dart'; +import 'package:intl/intl.dart'; +import 'package:meta/meta.dart'; +import 'package:mp_chart/mp/core/entry/entry.dart'; import 'package:vm_service/vm_service.dart'; +import '../auto_dispose.dart'; +import '../config_specific/file/file.dart'; import '../config_specific/logger/logger.dart'; import '../globals.dart'; -import '../vm_service_wrapper.dart'; +import '../service_manager.dart'; +import '../table.dart'; +import '../ui/utils.dart'; +import '../utils.dart'; +import 'memory_filter.dart'; +import 'memory_graph_model.dart'; import 'memory_protocol.dart'; import 'memory_service.dart'; +import 'memory_snapshot_models.dart'; + +enum ChartType { + DartHeaps, + AndroidHeaps, +} + +typedef chartStateListener = void Function(); + +// TODO(terry): Consider supporting more than one file since app was launched. +// Memory Log filename. +final String _memoryLogFilename = + '${MemoryController.logFilenamePrefix}${DateFormat("yyyyMMdd_hh_mm").format(DateTime.now())}'; /// This class contains the business logic for [memory.dart]. /// /// This class must not have direct dependencies on dart:html. This allows tests /// of the complicated logic in this class to run on the VM and will help /// simplify porting this code to work with Flutter Web. -class MemoryController { - MemoryController(); +class MemoryController extends DisposableController + with AutoDisposeControllerMixin { + MemoryController() { + memoryTimeline = MemoryTimeline(this); + memoryLog = MemoryLog(this); + } + + static const logFilenamePrefix = 'memory_log_'; + + bool showHeatMap = true; + + final snapshots = []; + + Snapshot get lastSnapshot => snapshots.safeLast; + + /// Root nodes names that contains nodes of either libraries or classes depending on + /// group by library or group by class. + static const libraryRootNode = '___LIBRARY___'; + static const classRootNode = '___CLASSES___'; + + /// Notifies that the source of the memory feed has changed. + ValueListenable get selectedSnapshotNotifier => + _selectedSnapshotNotifier; + + /// Stored value is pretty timestamp when the snapshot was done. + final _selectedSnapshotNotifier = ValueNotifier(''); + + set selectedSnapshotTimestamp(String snapshotTimestamp) { + _selectedSnapshotNotifier.value = snapshotTimestamp; + } + + String get selectedSnapshotTimestamp => _selectedSnapshotNotifier.value; + + HeapGraph heapGraph; + + /// Leaf node of tabletree snapshot selected? If selected then the instance + /// view is displayed to view the fields of an instance. + final _leafSelectedNotifier = ValueNotifier(null); + + ValueListenable get leafSelectedNotifier => + _leafSelectedNotifier; + + HeapGraphElementLive get selectedLeaf => _leafSelectedNotifier.value; + + set selectedLeaf(HeapGraphElementLive selected) { + _leafSelectedNotifier.value = selected; + } + + bool get isLeafSelected => selectedLeaf != null; + + void computeRoot() { + if (selectedLeaf != null) { + final root = instanceToFieldNodes(this, selectedLeaf); + _instanceRoot = root.isNotEmpty ? root : [FieldReference.empty]; + } else { + _instanceRoot = [FieldReference.empty]; + } + } + + List _instanceRoot; + + List get instanceRoot => _instanceRoot; + + /// Leaf node of analysis selected? If selected then the field + /// view is displayed to view an abbreviated fields of an instance. + final _leafAnalysisSelectedNotifier = ValueNotifier(null); + + ValueListenable get leafAnalysisSelectedNotifier => + _leafAnalysisSelectedNotifier; + + AnalysisInstance get selectedAnalysisLeaf => + _leafAnalysisSelectedNotifier.value; + + set selectedAnalysisLeaf(AnalysisInstance selected) { + _leafAnalysisSelectedNotifier.value = selected; + } + + bool get isAnalysisLeafSelected => selectedAnalysisLeaf != null; + + void computeAnalysisInstanceRoot() { + if (selectedAnalysisLeaf != null) { + final analysisFields = selectedAnalysisLeaf.fieldsRoot.children; + _analysisInstanceRoot = + analysisFields.isNotEmpty ? analysisFields : [AnalysisField.empty]; + } else { + _analysisInstanceRoot = [AnalysisField.empty]; + } + } + + List _analysisInstanceRoot; + + List get analysisInstanceRoot => _analysisInstanceRoot; + + // List of completed Analysis of Snapshots. + final List completedAnalyses = []; + + bool enableAnalyzeButton() { + if (snapshots.isNotEmpty) { + final lastSnapshot = snapshots.last; + if (completedAnalyses.isNotEmpty) { + final result = completedAnalyses.last.dateTime.compareTo( + lastSnapshot.collectedTimestamp, + ) != + 0; + return result; + } + return true; + } + + return false; + } + + MemoryTimeline memoryTimeline; + + MemoryLog memoryLog; + + /// Source of memory heap samples. False live data, True loaded from a + /// memory_log file. + bool offline = false; + + HeapSample _selectedDartSample; + + HeapSample _selectedAndroidSample; + + HeapSample getSelectedSample(ChartType type) => type == ChartType.DartHeaps + ? _selectedDartSample + : _selectedAndroidSample; + + void setSelectedSample(ChartType type, HeapSample sample) { + if (type == ChartType.DartHeaps) + _selectedDartSample = sample; + else + _selectedAndroidSample = sample; + } + + static const liveFeed = 'Live Feed'; + + String memorySourcePrefix; + + /// Notifies that the source of the memory feed has changed. + ValueListenable get memorySourceNotifier => _memorySourceNotifier; + + final _memorySourceNotifier = ValueNotifier(liveFeed); + + set memorySource(String source) { + _memorySourceNotifier.value = source; + } + + String get memorySource => _memorySourceNotifier.value; + + /// Starting chunk for slider based on the intervalDurationInMs. + double sliderValue = 1.0; + + /// Number of interval stops for the timeline slider e.g., for 15 minutes of + /// collected data, displayed at a 5 minute interval there will be 3 stops, + /// each stop would be 5 minutes prior to the previous stop. + int numberOfStops = 0; + + /// Compute total timeline stops used by Timeline slider. + int computeStops() { + int stops = 0; + if (memoryTimeline.data.isNotEmpty) { + final lastSampleTimestamp = memoryTimeline.data.last.timestamp.toDouble(); + final firstSampleTimestamp = + memoryTimeline.data.first.timestamp.toDouble(); + stops = + ((lastSampleTimestamp - firstSampleTimestamp) / intervalDurationInMs) + .round(); + } + return stops == 0 ? 1 : stops; + } + + /// Automatic pruning of memory statistics (plotted) full data is still retained. + static const displayOneMinute = '1'; + static const displayFiveMinutes = '5'; + static const displayTenMinutes = '10'; + static const displayAllMinutes = 'All'; + + /// Default is to display last minute of collected data in the chart. + final _displayIntervalNotifier = ValueNotifier(displayOneMinute); + + ValueListenable get displayIntervalNotifier => + _displayIntervalNotifier; + + set displayInterval(String interval) { + _displayIntervalNotifier.value = interval; + } + + String get displayInterval => _displayIntervalNotifier.value; + + /// 1 minute in milliseconds. + static const int minuteInMs = 60 * 1000; + + /// Return the pruning interval in milliseconds. + int get intervalDurationInMs => (displayInterval == displayAllMinutes) + ? maxJsInt + : int.parse(displayInterval) * minuteInMs; + + /// MemorySource has changed update the view. + void updatedMemorySource() { + if (memorySource == MemoryController.liveFeed) { + if (offline) { + // User is switching back to 'Live Feed'. + memoryTimeline.offlineData.clear(); + offline = false; // We're live again... + } else { + // Still a live feed - keep collecting. + assert(!offline); + } + } else { + // Switching to an offline memory log (JSON file in /tmp). + memoryLog.loadOffline(memorySource); + } + + // The memory source has changed, clear all plotted values. + memoryTimeline.dartChartData.reset(); + memoryTimeline.androidChartData.reset(); + } + + void recomputeOfflineData() { + final args = memoryTimeline.recomputeOfflineData(intervalDurationInMs); + processDataset(args); + } + + void recomputeData() { + final args = memoryTimeline.recomputeLiveData(intervalDurationInMs); + processDataset(args); + // TODO(terry): need to recomputeOffline data? + } + + void processDataset(List args) { + // Add entries of entries plotted in the chart. Entries plotted + // may not match data collected (based on display interval). + for (var arg in args) { + memoryTimeline.dartChartData.addTraceEntries( + capacityValue: arg[MemoryTimeline.capcityValueKey], + usedValue: arg[MemoryTimeline.usedValueKey], + externalValue: arg[MemoryTimeline.externalValueKey], + minutesToDisplay: intervalDurationInMs, + ); + memoryTimeline.androidChartData.addTraceEntries( + javaValue: arg[MemoryTimeline.javaHeapValueKey], + nativeValue: arg[MemoryTimeline.nativeHeapValueKey], + codeValue: arg[MemoryTimeline.codeValueKey], + stackValue: arg[MemoryTimeline.stackValueKey], + graphicsValue: arg[MemoryTimeline.graphicsValueKey], + otherValue: arg[MemoryTimeline.otherValueKey], + systemValue: arg[MemoryTimeline.systemValueKey], + totalValue: arg[MemoryTimeline.totalValueKey], + minutesToDisplay: intervalDurationInMs, + ); + + if (memoryTimeline.dartChartData.pruned) { + memoryTimeline.startingIndex++; + } + } + } + + void processData([bool reloadAllData = false]) { + final args = offline + ? memoryTimeline.fetchMemoryLogFileData() + : memoryTimeline.fetchLiveData(reloadAllData); + + processDataset(args); + } + + final _paused = ValueNotifier(false); + + ValueListenable get paused => _paused; + + void pauseLiveFeed() { + _paused.value = true; + } + + void resumeLiveFeed() { + _paused.value = false; + } + + bool _androidChartVisible = false; + + bool get isAndroidChartVisible => _androidChartVisible; + + bool toggleAndroidChartVisibility() => + _androidChartVisible = !_androidChartVisible; final SettingsModel settings = SettingsModel(); + final selectionNotifier = + ValueNotifier>(Selection()); + + /// Tree to view Libary/Class/Instance (grouped by) + TreeTable groupByTreeTable; + + /// Tree to view fields of an instance. + TreeTable instanceFieldsTreeTable; + + /// Tree to view fields of an analysis. + TreeTable analysisFieldsTreeTable; + + /// State of filters used by filter dialog (create/modify) and used + /// by filtering in grouping. final FilteredLibraries libraryFilters = FilteredLibraries(); - LibraryCollection libraryCollection; + /// Root of all known libraries. + LibraryReference libraryRoot; + + /// Root of known classes (used for group by class). + LibraryReference classRoot; + + /// Used by the filter dialog, grouped name displayed in filter dialog + /// e.g., dart:*, package:flutter/* + /// + /// The key is the group name (displayed in dialog), value is list of + /// libraries associated to the group. Structure is used to: + /// - allow user to hide/show a library when filtering a snapshot. + /// - create the hide list of libraries to drive the UX on when showing + /// list of libraries/classes/objects in a snapshot table. + final filteredLibrariesByGroupName = >{}; + + /// Notify that the filtering has changed. + ValueListenable get filterNotifier => _filterNotifier; + + final _filterNotifier = ValueNotifier(0); + + void updateFilter() { + _filterNotifier.value++; + } + + /// Hide any class that hasn't been constructed (zero instances). + final filterZeroInstances = CheckboxValueNotifier(true); + + ValueListenable get filterZeroInstancesListenable => + filterZeroInstances; + + /// Hide any private class, prefixed with an underscore. + final filterPrivateClasses = CheckboxValueNotifier(true); + + ValueListenable get filterPrivateClassesListenable => + filterPrivateClasses; + + /// Hide any library with no constructed class instances. + final filterLibraryNoInstances = CheckboxValueNotifier(true); + + ValueListenable get filterLibraryNoInstancesListenable => + filterLibraryNoInstances; + + /// Table ordered by library, class or instance + static const groupByLibrary = 'Library'; + static const groupByClass = 'Class'; + static const groupByInstance = 'Instance'; + + final groupingBy = ValueNotifier(groupByLibrary); + + ValueListenable get groupingByNotifier => groupingBy; + + final selectTheSearchNotifier = ValueNotifier(false); + + bool get selectTheSearch => selectTheSearchNotifier.value; + + /// Search is very dynamic, with auto-complete or programmatic searching, + /// setting the value to true will fire off searching through a snapshot. + set selectTheSearch(bool v) { + selectTheSearchNotifier.value = v; + } + + final _searchNotifier = ValueNotifier(''); + + /// Notify that the search has changed. + ValueListenable get searchNotifier => _searchNotifier; + + set search(String value) { + _searchNotifier.value = value; + } + + String get search => _searchNotifier.value; + + final searchAutoComplete = ValueNotifier>([]); + + ValueListenable> get searchAutoCompleteNotifier => + searchAutoComplete; + + void clearSearchAutoComplete() { + searchAutoComplete.value = []; + } String get _isolateId => serviceManager.isolateManager.selectedIsolate.id; @@ -52,12 +450,29 @@ class MemoryController { // TODO(terry): Need an event on the controller for this too? } - void _handleConnectionStart(VmServiceWrapper service) { - _memoryTracker = MemoryTracker(service); + void _handleConnectionStart(ServiceConnectionManager serviceManager) { + _memoryTracker = MemoryTracker(serviceManager, this); _memoryTracker.start(); - _memoryTracker.onChange.listen((_) { - _memoryTrackerController.add(_memoryTracker); + autoDispose( + _memoryTracker.onChange.listen((_) { + _memoryTrackerController.add(_memoryTracker); + }), + ); + autoDispose( + _memoryTracker.onChange.listen((_) { + _memoryTrackerController.add(_memoryTracker); + }), + ); + + // TODO(terry): Used to detect stream being closed from the + // memoryController dispose method. Needed when a HOT RELOAD + // will call dispose however, spinup (initState) doesn't seem + // to happen David is working on scaffolding. + _memoryTrackerController.stream.listen((_) {}, onDone: () { + // Stop polling and reset memoryTracker. + _memoryTracker.stop(); + _memoryTracker = null; }); } @@ -70,23 +485,36 @@ class MemoryController { } Future startTimeline() async { - serviceManager.isolateManager.onSelectedIsolateChanged.listen((_) { - _handleIsolateChanged(); - }); + autoDispose( + serviceManager.isolateManager.onSelectedIsolateChanged.listen((_) { + _handleIsolateChanged(); + }), + ); - serviceManager.onConnectionAvailable.listen(_handleConnectionStart); + autoDispose( + serviceManager.onConnectionAvailable + .listen((_) => _handleConnectionStart(serviceManager)), + ); if (serviceManager.hasConnection) { - _handleConnectionStart(serviceManager.service); + _handleConnectionStart(serviceManager); } - serviceManager.onConnectionClosed.listen(_handleConnectionStop); + autoDispose( + serviceManager.onConnectionClosed.listen(_handleConnectionStop), + ); + } + + Future snapshotMemory() async { + return await serviceManager.service + .getHeapSnapshotGraph(serviceManager.isolateManager.selectedIsolate); } Future> resetAllocationProfile() => getAllocationProfile(reset: true); // 'reset': true to reset the object allocation accumulators - Future> getAllocationProfile( - {bool reset = false}) async { + Future> getAllocationProfile({ + bool reset = false, + }) async { AllocationProfile allocationProfile; try { allocationProfile = await serviceManager.service.getAllocationProfile( @@ -103,8 +531,15 @@ class MemoryController { }).toList(); } + bool get isConnectedDeviceAndroid { + return serviceManager.vm.operatingSystem == 'android'; + } + Future> getInstances( - String classRef, String className, int maxInstances) async { + String classRef, + String className, + int maxInstances, + ) async { // TODO(terry): Expose as a stream to reduce stall when querying for 1000s // TODO(terry): of instances. InstanceSet instanceSet; @@ -123,33 +558,138 @@ class MemoryController { .toList(); } - void initializeLibraryFilters() {} - - Future computeLibraries() async { - if (libraryCollection == null) { - // TODO(terry): Review why unawaited is necessary. - unawaited(serviceManager.service.getVM().then((vm) { - Future.wait(vm.isolates.map((IsolateRef ref) { - return serviceManager.service.getIsolate(ref.id); - })).then((isolates) { - libraryCollection = LibraryCollection(libraryFilters); - for (LibraryRef libraryRef in isolates.first.libraries) { - serviceManager.service - .getObject(_isolateId, libraryRef.id) - .then((theLibrary) { - libraryCollection.addLibrary(theLibrary); - }); - } + /// When new snapshot occurs entire libraries should be rebuilt then rebuild should be true. + LibraryReference computeAllLibraries([ + bool filtered = true, + bool rebuild = false, + ]) { + if (snapshots.isEmpty) return null; + + if (filtered && libraryRoot != null && !rebuild) return libraryRoot; + + // Group by library + libraryRoot = LibraryReference(this, libraryRootNode, null); + + final analysesRoot = AnalysesReference(); + analysesRoot.addChild(AnalysisReference('')); + libraryRoot.addChild(analysesRoot); + + // Group by class (under root library __CLASSES__). + classRoot = LibraryReference(this, classRootNode, null); + + final snapshotgraph = snapshots.last.snapshotGraph; + final externalReferences = + ExternalReferences(this, snapshotgraph.externalSize); + for (final liveExternal in heapGraph.externals) { + final HeapGraphClassLive classLive = liveExternal.live.theClass; + + ExternalReference externalReference; + + if (externalReferences.children.isNotEmpty) { + externalReference = externalReferences.children.singleWhere( + (knownClass) => knownClass.name == classLive.name, + orElse: () => null, + ); + } + + if (externalReference == null) { + externalReference = + ExternalReference(this, classLive.name, liveExternal); + externalReferences.addChild(externalReference); + } - libraryCollection.computeDisplayClasses(); - }); - })); + final classInstance = ExternalObjectReference( + this, + externalReference.children.length, + liveExternal.live, + liveExternal.externalProperty.externalSize, + ); + + // Sum up the externalSize of the children, under the externalReference group. + externalReference.sumExternalSizes += + liveExternal.externalProperty.externalSize; + + externalReference.addChild(classInstance); } + + libraryRoot.addChild(externalReferences); + + // Add our filtered items under the 'Filtered' node. + if (filtered) { + final filteredReference = FilteredReference(this); + final filtered = heapGraph.filteredLibraries; + addAllToNode(filteredReference, filtered); + + libraryRoot.addChild(filteredReference); + } + + // Compute all libraries. + final groupBy = + filtered ? heapGraph.groupByLibrary : heapGraph.rawGroupByLibrary; + + groupBy.forEach((libraryName, classes) { + LibraryReference libReference = + libraryRoot.children.singleWhere((library) { + return libraryName == library.name; + }, orElse: () => null); + + // Library not found add to list of children. + if (libReference == null) { + libReference = LibraryReference(this, libraryName, classes); + libraryRoot.addChild(libReference); + } + + for (var actualClass in libReference.actualClasses) { + monitorClass( + className: actualClass.name, + message: 'computeAllLibraries', + ); + final classRef = ClassReference(this, actualClass); + classRef.addChild(Reference.empty); + + libReference.addChild(classRef); + + // TODO(terry): Consider adding the ability to clear the table tree cache + // (root) to reset the level/depth values. + final classRefClassGroupBy = ClassReference(this, actualClass); + classRefClassGroupBy.addChild(Reference.empty); + classRoot.addChild(classRefClassGroupBy); + } + }); + + return libraryRoot; } - // Keys in the libraries map is a normalized library name. - List sortLibrariesByNormalizedNames() => - libraryCollection.librarires.keys.toList()..sort(); + // TODO(terry): Change to Set of known libraries so it's O(n) instead of O(n^2). + void addAllToNode( + Reference root, Map> allItems) { + allItems.forEach((libraryName, classes) { + LibraryReference libReference = root.children.singleWhere((library) { + return libraryName == library.name; + }, orElse: () => null); + + // Library not found add to list of children. + libReference ??= LibraryReference(this, libraryName, classes); + root.addChild(libReference); + + for (var actualClass in libReference.actualClasses) { + monitorClass( + className: actualClass.name, + message: 'computeAllLibraries', + ); + final classRef = ClassReference(this, actualClass); + classRef.addChild(Reference.empty); + + libReference.addChild(classRef); + + // TODO(terry): Consider adding the ability to clear the table tree cache + // (root) to reset the level/depth values. + final classRefClassGroupBy = ClassReference(this, actualClass); + classRefClassGroupBy.addChild(Reference.empty); + classRoot.addChild(classRefClassGroupBy); + } + }); + } Future getObject(String objectRef) async => await serviceManager.service.getObject( @@ -157,11 +697,20 @@ class MemoryController { objectRef, ); + bool _gcing = false; + bool get isGcing => _gcing; + Future gc() async { - await serviceManager.service.getAllocationProfile( - _isolateId, - gc: true, - ); + _gcing = true; + + try { + await serviceManager.service.getAllocationProfile( + _isolateId, + gc: true, + ); + } finally { + _gcing = false; + } } // Temporary hack to allow accessing private fields(e.g., _extra) using eval @@ -198,6 +747,25 @@ class MemoryController { return false; } + + List snapshotByLibraryData; + + void createSnapshotByLibrary() { + snapshotByLibraryData ??= lastSnapshot?.librariesToList(); + } + + void storeSnapshot(DateTime timestamp, HeapSnapshotGraph graph) { + snapshots.add(Snapshot(timestamp, this, graph)); + } + + @override + void dispose() { + super.dispose(); + _displayIntervalNotifier.dispose(); + _memorySourceNotifier.dispose(); + _disconnectController.close(); + _memoryTrackerController.close(); + } } /// Settings dialog model. @@ -217,170 +785,509 @@ class SettingsModel { bool experiment = false; } -const String _dartLibraryUriPrefix = 'dart:'; -const String _flutterLibraryUriPrefix = 'package:flutter'; - -class FilteredLibraries { - final List _filteredLibraries = [ - normalizedDartLibraryUri, - normalizedFlutterLibraryUri, - ]; - - static const String normalizedDartLibraryUri = 'Dart'; - static const String normalizedFlutterLibraryUri = 'Flutter'; - - static String normalizeLibraryUri(Library library) { - final uriParts = library.uri.split('/'); - final firstPart = uriParts.first; - if (firstPart.startsWith(_dartLibraryUriPrefix)) { - return FilteredLibraries.normalizedDartLibraryUri; - } else if (firstPart.startsWith(_flutterLibraryUriPrefix)) { - return FilteredLibraries.normalizedFlutterLibraryUri; - } else { - return firstPart; +/// Prepare data to plot in MPChart. +class MPChartData { + bool _pruning = false; + + /// Signal that every addTrace will cause a prune. + bool get pruned => _pruning; + + /// Datapoint entries for each used heap value. + final List used = []; + + /// Datapoint entries for each capacity heap value. + final List capacity = []; + + /// Datapoint entries for each external memory value. + final List externalHeap = []; + + /// Add each entry to its corresponding trace. + void addTraceEntries({ + Entry capacityValue, + Entry usedValue, + Entry externalValue, + int minutesToDisplay, + }) { + if (!_pruning && + externalHeap.isNotEmpty && + (externalValue.x - externalHeap.first.x) > minutesToDisplay) { + _pruning = true; + assert(externalValue.x - externalHeap.last.x <= minutesToDisplay); + } + + // TODO(terry): Any way have a kind of trace order safe way to so we + // can keep an list of the entries (remoteAt and add). + if (_pruning) { + externalHeap.removeAt(0); + used.removeAt(0); + capacity.removeAt(0); } + + externalHeap.add(externalValue); + used.add(usedValue); + capacity.add(capacityValue); + } + + /// Remove all plotted entries in all traces. + void reset() { + // TODO(terry): Any way have a kind of trace order safe way to so we + // can keep an list of the entries (clear). + used.clear(); + capacity.clear(); + externalHeap.clear(); + _pruning = false; } +} + +/// Prepare Engine (ADB memory info) data to plot in MPChart. +class MPEngineChartData { + bool _pruning = false; + + /// Datapoint entries for each Java heap value. + final List javaHeap = []; + + /// Datapoint entries for each native heap value. + final List nativeHeap = []; + + /// Datapoint entries for code size value. + final List code = []; + + /// Datapoint entries for stack size value. + final List stack = []; - List get librariesFiltered => _filteredLibraries.toList(); + /// Datapoint entries for graphics size value. + final List graphics = []; - bool get isDartLibraryFiltered => - _filteredLibraries.contains(normalizedDartLibraryUri); + /// Datapoint entries for other size value. + final List other = []; - bool get isFlutterLibraryFiltered => - _filteredLibraries.contains(normalizedFlutterLibraryUri); + /// Datapoint entries for system size value. + final List system = []; - void clearFilters() { - _filteredLibraries.clear(); + /// Datapoint entries for total size value. + final List total = []; + + /// Add each entry to its corresponding trace. + void addTraceEntries({ + Entry javaValue, + Entry nativeValue, + Entry codeValue, + Entry stackValue, + Entry graphicsValue, + Entry otherValue, + Entry systemValue, + Entry totalValue, + int minutesToDisplay, + }) { + if (!_pruning && + javaHeap.isNotEmpty && + (javaValue.x - javaHeap.first.x) > minutesToDisplay) { + _pruning = true; + + assert(javaValue.x - javaHeap.last.x <= minutesToDisplay); + } + + // TODO(terry): Any way have a kind of trace order safe way to so we + // can keep an list of the entries (remoteAt and add). + if (_pruning) { + javaHeap.removeAt(0); + nativeHeap.removeAt(0); + code.removeAt(0); + stack.removeAt(0); + graphics.removeAt(0); + other.removeAt(0); + system.removeAt(0); + total.removeAt(0); + } + + javaHeap.add(javaValue); + nativeHeap.add(nativeValue); + code.add(codeValue); + stack.add(stackValue); + graphics.add(graphicsValue); + other.add(otherValue); + system.add(systemValue); + total.add(totalValue); } - void addFilter(String libraryUri) { - _filteredLibraries.add(libraryUri); + /// Remove all plotted entries in all traces. + void reset() { + // TODO(terry): Any way have a kind of trace order safe way to so we + // can keep an list of the entries (clear). + javaHeap.clear(); + nativeHeap.clear(); + code.clear(); + stack.clear(); + graphics.clear(); + other.clear(); + system.clear(); + total.clear(); + _pruning = false; } +} + +/// All Raw data received from the VM and offline data loaded from a memory log file. +class MemoryTimeline { + MemoryTimeline(this.controller); - void removeFilter(String libraryUri) { - _filteredLibraries.remove(libraryUri); + /// Version of timeline data (HeapSample) JSON payload. + static const version = 1; + + /// Keys used in a map to store all the MPChart Entries we construct to be plotted. + static const capcityValueKey = 'capacityValue'; + static const usedValueKey = 'usedValue'; + static const externalValueKey = 'externalValue'; + static const rssValueKey = 'rssValue'; + + /// Keys used in a map to store all the MPEngineChart Entries we construct to be plotted, + /// ADB memory info. + static const javaHeapValueKey = 'javaHeapValue'; + static const nativeHeapValueKey = 'nativeHeapValue'; + static const codeValueKey = 'codeValue'; + static const stackValueKey = 'stackValue'; + static const graphicsValueKey = 'graphicsValue'; + static const otherValueKey = 'otherValue'; + static const systemValueKey = 'systemValue'; + static const totalValueKey = 'totalValue'; + + final MemoryController controller; + + /// Flutter Framework information (Dart heaps). + final dartChartData = MPChartData(); + + /// Flutter Engine (ADB memory information). + final androidChartData = MPEngineChartData(); + + /// Return the data payload that is active. + List get data => controller.offline ? offlineData : liveData; + + int get startingIndex => + controller.offline ? offlineStartingIndex : liveStartingIndex; + + set startingIndex(int value) { + controller.offline + ? offlineStartingIndex = value + : liveStartingIndex = value; } - bool isDartLibrary(Library library) => - library.uri.startsWith(_dartLibraryUriPrefix); + int get endingIndex => data.isNotEmpty ? data.length - 1 : -1; - bool isFlutterLibrary(Library library) => - library.uri.startsWith(_flutterLibraryUriPrefix); + /// Raw Heap sampling data from the VM. + final List liveData = []; - bool isLibraryFiltered(String normalizedLibraryUri) => - _filteredLibraries.contains(normalizedLibraryUri); -} + /// Start index of liveData plotted for MPChartData/MPEngineChartData sets. + int liveStartingIndex = 0; -class LibraryCollection { - LibraryCollection(FilteredLibraries filters) : _libraryFilters = filters; + /// Data of the last selected offline memory source (JSON file in /tmp). + final List offlineData = []; - final FilteredLibraries _libraryFilters; + /// Start index of offlineData plotted for MPChartData/MPEngineChartData sets. + int offlineStartingIndex = 0; - /// normalizeLibraryUri, Library - final Map> librarires = {}; + /// Notifies that a new Heap sample has been added to the timeline. + final _sampleAddedNotifier = ValueNotifier(null); - /// Classes displayed in snapshot - classId and libraryId. - final Map displayClasses = {}; + ValueListenable get sampleAddedNotifier => _sampleAddedNotifier; - bool isDisplayClass(String classId) => displayClasses.containsKey(classId); + /// Whether the timeline has been manually paused via the Pause button. + bool manuallyPaused = false; - void addLibrary(Library library) { - final normalizedUri = FilteredLibraries.normalizeLibraryUri(library); - if (librarires[normalizedUri] == null) { - // Add first library to this normalizedUri. - librarires[normalizedUri] = [library]; - } else { - // Add subsequent library to this normalizedUri. - librarires[normalizedUri].add(library); - } + /// Notifies that the timeline has been paused. + final _pausedNotifier = ValueNotifier(false); + + ValueNotifier get pausedNotifier => _pausedNotifier; - _filterOrShowClasses(library); + void pause({bool manual = false}) { + manuallyPaused = manual; + _pausedNotifier.value = true; } - void _filterOrShowClasses(Library library) { - final normalizedUri = FilteredLibraries.normalizeLibraryUri(library); - if (_libraryFilters.isLibraryFiltered(normalizedUri)) { - // We're filtering this library - nothing to show. - return; - } + void resume() { + manuallyPaused = false; + _pausedNotifier.value = false; + } - // This library isn't being filtered so show all its classes. - for (ClassRef classRef in library.classes) { - showClass(classRef.id, library); - } + /// Notifies any visible marker for a particular chart should be hidden. + final _markerHiddenNotifier = ValueNotifier(false); + + ValueListenable get markerHiddenNotifier => _markerHiddenNotifier; + + void hideMarkers() { + _markerHiddenNotifier.value = !_markerHiddenNotifier.value; } - /// Called from filter dialog when "apply" is clicked. - void computeDisplayClasses([FilteredLibraries filters]) { - final librariesFiltered = filters == null ? _libraryFilters : filters; - displayClasses.clear(); + /// dart_ui.Image Image asset displayed for each entry plotted in a chart. + // ignore: unused_field + dart_ui.Image _img; - librarires.forEach((String normalizedUri, List libraries) { - if (librariesFiltered.librariesFiltered.contains(normalizedUri)) { - for (var library in libraries) { - for (var theClass in library.classes) { - filterClass(theClass.id); - } - } - } else { - for (var library in libraries) { - for (var theClass in library.classes) { - showClass(theClass.id, library); - } - } - } - }); + // TODO(terry): Look at using _img for each data point (at least last N). + dart_ui.Image get dataPointImage => null; + + set image(dart_ui.Image img) { + _img = img; + } + + void reset() { + liveData.clear(); + startingIndex = 0; + dartChartData.reset(); + androidChartData.reset(); } - Library findDartLibrary(String libraryId) => - librarires[FilteredLibraries.normalizedDartLibraryUri].firstWhere( - (Library library) => library.id == libraryId, - orElse: () => null); + /// Common utility function to handle loading of the data into the + /// chart for either offline or live Feed. + List _processData(int index) { + final result = >[]; + + for (var lastIndex = index; lastIndex < data.length; lastIndex++) { + final sample = data[lastIndex]; + final timestamp = sample.timestamp.toDouble(); + + // Flutter Framework memory (Dart VM Heaps) + final capacity = sample.capacity.toDouble(); + final used = sample.used.toDouble(); + final external = sample.external.toDouble(); + + // TOOD(terry): Need to plot. + final rss = (sample.rss ?? 0).toDouble(); + + final extEntry = Entry(x: timestamp, y: external, icon: dataPointImage); + final usedEntry = + Entry(x: timestamp, y: used + external, icon: dataPointImage); + final capacityEntry = + Entry(x: timestamp, y: capacity, icon: dataPointImage); + final rssEntry = Entry(x: timestamp, y: rss, icon: dataPointImage); + + // Engine memory values (ADB Android): + final javaHeap = sample.adbMemoryInfo.javaHeap.toDouble(); + final nativeHeap = sample.adbMemoryInfo.nativeHeap.toDouble(); + final code = sample.adbMemoryInfo.code.toDouble(); + final stack = sample.adbMemoryInfo.stack.toDouble(); + final graphics = sample.adbMemoryInfo.graphics.toDouble(); + final other = sample.adbMemoryInfo.other.toDouble(); + final system = sample.adbMemoryInfo.system.toDouble(); + final total = sample.adbMemoryInfo.total.toDouble(); + + final graphicsEntry = Entry( + x: timestamp, + y: graphics, + icon: dataPointImage, + ); + final stackEntry = Entry( + x: timestamp, + y: stack + graphics, + icon: dataPointImage, + ); + final javaHeapEntry = Entry( + x: timestamp, + y: javaHeap + graphics + stack, + icon: dataPointImage, + ); + final nativeHeapEntry = Entry( + x: timestamp, + y: nativeHeap + javaHeap + graphics + stack, + icon: dataPointImage, + ); + final codeEntry = Entry( + x: timestamp, + y: code + nativeHeap + javaHeap + graphics + stack, + icon: dataPointImage, + ); + final otherEntry = Entry( + x: timestamp, + y: other + code + nativeHeap + javaHeap + graphics + stack, + icon: dataPointImage, + ); + final systemEntry = Entry( + x: timestamp, + y: system + other + code + nativeHeap + javaHeap + graphics + stack, + icon: dataPointImage, + ); + final totalEntry = Entry( + x: timestamp, + y: total, + icon: dataPointImage, + ); + + result.add({ + capcityValueKey: capacityEntry, + usedValueKey: usedEntry, + externalValueKey: extEntry, + rssValueKey: rssEntry, + javaHeapValueKey: javaHeapEntry, + nativeHeapValueKey: nativeHeapEntry, + codeValueKey: codeEntry, + stackValueKey: stackEntry, + graphicsValueKey: graphicsEntry, + otherValueKey: otherEntry, + systemValueKey: systemEntry, + totalValueKey: totalEntry, + }); + } - Library findFlutterLibrary(String libraryId) => - librarires[FilteredLibraries.normalizedFlutterLibraryUri].firstWhere( - (Library library) => library.id == libraryId, - orElse: () => null); + return result; + } + + /// Fetch all the data in the loaded from a memory log (JSON file in /tmp). + List fetchMemoryLogFileData() { + assert(controller.offline); + assert(offlineData.isNotEmpty); + return _processData(startingIndex); + } - Library findOtherLibrary(String libraryId) { - for (var libraries in librarires.values) { - for (var library in libraries) { - if (libraryId == library.id) return library; + List fetchLiveData([bool reloadAllData = false]) { + assert(!controller.offline); + assert(liveData.isNotEmpty); + + if (endingIndex - startingIndex != liveData.length || reloadAllData) { + // Process the data received (startingDataIndex is the last sample). + final args = _processData(endingIndex < 0 ? 0 : endingIndex); + + // Debugging data - to enable remove logical not operator. + if (!true) { + final DateFormat mFormat = DateFormat('hh:mm:ss.mmm'); + final startDT = mFormat.format(DateTime.fromMillisecondsSinceEpoch( + liveData[startingIndex].timestamp.toInt())); + final endDT = mFormat.format(DateTime.fromMillisecondsSinceEpoch( + liveData[endingIndex].timestamp.toInt())); + log('Time range Live data start: $startDT, end: $endDT'); } + + return args; } - return null; + return []; } - /// Class to actively display (otherwise class is filtered out of snapshot). - void showClass(String classId, Library library) { - displayClasses[classId] = library.id; + List recomputeOfflineData(int displayInterval) { + assert(displayInterval > 0); + + _computeStartingIndex(displayInterval); + + // Start from the first sample to display in this time interval. + return _processData(startingIndex); } - void filterClass(String classId) { - displayClasses.remove(classId); + List recomputeLiveData(int displayInterval) { + assert(displayInterval > 0); + + _computeStartingIndex(displayInterval); + + // Start from the first sample to display in this time interval. + return _processData(startingIndex); } - bool isDartLibrary(String classId) { - final dartLibrary = findDartLibrary(displayClasses[classId]); - if (dartLibrary != null) { - assert(dartLibrary.uri.startsWith(_dartLibraryUriPrefix)); - return true; + void _computeStartingIndex(int displayInterval) { + // Compute a new starting index from length - N minutes. + final timeLastSample = data.last.timestamp; + var dataIndex = data.length - 1; + for (; dataIndex > 0; dataIndex--) { + final sample = data[dataIndex]; + final timestamp = sample.timestamp; + + if ((timeLastSample - timestamp) > displayInterval) break; } - return false; + startingIndex = dataIndex; + + // Debugging data - to enable remove logical not operator. + if (!true) { + final DateFormat mFormat = DateFormat('hh:mm:ss.mmm'); + final startDT = mFormat.format(DateTime.fromMillisecondsSinceEpoch( + data[startingIndex].timestamp.toInt())); + final endDT = mFormat.format(DateTime.fromMillisecondsSinceEpoch( + data[endingIndex].timestamp.toInt())); + log('Recompute Time range Offline data start: $startDT, end: $endDT'); + } } - bool isFlutterLibrary(String classId) { - final flutterLibrary = findFlutterLibrary(displayClasses[classId]); - if (flutterLibrary != null) { - assert(flutterLibrary.uri.startsWith(_dartLibraryUriPrefix)); - return true; + void addSample(HeapSample sample) { + // Always record the heap sample in the raw set of data (liveFeed). + liveData.add(sample); + + // Only notify that new sample has arrived if the + // memory source is 'Live Feed'. + if (!controller.offline) { + _sampleAddedNotifier.value = sample; } + } +} - return false; +/// Supports saving and loading memory samples. +class MemoryLog { + MemoryLog(this.controller); + + /// Use in memory or local file system based on Flutter Web/Desktop. + static final _fs = FileIO(); + + MemoryController controller; + + /// Persist the the live memory data to a JSON file in the /tmp directory. + void exportMemory() async { + final liveData = controller.memoryTimeline.liveData; + + bool pseudoData = false; + if (liveData.isEmpty) { + // TODO(terry): Can eliminate once I add loading a canned data source + // see the todo in memory_screen_test. + // Used to create empty memory log for test. + pseudoData = true; + liveData.add(HeapSample( + DateTime.now().microsecondsSinceEpoch, + 0, + 0, + 0, + 0, + false, + AdbMemoryInfo.empty(), + )); + } + + final jsonPayload = MemoryJson.encodeHeapSamples(liveData); + if (kDebugMode) { + // TODO(terry): Remove this check add a unit test instead. + // Reload the file just created and validate that the saved data matches + // the live data. + final memoryJson = MemoryJson.decode(jsonPayload); + assert(memoryJson.isMatchedVersion); + assert(memoryJson.isMemoryPayload); + assert(memoryJson.data.length == liveData.length); + } + + _fs.writeStringToFile(_memoryLogFilename, jsonPayload); + + // TODO(terry): Display filename created in a toast. + + if (pseudoData) liveData.clear(); + } + + /// Return a list of offline memory logs filenames in the /tmp directory + /// that are available to open. + List offlineFiles() { + final memoryLogs = _fs.list(prefix: MemoryController.logFilenamePrefix); + + // Sort by newest file top-most (DateTime is in the filename). + memoryLogs.sort((a, b) => b.compareTo(a)); + + return memoryLogs; + } + + /// Load the memory profile data from a saved memory log file. + void loadOffline(String filename) async { + controller.offline = true; + + final jsonPayload = _fs.readStringFromFile(filename); + final memoryJson = MemoryJson.decode(jsonPayload); + + // TODO(terry): Display notification JSON file isn't version isn't + // supported or if the payload isn't an exported memory file. + assert(memoryJson.isMatchedVersion); + assert(memoryJson.isMemoryPayload); + + controller.memoryTimeline.offlineData.clear(); + controller.memoryTimeline.offlineData.addAll(memoryJson.data); } - bool isOtherLibrary(String classId) => - findOtherLibrary(displayClasses[classId]) != null; + @visibleForTesting + bool removeOfflineFile(String filename) => _fs.deleteFile(filename); } diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_filter.dart b/packages/devtools_app/lib/src/memory/memory_filter.dart similarity index 98% rename from packages/devtools_app/lib/src/memory/flutter/memory_filter.dart rename to packages/devtools_app/lib/src/memory/memory_filter.dart index abeb958a03d..8dc5bcb0a31 100644 --- a/packages/devtools_app/lib/src/memory/flutter/memory_filter.dart +++ b/packages/devtools_app/lib/src/memory/memory_filter.dart @@ -5,11 +5,11 @@ import 'package:flutter/material.dart'; import 'package:vm_service/vm_service.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/flutter_widgets/linked_scroll_controller.dart'; -import '../../ui/flutter/dialog.dart'; -import '../../ui/flutter/utils.dart'; +import '../auto_dispose_mixin.dart'; +import '../common_widgets.dart'; +import '../flutter_widgets/linked_scroll_controller.dart'; +import '../ui/dialog.dart'; +import '../ui/utils.dart'; import 'memory_controller.dart'; import 'memory_snapshot_models.dart'; diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_graph_model.dart b/packages/devtools_app/lib/src/memory/memory_graph_model.dart similarity index 99% rename from packages/devtools_app/lib/src/memory/flutter/memory_graph_model.dart rename to packages/devtools_app/lib/src/memory/memory_graph_model.dart index 716c837224c..ec1d64985f2 100644 --- a/packages/devtools_app/lib/src/memory/flutter/memory_graph_model.dart +++ b/packages/devtools_app/lib/src/memory/memory_graph_model.dart @@ -4,8 +4,8 @@ import 'package:vm_service/vm_service.dart'; -import '../../config_specific/logger/logger.dart'; -import '../flutter/memory_controller.dart'; +import '../config_specific/logger/logger.dart'; +import 'memory_controller.dart'; // TODO(terry): Ask Ben, what is a class name of ::? /// Internal class names :: automatically filter out. diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_heap_tree_view.dart b/packages/devtools_app/lib/src/memory/memory_heap_tree_view.dart similarity index 99% rename from packages/devtools_app/lib/src/memory/flutter/memory_heap_tree_view.dart rename to packages/devtools_app/lib/src/memory/memory_heap_tree_view.dart index bdbe20ec3c7..be5b9b14dca 100644 --- a/packages/devtools_app/lib/src/memory/flutter/memory_heap_tree_view.dart +++ b/packages/devtools_app/lib/src/memory/memory_heap_tree_view.dart @@ -10,13 +10,13 @@ import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -import '../../config_specific/logger/logger.dart' as logger; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/table.dart'; -import '../../flutter/theme.dart'; -import '../../table_data.dart'; -import '../../ui/flutter/label.dart'; -import '../../utils.dart'; +import '../auto_dispose_mixin.dart'; +import '../config_specific/logger/logger.dart' as logger; +import '../table.dart'; +import '../table_data.dart'; +import '../theme.dart'; +import '../ui/label.dart'; +import '../utils.dart'; import 'memory_analyzer.dart'; import 'memory_controller.dart'; import 'memory_filter.dart'; diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_heatmap.dart b/packages/devtools_app/lib/src/memory/memory_heatmap.dart similarity index 99% rename from packages/devtools_app/lib/src/memory/flutter/memory_heatmap.dart rename to packages/devtools_app/lib/src/memory/memory_heatmap.dart index 46fee14c152..5d18241ad6f 100644 --- a/packages/devtools_app/lib/src/memory/flutter/memory_heatmap.dart +++ b/packages/devtools_app/lib/src/memory/memory_heatmap.dart @@ -13,8 +13,8 @@ import 'package:flutter/widgets.dart' hide TextStyle; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../ui/colors.dart'; +import '../auto_dispose_mixin.dart'; +import '../ui/colors.dart'; import 'memory_controller.dart'; import 'memory_graph_model.dart'; diff --git a/packages/devtools_app/lib/src/memory/memory_protocol.dart b/packages/devtools_app/lib/src/memory/memory_protocol.dart index 9a367862578..4afe2b6b58e 100644 --- a/packages/devtools_app/lib/src/memory/memory_protocol.dart +++ b/packages/devtools_app/lib/src/memory/memory_protocol.dart @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(terry): File is deprecated (HTML only app) and should be removed -// when the DevTools app is the package:flutter version. - import 'dart:async'; import 'dart:math' as math; @@ -12,22 +9,33 @@ import 'package:devtools_shared/devtools_shared.dart'; import 'package:vm_service/vm_service.dart'; import '../globals.dart'; +import '../service_manager.dart'; import '../version.dart'; import '../vm_service_wrapper.dart'; +import 'memory_controller.dart'; class MemoryTracker { - MemoryTracker(this.service); + MemoryTracker(this.serviceManager, this.memoryController); + + static const Duration _updateDelay = Duration(milliseconds: 500); + + ServiceConnectionManager serviceManager; - static const Duration kUpdateDelay = Duration(milliseconds: 500); + final MemoryController memoryController; + + VmServiceWrapper get service => serviceManager?.service; - VmServiceWrapper service; Timer _pollingTimer; final List samples = []; - final Map> isolateHeaps = >{}; - int heapMax; + final Map isolateHeaps = {}; + + /// Polled VM current RSS. int processRss; + /// Polled adb dumpsys meminfo values. + AdbMemoryInfo adbMemoryInfo; + bool get hasConnection => service != null; Stream get onChange => _changeController.stream; @@ -39,89 +47,120 @@ class MemoryTracker { int get currentExternal => samples.last.external; + StreamSubscription _gcStreamListener; + void start() { - _pollingTimer = Timer(kUpdateDelay, _pollMemory); - service.onGCEvent.listen(_handleGCEvent); + _updateLiveDataPolling(memoryController.paused.value); + memoryController.paused.addListener(_updateLiveDataPolling); + } + + void _updateLiveDataPolling([bool paused]) { + paused ??= memoryController.paused.value; + + if (paused) { + _pollingTimer?.cancel(); + _gcStreamListener?.cancel(); + } else { + _pollingTimer = Timer(Duration.zero, _pollMemory); + _gcStreamListener = service.onGCEvent.listen(_handleGCEvent); + } } void stop() { - _pollingTimer?.cancel(); - service = null; + _updateLiveDataPolling(false); + memoryController.paused.removeListener(_updateLiveDataPolling); + serviceManager = null; } void _handleGCEvent(Event event) { - //final bool ignore = event.json['reason'] == 'compact'; + final HeapSpace newHeap = HeapSpace.parse(event.json['new']); + final HeapSpace oldHeap = HeapSpace.parse(event.json['old']); + + final MemoryUsage memoryUsage = MemoryUsage( + externalUsage: newHeap.external + oldHeap.external, + heapCapacity: newHeap.capacity + oldHeap.capacity, + heapUsage: newHeap.used + oldHeap.used, + ); - final List heaps = [ - HeapSpace.parse(event.json['new']), - HeapSpace.parse(event.json['old']) - ]; - _updateGCEvent(event.isolate.id, heaps); + _updateGCEvent(event.isolate.id, memoryUsage); // TODO(terry): expose when GC occured as markers in memory timeline. } // TODO(terry): Discuss need a record/stop record for memory? Unless expensive probably not. Future _pollMemory() async { - if (!hasConnection) { + if (!hasConnection || memoryController.memoryTracker == null) { return; } - final VM vm = await service.getVM(); - // TODO(terry): Need to handle a possible Sentinel being returned. - final List isolates = - await Future.wait(vm.isolates.map((IsolateRef ref) async { - return await service.getIsolate(ref.id); - })); - _update(vm, isolates); + final isolateMemory = {}; + for (IsolateRef isolateRef in serviceManager.isolateManager.isolates) { + isolateMemory[isolateRef] = await service.getMemoryUsage(isolateRef.id); + } + + // Polls for current Android meminfo using: + // > adb shell dumpsys meminfo -d + if (hasConnection && serviceManager.vm.operatingSystem == 'android') { + adbMemoryInfo = await _fetchAdbInfo(); + } else { + // TODO(terry): TBD alternative for iOS memory info - all values zero. + adbMemoryInfo = AdbMemoryInfo.empty(); + } - _pollingTimer = Timer(kUpdateDelay, _pollMemory); + // Polls for current RSS size. + _update(await service.getVM(), isolateMemory); + + _pollingTimer = Timer(_updateDelay, _pollMemory); } - void _update(VM vm, List isolates) { + void _update(VM vm, Map isolateMemory) { processRss = vm.json['_currentRSS']; isolateHeaps.clear(); - for (Isolate isolate in isolates) { - final List heaps = getHeaps(isolate).toList(); - isolateHeaps[isolate.id] = heaps; + for (IsolateRef isolateRef in isolateMemory.keys) { + isolateHeaps[isolateRef.id] = isolateMemory[isolateRef]; } _recalculate(); } - void _updateGCEvent(String id, List heaps) { - isolateHeaps[id] = heaps; + void _updateGCEvent(String isolateId, MemoryUsage memoryUsage) { + isolateHeaps[isolateId] = memoryUsage; _recalculate(true); } - void _recalculate([bool fromGC = false]) { - int total = 0; + // Poll ADB meminfo + Future _fetchAdbInfo() async => + AdbMemoryInfo.fromJson((await serviceManager.getAdbMemoryInfo()).json); + void _recalculate([bool fromGC = false]) async { int used = 0; int capacity = 0; int external = 0; - for (List heaps in isolateHeaps.values) { - used += heaps.fold(0, (int i, HeapSpace heap) => i + heap.used); - capacity += - heaps.fold(0, (int i, HeapSpace heap) => i + heap.capacity); - external += - heaps.fold(0, (int i, HeapSpace heap) => i + heap.external); - - capacity += external; - total += heaps.fold( - 0, (int i, HeapSpace heap) => i + heap.capacity + heap.external); + for (MemoryUsage memoryUsage in isolateHeaps.values) { + used += memoryUsage.heapUsage; + capacity += memoryUsage.heapCapacity; + external += memoryUsage.externalUsage; } - heapMax = total; - int time = DateTime.now().millisecondsSinceEpoch; if (samples.isNotEmpty) { time = math.max(time, samples.last.timestamp); } - _addSample(HeapSample(time, processRss, capacity, used, external, fromGC)); + final HeapSample sample = HeapSample( + time, + processRss, + capacity + external, + used, + external, + fromGC, + adbMemoryInfo, + ); + + _addSample(sample); + memoryController.memoryTimeline.addSample(sample); } void _addSample(HeapSample sample) { @@ -129,12 +168,6 @@ class MemoryTracker { _changeController.add(null); } - - // TODO(devoncarew): fix HeapSpace.parse upstream - static Iterable getHeaps(Isolate isolate) { - final Map heaps = isolate.json['_heaps']; - return heaps.values.map((dynamic json) => HeapSpace.parse(json)); - } } // Heap Statistics diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_screen.dart b/packages/devtools_app/lib/src/memory/memory_screen.dart similarity index 96% rename from packages/devtools_app/lib/src/memory/flutter/memory_screen.dart rename to packages/devtools_app/lib/src/memory/memory_screen.dart index 8602dd2cf27..263d3a14981 100644 --- a/packages/devtools_app/lib/src/memory/flutter/memory_screen.dart +++ b/packages/devtools_app/lib/src/memory/memory_screen.dart @@ -5,15 +5,15 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../../config_specific/logger/logger.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/banner_messages.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/octicons.dart'; -import '../../flutter/screen.dart'; -import '../../flutter/theme.dart'; -import '../../globals.dart'; -import '../../ui/flutter/label.dart'; +import '../auto_dispose_mixin.dart'; +import '../banner_messages.dart'; +import '../common_widgets.dart'; +import '../config_specific/logger/logger.dart'; +import '../globals.dart'; +import '../octicons.dart'; +import '../screen.dart'; +import '../theme.dart'; +import '../ui/label.dart'; import 'memory_chart.dart'; import 'memory_controller.dart'; import 'memory_heap_tree_view.dart'; diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_snapshot_models.dart b/packages/devtools_app/lib/src/memory/memory_snapshot_models.dart similarity index 99% rename from packages/devtools_app/lib/src/memory/flutter/memory_snapshot_models.dart rename to packages/devtools_app/lib/src/memory/memory_snapshot_models.dart index 16cd947beb1..fb169397ca4 100644 --- a/packages/devtools_app/lib/src/memory/flutter/memory_snapshot_models.dart +++ b/packages/devtools_app/lib/src/memory/memory_snapshot_models.dart @@ -5,9 +5,9 @@ import 'package:intl/intl.dart'; import 'package:vm_service/vm_service.dart'; -import '../../trees.dart'; -import '../flutter/memory_controller.dart'; -import '../flutter/memory_graph_model.dart'; +import '../trees.dart'; +import 'memory_controller.dart'; +import 'memory_graph_model.dart'; /// Consolidated list of libraries. External is the external heap /// and Filtered is the sum of all filtered (hidden) libraries. diff --git a/packages/devtools_app/lib/src/memory/flutter/memory_utils.dart b/packages/devtools_app/lib/src/memory/memory_utils.dart similarity index 100% rename from packages/devtools_app/lib/src/memory/flutter/memory_utils.dart rename to packages/devtools_app/lib/src/memory/memory_utils.dart diff --git a/packages/devtools_app/lib/src/flutter/navigation.dart b/packages/devtools_app/lib/src/navigation.dart similarity index 97% rename from packages/devtools_app/lib/src/flutter/navigation.dart rename to packages/devtools_app/lib/src/navigation.dart index fe13584bcaa..9cbaf82f434 100644 --- a/packages/devtools_app/lib/src/flutter/navigation.dart +++ b/packages/devtools_app/lib/src/navigation.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; -import '../ui/theme.dart' as devtools_theme; +import 'ui/theme.dart' as devtools_theme; /// Returns [routeName] with [queryParameters] appended as [Uri] query /// parameters. diff --git a/packages/devtools_app/lib/src/network/flutter/http_request_inspector.dart b/packages/devtools_app/lib/src/network/http_request_inspector.dart similarity index 95% rename from packages/devtools_app/lib/src/network/flutter/http_request_inspector.dart rename to packages/devtools_app/lib/src/network/http_request_inspector.dart index c31aa5b8614..b6106b91bed 100644 --- a/packages/devtools_app/lib/src/network/flutter/http_request_inspector.dart +++ b/packages/devtools_app/lib/src/network/http_request_inspector.dart @@ -4,9 +4,9 @@ import 'package:flutter/material.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/theme.dart'; -import '../../http/http_request_data.dart'; +import '../common_widgets.dart'; +import '../http/http_request_data.dart'; +import '../theme.dart'; import 'http_request_inspector_views.dart'; /// A [Widget] which displays information about an HTTP request. diff --git a/packages/devtools_app/lib/src/network/flutter/http_request_inspector_views.dart b/packages/devtools_app/lib/src/network/http_request_inspector_views.dart similarity index 98% rename from packages/devtools_app/lib/src/network/flutter/http_request_inspector_views.dart rename to packages/devtools_app/lib/src/network/http_request_inspector_views.dart index f8295b93d74..2a74c62e101 100644 --- a/packages/devtools_app/lib/src/network/flutter/http_request_inspector_views.dart +++ b/packages/devtools_app/lib/src/network/http_request_inspector_views.dart @@ -4,11 +4,11 @@ import 'package:flutter/material.dart'; -import '../../flutter/table.dart'; -import '../../flutter/theme.dart'; -import '../../http/http.dart'; -import '../../http/http_request_data.dart'; -import '../../utils.dart'; +import '../http/http.dart'; +import '../http/http_request_data.dart'; +import '../table.dart'; +import '../theme.dart'; +import '../utils.dart'; // Approximately double the indent of the expandable tile's title. const double _rowIndentPadding = 30; diff --git a/packages/devtools_app/lib/src/network/flutter/network_screen.dart b/packages/devtools_app/lib/src/network/network_screen.dart similarity index 96% rename from packages/devtools_app/lib/src/network/flutter/network_screen.dart rename to packages/devtools_app/lib/src/network/network_screen.dart index 135e002b727..4d85e3592e7 100644 --- a/packages/devtools_app/lib/src/network/flutter/network_screen.dart +++ b/packages/devtools_app/lib/src/network/network_screen.dart @@ -7,17 +7,17 @@ import 'package:flutter/rendering.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/screen.dart'; -import '../../flutter/split.dart'; -import '../../flutter/table.dart'; -import '../../flutter/theme.dart'; -import '../../globals.dart'; -import '../../http/http_request_data.dart'; -import '../../table_data.dart'; -import '../../utils.dart'; -import '../network_controller.dart'; +import '../common_widgets.dart'; +import '../globals.dart'; +import '../http/http_request_data.dart'; +import '../screen.dart'; +import '../split.dart'; +import '../table.dart'; +import '../table_data.dart'; +import '../theme.dart'; +import '../utils.dart'; import 'http_request_inspector.dart'; +import 'network_controller.dart'; class NetworkScreen extends Screen { const NetworkScreen() diff --git a/packages/devtools_app/lib/src/flutter/notifications.dart b/packages/devtools_app/lib/src/notifications.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/notifications.dart rename to packages/devtools_app/lib/src/notifications.dart diff --git a/packages/devtools_app/lib/src/flutter/octicons.dart b/packages/devtools_app/lib/src/octicons.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/octicons.dart rename to packages/devtools_app/lib/src/octicons.dart diff --git a/packages/devtools_app/lib/src/performance/performance_controller.dart b/packages/devtools_app/lib/src/performance/performance_controller.dart index 775cc10fd51..f86a8a10553 100644 --- a/packages/devtools_app/lib/src/performance/performance_controller.dart +++ b/packages/devtools_app/lib/src/performance/performance_controller.dart @@ -6,11 +6,11 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; -import '../config_specific/flutter/import_export/import_export.dart'; +import '../config_specific/import_export/import_export.dart'; import '../profiler/cpu_profile_controller.dart'; import '../profiler/cpu_profile_model.dart'; import '../utils.dart'; -import 'flutter/performance_screen.dart'; +import 'performance_screen.dart'; class PerformanceController with CpuProfilerControllerProviderMixin { final _exportController = ExportController(); diff --git a/packages/devtools_app/lib/src/performance/flutter/performance_screen.dart b/packages/devtools_app/lib/src/performance/performance_screen.dart similarity index 92% rename from packages/devtools_app/lib/src/performance/flutter/performance_screen.dart rename to packages/devtools_app/lib/src/performance/performance_screen.dart index 0297e74d8ea..a361e87f3e1 100644 --- a/packages/devtools_app/lib/src/performance/flutter/performance_screen.dart +++ b/packages/devtools_app/lib/src/performance/performance_screen.dart @@ -8,20 +8,20 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:vm_service/vm_service.dart' hide Stack; -import '../../config_specific/flutter/import_export/import_export.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/banner_messages.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/notifications.dart'; -import '../../flutter/octicons.dart'; -import '../../flutter/screen.dart'; -import '../../flutter/theme.dart'; -import '../../globals.dart'; -import '../../profiler/cpu_profile_controller.dart'; -import '../../profiler/cpu_profile_model.dart'; -import '../../profiler/flutter/cpu_profiler.dart'; -import '../../ui/flutter/vm_flag_widgets.dart'; -import '../performance_controller.dart'; +import '../auto_dispose_mixin.dart'; +import '../banner_messages.dart'; +import '../common_widgets.dart'; +import '../config_specific/import_export/import_export.dart'; +import '../globals.dart'; +import '../notifications.dart'; +import '../octicons.dart'; +import '../profiler/cpu_profile_controller.dart'; +import '../profiler/cpu_profile_model.dart'; +import '../profiler/cpu_profiler.dart'; +import '../screen.dart'; +import '../theme.dart'; +import '../ui/vm_flag_widgets.dart'; +import 'performance_controller.dart'; class PerformanceScreen extends Screen { const PerformanceScreen() diff --git a/packages/devtools_app/lib/src/flutter/preferences.dart b/packages/devtools_app/lib/src/preferences.dart similarity index 91% rename from packages/devtools_app/lib/src/flutter/preferences.dart rename to packages/devtools_app/lib/src/preferences.dart index 35b1859e405..fd6d9aeefbb 100644 --- a/packages/devtools_app/lib/src/flutter/preferences.dart +++ b/packages/devtools_app/lib/src/preferences.dart @@ -4,9 +4,9 @@ import 'package:flutter/foundation.dart'; -import '../config_specific/logger/logger.dart'; -import '../globals.dart'; -import '../ui/theme.dart' as devtools_theme; +import 'config_specific/logger/logger.dart'; +import 'globals.dart'; +import 'ui/theme.dart' as devtools_theme; /// A controller for global application preferences. class PreferencesController { diff --git a/packages/devtools_app/lib/src/profiler/flutter/cpu_profile_bottom_up.dart b/packages/devtools_app/lib/src/profiler/cpu_profile_bottom_up.dart similarity index 88% rename from packages/devtools_app/lib/src/profiler/flutter/cpu_profile_bottom_up.dart rename to packages/devtools_app/lib/src/profiler/cpu_profile_bottom_up.dart index 5c3dc620e2e..164b2e6980b 100644 --- a/packages/devtools_app/lib/src/profiler/flutter/cpu_profile_bottom_up.dart +++ b/packages/devtools_app/lib/src/profiler/cpu_profile_bottom_up.dart @@ -4,11 +4,11 @@ import 'package:flutter/material.dart'; -import '../../flutter/table.dart'; -import '../../profiler/cpu_profile_columns.dart'; -import '../../profiler/cpu_profile_model.dart'; -import '../../table_data.dart'; -import '../../utils.dart'; +import '../table.dart'; +import '../table_data.dart'; +import '../utils.dart'; +import 'cpu_profile_columns.dart'; +import 'cpu_profile_model.dart'; /// A table of the CPU's bottom-up call tree. class CpuBottomUpTable extends StatelessWidget { diff --git a/packages/devtools_app/lib/src/profiler/flutter/cpu_profile_call_tree.dart b/packages/devtools_app/lib/src/profiler/cpu_profile_call_tree.dart similarity index 87% rename from packages/devtools_app/lib/src/profiler/flutter/cpu_profile_call_tree.dart rename to packages/devtools_app/lib/src/profiler/cpu_profile_call_tree.dart index f3159a1bb95..6fc685aa6c3 100644 --- a/packages/devtools_app/lib/src/profiler/flutter/cpu_profile_call_tree.dart +++ b/packages/devtools_app/lib/src/profiler/cpu_profile_call_tree.dart @@ -4,11 +4,11 @@ import 'package:flutter/material.dart'; -import '../../flutter/table.dart'; -import '../../profiler/cpu_profile_columns.dart'; -import '../../profiler/cpu_profile_model.dart'; -import '../../table_data.dart'; -import '../../utils.dart'; +import '../table.dart'; +import '../table_data.dart'; +import '../utils.dart'; +import 'cpu_profile_columns.dart'; +import 'cpu_profile_model.dart'; /// A table of the CPU's top-down call tree. class CpuCallTreeTable extends StatelessWidget { diff --git a/packages/devtools_app/lib/src/profiler/flutter/cpu_profile_flame_chart.dart b/packages/devtools_app/lib/src/profiler/cpu_profile_flame_chart.dart similarity index 96% rename from packages/devtools_app/lib/src/profiler/flutter/cpu_profile_flame_chart.dart rename to packages/devtools_app/lib/src/profiler/cpu_profile_flame_chart.dart index 0c480504d71..b214aa6b10c 100644 --- a/packages/devtools_app/lib/src/profiler/flutter/cpu_profile_flame_chart.dart +++ b/packages/devtools_app/lib/src/profiler/cpu_profile_flame_chart.dart @@ -3,10 +3,10 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import '../../charts/flutter/flame_chart.dart'; -import '../../ui/colors.dart'; -import '../../utils.dart'; -import '../cpu_profile_model.dart'; +import '../charts/flame_chart.dart'; +import '../ui/colors.dart'; +import '../utils.dart'; +import 'cpu_profile_model.dart'; class CpuProfileFlameChart extends FlameChart { CpuProfileFlameChart( diff --git a/packages/devtools_app/lib/src/profiler/flutter/cpu_profiler.dart b/packages/devtools_app/lib/src/profiler/cpu_profiler.dart similarity index 97% rename from packages/devtools_app/lib/src/profiler/flutter/cpu_profiler.dart rename to packages/devtools_app/lib/src/profiler/cpu_profiler.dart index aeab468f26c..23951f8ad1a 100644 --- a/packages/devtools_app/lib/src/profiler/flutter/cpu_profiler.dart +++ b/packages/devtools_app/lib/src/profiler/cpu_profiler.dart @@ -3,13 +3,13 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import '../../flutter/theme.dart'; -import '../cpu_profile_controller.dart'; -import '../cpu_profile_model.dart'; -import '../cpu_profile_transformer.dart'; +import '../theme.dart'; import 'cpu_profile_bottom_up.dart'; import 'cpu_profile_call_tree.dart'; +import 'cpu_profile_controller.dart'; import 'cpu_profile_flame_chart.dart'; +import 'cpu_profile_model.dart'; +import 'cpu_profile_transformer.dart'; // TODO(kenz): provide useful UI upon selecting a CPU stack frame. diff --git a/packages/devtools_app/lib/src/flutter/scaffold.dart b/packages/devtools_app/lib/src/scaffold.dart similarity index 98% rename from packages/devtools_app/lib/src/flutter/scaffold.dart rename to packages/devtools_app/lib/src/scaffold.dart index 2cc12560246..9bd4b39d27e 100644 --- a/packages/devtools_app/lib/src/flutter/scaffold.dart +++ b/packages/devtools_app/lib/src/scaffold.dart @@ -9,13 +9,13 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../config_specific/flutter/drag_and_drop/drag_and_drop.dart'; -import '../config_specific/flutter/import_export/import_export.dart'; -import '../framework_controller.dart'; -import '../globals.dart'; import 'app.dart'; import 'banner_messages.dart'; import 'common_widgets.dart'; +import 'config_specific/drag_and_drop/drag_and_drop.dart'; +import 'config_specific/import_export/import_export.dart'; +import 'framework_controller.dart'; +import 'globals.dart'; import 'navigation.dart'; import 'notifications.dart'; import 'screen.dart'; diff --git a/packages/devtools_app/lib/src/flutter/screen.dart b/packages/devtools_app/lib/src/screen.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/screen.dart rename to packages/devtools_app/lib/src/screen.dart diff --git a/packages/devtools_app/lib/src/flutter/snapshot_screen.dart b/packages/devtools_app/lib/src/snapshot_screen.dart similarity index 99% rename from packages/devtools_app/lib/src/flutter/snapshot_screen.dart rename to packages/devtools_app/lib/src/snapshot_screen.dart index 9b342e2b3c5..524204130af 100644 --- a/packages/devtools_app/lib/src/flutter/snapshot_screen.dart +++ b/packages/devtools_app/lib/src/snapshot_screen.dart @@ -3,8 +3,8 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import '../globals.dart'; import 'common_widgets.dart'; +import 'globals.dart'; import 'screen.dart'; /// The screen in the app responsible for connecting to the Dart VM. diff --git a/packages/devtools_app/lib/src/flutter/split.dart b/packages/devtools_app/lib/src/split.dart similarity index 99% rename from packages/devtools_app/lib/src/flutter/split.dart rename to packages/devtools_app/lib/src/split.dart index a337175d594..fd43d844a6c 100644 --- a/packages/devtools_app/lib/src/flutter/split.dart +++ b/packages/devtools_app/lib/src/split.dart @@ -8,7 +8,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import '../utils.dart'; +import 'utils.dart'; /// A widget that takes a list of children, lays them out along [axis], and /// allows the user to resize them. diff --git a/packages/devtools_app/lib/src/flutter/status_line.dart b/packages/devtools_app/lib/src/status_line.dart similarity index 97% rename from packages/devtools_app/lib/src/flutter/status_line.dart rename to packages/devtools_app/lib/src/status_line.dart index e3a32b826b2..0fe7a090b32 100644 --- a/packages/devtools_app/lib/src/flutter/status_line.dart +++ b/packages/devtools_app/lib/src/status_line.dart @@ -9,14 +9,13 @@ import 'package:pedantic/pedantic.dart'; import 'package:provider/provider.dart'; import 'package:vm_service/vm_service.dart'; -import '../../devtools.dart' as devtools; -import '../globals.dart'; -import '../info/info_controller.dart'; -import '../service_manager.dart'; -import '../utils.dart'; +import '../devtools.dart' as devtools; import 'common_widgets.dart'; import 'device_dialog.dart'; +import 'globals.dart'; +import 'info/info_controller.dart'; import 'screen.dart'; +import 'service_manager.dart'; import 'theme.dart'; import 'utils.dart'; diff --git a/packages/devtools_app/lib/src/flutter/syntax_highlighting.dart b/packages/devtools_app/lib/src/syntax_highlighting.dart similarity index 100% rename from packages/devtools_app/lib/src/flutter/syntax_highlighting.dart rename to packages/devtools_app/lib/src/syntax_highlighting.dart diff --git a/packages/devtools_app/lib/src/flutter/table.dart b/packages/devtools_app/lib/src/table.dart similarity index 99% rename from packages/devtools_app/lib/src/flutter/table.dart rename to packages/devtools_app/lib/src/table.dart index 58d00c1663d..da78179b3f2 100644 --- a/packages/devtools_app/lib/src/flutter/table.dart +++ b/packages/devtools_app/lib/src/table.dart @@ -3,16 +3,16 @@ import 'dart:math'; import 'package:flutter/material.dart' hide TableRow; import 'package:flutter/services.dart'; -import '../flutter/common_widgets.dart'; -import '../table_data.dart'; -import '../trees.dart'; -import '../utils.dart'; import 'auto_dispose_mixin.dart'; import 'collapsible_mixin.dart'; +import 'common_widgets.dart'; import 'common_widgets.dart' show ColorExtension, ScrollControllerAutoScroll; import 'flutter_widgets/linked_scroll_controller.dart'; +import 'table_data.dart'; import 'theme.dart'; import 'tree.dart'; +import 'trees.dart'; +import 'utils.dart'; // TODO(devoncarew): We need to render the selected row with a different // background color. diff --git a/packages/devtools_app/lib/src/flutter/theme.dart b/packages/devtools_app/lib/src/theme.dart similarity index 98% rename from packages/devtools_app/lib/src/flutter/theme.dart rename to packages/devtools_app/lib/src/theme.dart index 9922f9ff165..4ec0d66b8d0 100644 --- a/packages/devtools_app/lib/src/flutter/theme.dart +++ b/packages/devtools_app/lib/src/theme.dart @@ -5,8 +5,8 @@ import 'package:flutter/material.dart'; import 'package:mp_chart/mp/core/adapter_android_mp.dart'; -import '../flutter/common_widgets.dart'; -import '../ui/theme.dart'; +import 'common_widgets.dart'; +import 'ui/theme.dart'; /// Constructs the light or dark theme for the app. ThemeData themeFor({@required bool isDarkTheme}) { diff --git a/packages/devtools_app/lib/src/timeline/flutter/event_details.dart b/packages/devtools_app/lib/src/timeline/event_details.dart similarity index 95% rename from packages/devtools_app/lib/src/timeline/flutter/event_details.dart rename to packages/devtools_app/lib/src/timeline/event_details.dart index eb371387400..512ce6441d2 100644 --- a/packages/devtools_app/lib/src/timeline/flutter/event_details.dart +++ b/packages/devtools_app/lib/src/timeline/event_details.dart @@ -8,13 +8,13 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:vm_service/vm_service.dart' hide TimelineEvent; -import '../../flutter/common_widgets.dart'; -import '../../globals.dart'; -import '../../profiler/cpu_profile_controller.dart'; -import '../../profiler/cpu_profile_model.dart'; -import '../../profiler/flutter/cpu_profiler.dart'; -import '../../trace_event.dart'; -import '../../utils.dart'; +import '../common_widgets.dart'; +import '../globals.dart'; +import '../profiler/cpu_profile_controller.dart'; +import '../profiler/cpu_profile_model.dart'; +import '../profiler/cpu_profiler.dart'; +import '../trace_event.dart'; +import '../utils.dart'; import 'timeline_controller.dart'; import 'timeline_model.dart'; diff --git a/packages/devtools_app/lib/src/timeline/flutter/flutter_frames_chart.dart b/packages/devtools_app/lib/src/timeline/flutter_frames_chart.dart similarity index 98% rename from packages/devtools_app/lib/src/timeline/flutter/flutter_frames_chart.dart rename to packages/devtools_app/lib/src/timeline/flutter_frames_chart.dart index 270f8ac74eb..07c604357c9 100644 --- a/packages/devtools_app/lib/src/timeline/flutter/flutter_frames_chart.dart +++ b/packages/devtools_app/lib/src/timeline/flutter_frames_chart.dart @@ -5,11 +5,11 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/theme.dart'; -import '../../ui/colors.dart'; -import '../../utils.dart'; +import '../auto_dispose_mixin.dart'; +import '../common_widgets.dart'; +import '../theme.dart'; +import '../ui/colors.dart'; +import '../utils.dart'; import 'timeline_controller.dart'; import 'timeline_model.dart'; diff --git a/packages/devtools_app/lib/src/timeline/flutter/timeline_controller.dart b/packages/devtools_app/lib/src/timeline/timeline_controller.dart similarity index 96% rename from packages/devtools_app/lib/src/timeline/flutter/timeline_controller.dart rename to packages/devtools_app/lib/src/timeline/timeline_controller.dart index 83695a9b918..5af97bc5408 100644 --- a/packages/devtools_app/lib/src/timeline/flutter/timeline_controller.dart +++ b/packages/devtools_app/lib/src/timeline/timeline_controller.dart @@ -7,18 +7,18 @@ import 'package:flutter/foundation.dart'; import 'package:pedantic/pedantic.dart'; import 'package:vm_service/vm_service.dart' as vm_service; -import '../../auto_dispose.dart'; -import '../../config_specific/flutter/import_export/import_export.dart'; -import '../../config_specific/logger/allowed_error.dart'; -import '../../config_specific/logger/logger.dart'; -import '../../globals.dart'; -import '../../http/http_service.dart'; -import '../../profiler/cpu_profile_controller.dart'; -import '../../profiler/cpu_profile_service.dart'; -import '../../profiler/cpu_profile_transformer.dart'; -import '../../profiler/profile_granularity.dart'; -import '../../service_manager.dart'; -import '../../trace_event.dart'; +import '../auto_dispose.dart'; +import '../config_specific/import_export/import_export.dart'; +import '../config_specific/logger/allowed_error.dart'; +import '../config_specific/logger/logger.dart'; +import '../globals.dart'; +import '../http/http_service.dart'; +import '../profiler/cpu_profile_controller.dart'; +import '../profiler/cpu_profile_service.dart'; +import '../profiler/cpu_profile_transformer.dart'; +import '../profiler/profile_granularity.dart'; +import '../service_manager.dart'; +import '../trace_event.dart'; import 'timeline_model.dart'; import 'timeline_processor.dart'; import 'timeline_screen.dart'; diff --git a/packages/devtools_app/lib/src/timeline/flutter/timeline_flame_chart.dart b/packages/devtools_app/lib/src/timeline/timeline_flame_chart.dart similarity index 99% rename from packages/devtools_app/lib/src/timeline/flutter/timeline_flame_chart.dart rename to packages/devtools_app/lib/src/timeline/timeline_flame_chart.dart index 40cd9ae3bea..de2b1554db7 100644 --- a/packages/devtools_app/lib/src/timeline/flutter/timeline_flame_chart.dart +++ b/packages/devtools_app/lib/src/timeline/timeline_flame_chart.dart @@ -9,12 +9,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../../charts/flutter/flame_chart.dart'; -import '../../flutter/theme.dart'; -import '../../geometry.dart'; -import '../../ui/colors.dart'; -import '../../ui/theme.dart'; -import '../../utils.dart'; +import '../charts/flame_chart.dart'; +import '../geometry.dart'; +import '../theme.dart'; +import '../ui/colors.dart'; +import '../ui/theme.dart'; +import '../utils.dart'; import 'timeline_controller.dart'; import 'timeline_model.dart'; diff --git a/packages/devtools_app/lib/src/timeline/flutter/timeline_model.dart b/packages/devtools_app/lib/src/timeline/timeline_model.dart similarity index 99% rename from packages/devtools_app/lib/src/timeline/flutter/timeline_model.dart rename to packages/devtools_app/lib/src/timeline/timeline_model.dart index 5cc1b1bb940..54b77faa32f 100644 --- a/packages/devtools_app/lib/src/timeline/flutter/timeline_model.dart +++ b/packages/devtools_app/lib/src/timeline/timeline_model.dart @@ -6,11 +6,11 @@ import 'dart:math' as math; import 'package:meta/meta.dart'; -import '../../profiler/cpu_profile_model.dart'; -import '../../service_manager.dart'; -import '../../trace_event.dart'; -import '../../trees.dart'; -import '../../utils.dart'; +import '../profiler/cpu_profile_model.dart'; +import '../service_manager.dart'; +import '../trace_event.dart'; +import '../trees.dart'; +import '../utils.dart'; class TimelineData { TimelineData({ diff --git a/packages/devtools_app/lib/src/timeline/flutter/timeline_processor.dart b/packages/devtools_app/lib/src/timeline/timeline_processor.dart similarity index 99% rename from packages/devtools_app/lib/src/timeline/flutter/timeline_processor.dart rename to packages/devtools_app/lib/src/timeline/timeline_processor.dart index f4e7f0bda43..728db9dbb7a 100644 --- a/packages/devtools_app/lib/src/timeline/flutter/timeline_processor.dart +++ b/packages/devtools_app/lib/src/timeline/timeline_processor.dart @@ -7,9 +7,9 @@ import 'dart:math' as math; import 'package:flutter/foundation.dart'; import 'package:meta/meta.dart'; -import '../../config_specific/logger/logger.dart'; -import '../../trace_event.dart'; -import '../../utils.dart'; +import '../config_specific/logger/logger.dart'; +import '../trace_event.dart'; +import '../utils.dart'; //import '../simple_trace_example.dart'; import 'timeline_controller.dart'; import 'timeline_model.dart'; diff --git a/packages/devtools_app/lib/src/timeline/flutter/timeline_screen.dart b/packages/devtools_app/lib/src/timeline/timeline_screen.dart similarity index 95% rename from packages/devtools_app/lib/src/timeline/flutter/timeline_screen.dart rename to packages/devtools_app/lib/src/timeline/timeline_screen.dart index 5ceb331d952..f91cd475575 100644 --- a/packages/devtools_app/lib/src/timeline/flutter/timeline_screen.dart +++ b/packages/devtools_app/lib/src/timeline/timeline_screen.dart @@ -8,19 +8,19 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../../config_specific/flutter/import_export/import_export.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/banner_messages.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/notifications.dart'; -import '../../flutter/octicons.dart'; -import '../../flutter/screen.dart'; -import '../../flutter/split.dart'; -import '../../flutter/theme.dart'; -import '../../globals.dart'; -import '../../service_extensions.dart'; -import '../../ui/flutter/service_extension_widgets.dart'; -import '../../ui/flutter/vm_flag_widgets.dart'; +import '../auto_dispose_mixin.dart'; +import '../banner_messages.dart'; +import '../common_widgets.dart'; +import '../config_specific/import_export/import_export.dart'; +import '../globals.dart'; +import '../notifications.dart'; +import '../octicons.dart'; +import '../screen.dart'; +import '../service_extensions.dart'; +import '../split.dart'; +import '../theme.dart'; +import '../ui/service_extension_widgets.dart'; +import '../ui/vm_flag_widgets.dart'; import 'event_details.dart'; import 'flutter_frames_chart.dart'; import 'timeline_controller.dart'; diff --git a/packages/devtools_app/lib/src/timeline/flutter/timeline_streams.dart b/packages/devtools_app/lib/src/timeline/timeline_streams.dart similarity index 100% rename from packages/devtools_app/lib/src/timeline/flutter/timeline_streams.dart rename to packages/devtools_app/lib/src/timeline/timeline_streams.dart diff --git a/packages/devtools_app/lib/src/flutter/tree.dart b/packages/devtools_app/lib/src/tree.dart similarity index 99% rename from packages/devtools_app/lib/src/flutter/tree.dart rename to packages/devtools_app/lib/src/tree.dart index 406afc7ab3f..ee481079fbd 100644 --- a/packages/devtools_app/lib/src/flutter/tree.dart +++ b/packages/devtools_app/lib/src/tree.dart @@ -4,9 +4,9 @@ import 'package:flutter/material.dart' hide Stack; -import '../trees.dart'; import 'collapsible_mixin.dart'; import 'theme.dart'; +import 'trees.dart'; class TreeView> extends StatefulWidget { const TreeView({ diff --git a/packages/devtools_app/lib/src/ui/flutter/dialog.dart b/packages/devtools_app/lib/src/ui/dialog.dart similarity index 100% rename from packages/devtools_app/lib/src/ui/flutter/dialog.dart rename to packages/devtools_app/lib/src/ui/dialog.dart diff --git a/packages/devtools_app/lib/src/ui/icons.dart b/packages/devtools_app/lib/src/ui/icons.dart index ce5f7196038..f46241f8059 100644 --- a/packages/devtools_app/lib/src/ui/icons.dart +++ b/packages/devtools_app/lib/src/ui/icons.dart @@ -16,7 +16,7 @@ library icons; import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; -import '../flutter/theme.dart'; +import '../theme.dart'; import 'theme.dart'; class CustomIcon extends StatelessWidget { diff --git a/packages/devtools_app/lib/src/ui/flutter/label.dart b/packages/devtools_app/lib/src/ui/label.dart similarity index 100% rename from packages/devtools_app/lib/src/ui/flutter/label.dart rename to packages/devtools_app/lib/src/ui/label.dart diff --git a/packages/devtools_app/lib/src/ui/flutter/service_extension_widgets.dart b/packages/devtools_app/lib/src/ui/service_extension_widgets.dart similarity index 97% rename from packages/devtools_app/lib/src/ui/flutter/service_extension_widgets.dart rename to packages/devtools_app/lib/src/ui/service_extension_widgets.dart index f89a48b9275..ca85d728ab5 100644 --- a/packages/devtools_app/lib/src/ui/flutter/service_extension_widgets.dart +++ b/packages/devtools_app/lib/src/ui/service_extension_widgets.dart @@ -7,17 +7,17 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../../config_specific/logger/logger.dart'; -import '../../core/message_bus.dart'; -import '../../flutter/auto_dispose_mixin.dart'; -import '../../flutter/common_widgets.dart'; -import '../../flutter/notifications.dart'; -import '../../flutter/scaffold.dart'; -import '../../flutter/theme.dart'; -import '../../globals.dart'; -import '../../service_extensions.dart'; -import '../../service_registrations.dart'; -import '../../utils.dart'; +import '../auto_dispose_mixin.dart'; +import '../common_widgets.dart'; +import '../config_specific/logger/logger.dart'; +import '../core/message_bus.dart'; +import '../globals.dart'; +import '../notifications.dart'; +import '../scaffold.dart'; +import '../service_extensions.dart'; +import '../service_registrations.dart'; +import '../theme.dart'; +import '../utils.dart'; import 'label.dart'; /// Group of buttons where each button toggles the state of a VMService diff --git a/packages/devtools_app/lib/src/ui/flutter/utils.dart b/packages/devtools_app/lib/src/ui/utils.dart similarity index 100% rename from packages/devtools_app/lib/src/ui/flutter/utils.dart rename to packages/devtools_app/lib/src/ui/utils.dart diff --git a/packages/devtools_app/lib/src/ui/flutter/vm_flag_widgets.dart b/packages/devtools_app/lib/src/ui/vm_flag_widgets.dart similarity index 95% rename from packages/devtools_app/lib/src/ui/flutter/vm_flag_widgets.dart rename to packages/devtools_app/lib/src/ui/vm_flag_widgets.dart index da50cdd5a6c..a30f5228f27 100644 --- a/packages/devtools_app/lib/src/ui/flutter/vm_flag_widgets.dart +++ b/packages/devtools_app/lib/src/ui/vm_flag_widgets.dart @@ -6,9 +6,9 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:vm_service/vm_service.dart'; -import '../../flutter/banner_messages.dart'; -import '../../profiler/cpu_profile_service.dart'; -import '../../profiler/profile_granularity.dart'; +import '../banner_messages.dart'; +import '../profiler/cpu_profile_service.dart'; +import '../profiler/profile_granularity.dart'; /// DropdownButton that controls the value of the 'profile_period' vm flag. /// diff --git a/packages/devtools_app/lib/src/utils.dart b/packages/devtools_app/lib/src/utils.dart index 65f864ddd0e..5b268bfeeda 100644 --- a/packages/devtools_app/lib/src/utils.dart +++ b/packages/devtools_app/lib/src/utils.dart @@ -6,12 +6,19 @@ import 'dart:async'; import 'dart:convert'; import 'dart:math'; +import 'package:ansi_up/ansi_up.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; import 'package:vm_service/vm_service.dart'; +import 'package:url_launcher/url_launcher.dart' as url_launcher; + +import 'notifications.dart'; + bool collectionEquals(e1, e2) => const DeepCollectionEquality().equals(e1, e2); const String loremIpsum = ''' @@ -685,3 +692,103 @@ class DebugTimingLogger { print('[$name] $message'); } } + +Future launchUrl(String url, BuildContext context) async { + if (await url_launcher.canLaunch(url)) { + await url_launcher.launch(url); + } else { + Notifications.of(context).push('Unable to open $url.'); + } +} + +/// Attempts to copy a String of `data` to the clipboard. +/// +/// Shows a `successMessage` [Notification] on the passed in `context`. +Future copyToClipboard( + String data, + String successMessage, + BuildContext context, +) async { + await Clipboard.setData(ClipboardData( + text: data, + )); + + if (successMessage != null) { + Notifications.of(context)?.push(successMessage); + } +} + +List processAnsiTerminalCodes(String input, TextStyle defaultStyle) { + if (input == null) { + return []; + } + return decodeAnsiColorEscapeCodes(input, AnsiUp()) + .map( + (entry) => TextSpan( + text: entry.text, + style: entry.style.isEmpty + ? defaultStyle + : TextStyle( + color: entry.fgColor != null + ? colorFromAnsi(entry.fgColor) + : null, + backgroundColor: entry.bgColor != null + ? colorFromAnsi(entry.bgColor) + : null, + fontWeight: entry.bold ? FontWeight.bold : FontWeight.normal, + ), + ), + ) + .toList(); +} + +Color colorFromAnsi(List ansiInput) { + assert(ansiInput.length == 3, 'Ansi color list should contain 3 elements'); + return Color.fromRGBO(ansiInput[0], ansiInput[1], ansiInput[2], 1); +} + +/// An extension on [LogicalKeySet] to provide user-facing names for key +/// bindings. +extension LogicalKeySetExtension on LogicalKeySet { + static final Set _modifiers = { + LogicalKeyboardKey.alt, + LogicalKeyboardKey.control, + LogicalKeyboardKey.meta, + LogicalKeyboardKey.shift, + }; + + static final Map _modifierNames = { + LogicalKeyboardKey.alt: 'Alt', + LogicalKeyboardKey.control: 'Control', + LogicalKeyboardKey.meta: 'Meta', + LogicalKeyboardKey.shift: 'Shift', + }; + + /// Return a user-facing name for the [LogicalKeySet]. + String describeKeys({bool isMacOS = false}) { + // Put the modifiers first. If it has a synonym, then it's something like + // shiftLeft, altRight, etc. + final List sortedKeys = keys.toList() + ..sort((a, b) { + final aIsModifier = a.synonyms.isNotEmpty || _modifiers.contains(a); + final bIsModifier = b.synonyms.isNotEmpty || _modifiers.contains(b); + if (aIsModifier && !bIsModifier) { + return -1; + } else if (bIsModifier && !aIsModifier) { + return 1; + } + return a.keyLabel.compareTo(b.keyLabel); + }); + + return sortedKeys.map((key) { + if (_modifiers.contains(key)) { + if (isMacOS && key == LogicalKeyboardKey.meta) { + return '⌘'; + } + return '${_modifierNames[key]}-'; + } else { + return key.keyLabel.toUpperCase(); + } + }).join(); + } +} diff --git a/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift index 4618f386864..8236f5728c6 100644 --- a/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,10 +5,8 @@ import FlutterMacOS import Foundation -import path_provider_macos import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/packages/devtools_app/test/flutter/about_dialog_test.dart b/packages/devtools_app/test/about_dialog_test.dart similarity index 91% rename from packages/devtools_app/test/flutter/about_dialog_test.dart rename to packages/devtools_app/test/about_dialog_test.dart index eecb218b7dc..903a16794fc 100644 --- a/packages/devtools_app/test/flutter/about_dialog_test.dart +++ b/packages/devtools_app/test/about_dialog_test.dart @@ -3,11 +3,11 @@ // found in the LICENSE file. import 'package:devtools_app/devtools.dart' as devtools; -import 'package:devtools_app/src/flutter/app.dart'; +import 'package:devtools_app/src/app.dart'; import 'package:flutter_test/flutter_test.dart'; -import '../support/utils.dart'; -import 'wrappers.dart'; +import 'support/utils.dart'; +import 'support/wrappers.dart'; void main() { DevToolsAboutDialog aboutDialog; diff --git a/packages/devtools_app/test/flutter/auto_dispose_mixin_test.dart b/packages/devtools_app/test/auto_dispose_mixin_test.dart similarity index 98% rename from packages/devtools_app/test/flutter/auto_dispose_mixin_test.dart rename to packages/devtools_app/test/auto_dispose_mixin_test.dart index ad13d8427dd..5e6c6b6c22c 100644 --- a/packages/devtools_app/test/flutter/auto_dispose_mixin_test.dart +++ b/packages/devtools_app/test/auto_dispose_mixin_test.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'package:devtools_app/src/auto_dispose.dart'; -import 'package:devtools_app/src/flutter/auto_dispose_mixin.dart'; +import 'package:devtools_app/src/auto_dispose_mixin.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/devtools_app/test/flutter/banner_messages_test.dart b/packages/devtools_app/test/banner_messages_test.dart similarity index 95% rename from packages/devtools_app/test/flutter/banner_messages_test.dart rename to packages/devtools_app/test/banner_messages_test.dart index b53d845c000..5a768c810d2 100644 --- a/packages/devtools_app/test/flutter/banner_messages_test.dart +++ b/packages/devtools_app/test/banner_messages_test.dart @@ -2,19 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/banner_messages.dart'; -import 'package:devtools_app/src/flutter/common_widgets.dart'; -import 'package:devtools_app/src/flutter/scaffold.dart'; +import 'package:devtools_app/src/banner_messages.dart'; +import 'package:devtools_app/src/common_widgets.dart'; +import 'package:devtools_app/src/scaffold.dart'; import 'package:devtools_app/src/globals.dart'; -import 'package:devtools_app/src/performance/flutter/performance_screen.dart'; +import 'package:devtools_app/src/performance/performance_screen.dart'; import 'package:devtools_app/src/service_manager.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:provider/provider.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { BannerMessagesController controller; diff --git a/packages/devtools_app/test/flutter/common_widgets_test.dart b/packages/devtools_app/test/common_widgets_test.dart similarity index 97% rename from packages/devtools_app/test/flutter/common_widgets_test.dart rename to packages/devtools_app/test/common_widgets_test.dart index dcf9f39879f..8cddd3b8532 100644 --- a/packages/devtools_app/test/flutter/common_widgets_test.dart +++ b/packages/devtools_app/test/common_widgets_test.dart @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/common_widgets.dart'; +import 'package:devtools_app/src/common_widgets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'wrappers.dart'; +import 'support/wrappers.dart'; // TODO(kenz): add tests for other widgets in common_widgets.dart diff --git a/packages/devtools_app/test/flutter/connect_screen_test.dart b/packages/devtools_app/test/connect_screen_test.dart similarity index 86% rename from packages/devtools_app/test/flutter/connect_screen_test.dart rename to packages/devtools_app/test/connect_screen_test.dart index f4e13db529d..a0e0de82f74 100644 --- a/packages/devtools_app/test/flutter/connect_screen_test.dart +++ b/packages/devtools_app/test/connect_screen_test.dart @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/connect_screen.dart'; +import 'package:devtools_app/src/connect_screen.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'wrappers.dart'; +import 'support/wrappers.dart'; void main() { testWidgets('Connect screen displays without error', diff --git a/packages/devtools_app/test/flutter/cpu_profiler_test.dart b/packages/devtools_app/test/cpu_profiler_test.dart similarity index 94% rename from packages/devtools_app/test/flutter/cpu_profiler_test.dart rename to packages/devtools_app/test/cpu_profiler_test.dart index 96447d1bb2b..c10ed6cbcba 100644 --- a/packages/devtools_app/test/flutter/cpu_profiler_test.dart +++ b/packages/devtools_app/test/cpu_profiler_test.dart @@ -4,16 +4,16 @@ import 'package:devtools_app/src/profiler/cpu_profile_model.dart'; import 'package:devtools_app/src/profiler/cpu_profile_transformer.dart'; -import 'package:devtools_app/src/profiler/flutter/cpu_profile_bottom_up.dart'; +import 'package:devtools_app/src/profiler/cpu_profile_bottom_up.dart'; import 'package:devtools_app/src/profiler/cpu_profile_controller.dart'; -import 'package:devtools_app/src/profiler/flutter/cpu_profile_call_tree.dart'; -import 'package:devtools_app/src/profiler/flutter/cpu_profile_flame_chart.dart'; -import 'package:devtools_app/src/profiler/flutter/cpu_profiler.dart'; +import 'package:devtools_app/src/profiler/cpu_profile_call_tree.dart'; +import 'package:devtools_app/src/profiler/cpu_profile_flame_chart.dart'; +import 'package:devtools_app/src/profiler/cpu_profiler.dart'; import 'package:devtools_testing/support/cpu_profile_test_data.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'wrappers.dart'; +import 'support/wrappers.dart'; void main() { CpuProfiler cpuProfiler; diff --git a/packages/devtools_app/test/flutter/debugger_controller_test.dart b/packages/devtools_app/test/debugger_controller_test.dart similarity index 97% rename from packages/devtools_app/test/flutter/debugger_controller_test.dart rename to packages/devtools_app/test/debugger_controller_test.dart index d23483a3497..c4e3e03f56c 100644 --- a/packages/devtools_app/test/flutter/debugger_controller_test.dart +++ b/packages/devtools_app/test/debugger_controller_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/debugger/flutter/debugger_controller.dart'; +import 'package:devtools_app/src/debugger/debugger_controller.dart'; import 'package:test/test.dart'; import 'package:vm_service/vm_service.dart'; diff --git a/packages/devtools_app/test/flutter/debugger_screen_test.dart b/packages/devtools_app/test/debugger_screen_test.dart similarity index 97% rename from packages/devtools_app/test/flutter/debugger_screen_test.dart rename to packages/devtools_app/test/debugger_screen_test.dart index 0d812f6c139..72d8feef95f 100644 --- a/packages/devtools_app/test/flutter/debugger_screen_test.dart +++ b/packages/devtools_app/test/debugger_screen_test.dart @@ -3,12 +3,12 @@ // found in the LICENSE file. import 'package:ansicolor/ansicolor.dart'; -import 'package:devtools_app/src/debugger/flutter/console.dart'; -import 'package:devtools_app/src/debugger/flutter/controls.dart'; -import 'package:devtools_app/src/debugger/flutter/debugger_controller.dart'; -import 'package:devtools_app/src/debugger/flutter/debugger_model.dart'; -import 'package:devtools_app/src/debugger/flutter/debugger_screen.dart'; -import 'package:devtools_app/src/flutter/common_widgets.dart'; +import 'package:devtools_app/src/debugger/console.dart'; +import 'package:devtools_app/src/debugger/controls.dart'; +import 'package:devtools_app/src/debugger/debugger_controller.dart'; +import 'package:devtools_app/src/debugger/debugger_model.dart'; +import 'package:devtools_app/src/debugger/debugger_screen.dart'; +import 'package:devtools_app/src/common_widgets.dart'; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/service_manager.dart'; import 'package:flutter/material.dart'; @@ -17,9 +17,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:vm_service/vm_service.dart'; -import '../support/mocks.dart'; -import '../support/utils.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/utils.dart'; +import 'support/wrappers.dart'; void main() { DebuggerScreen screen; diff --git a/packages/devtools_app/test/flutter/device_dialog_test.dart b/packages/devtools_app/test/device_dialog_test.dart similarity index 96% rename from packages/devtools_app/test/flutter/device_dialog_test.dart rename to packages/devtools_app/test/device_dialog_test.dart index fbf60ba7c17..ad6687f68ef 100644 --- a/packages/devtools_app/test/flutter/device_dialog_test.dart +++ b/packages/devtools_app/test/device_dialog_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/device_dialog.dart'; +import 'package:devtools_app/src/device_dialog.dart'; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/service_manager.dart'; import 'package:devtools_app/src/service_registrations.dart' as registrations; @@ -11,9 +11,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; -import '../support/utils.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/utils.dart'; +import 'support/wrappers.dart'; void main() { FakeServiceManager fakeServiceManager; diff --git a/packages/devtools_app/test/flutter/event_details_test.dart b/packages/devtools_app/test/event_details_test.dart similarity index 93% rename from packages/devtools_app/test/flutter/event_details_test.dart rename to packages/devtools_app/test/event_details_test.dart index 6d51266876f..6aafd5d6a7a 100644 --- a/packages/devtools_app/test/flutter/event_details_test.dart +++ b/packages/devtools_app/test/event_details_test.dart @@ -3,18 +3,18 @@ // found in the LICENSE file. import 'package:devtools_app/src/globals.dart'; -import 'package:devtools_app/src/profiler/flutter/cpu_profiler.dart'; +import 'package:devtools_app/src/profiler/cpu_profiler.dart'; import 'package:devtools_app/src/service_manager.dart'; -import 'package:devtools_app/src/timeline/flutter/event_details.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_controller.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_model.dart'; +import 'package:devtools_app/src/timeline/event_details.dart'; +import 'package:devtools_app/src/timeline/timeline_controller.dart'; +import 'package:devtools_app/src/timeline/timeline_model.dart'; import 'package:devtools_app/src/vm_flags.dart' as vm_flags; -import 'package:devtools_testing/support/flutter/timeline_test_data.dart'; +import 'package:devtools_testing/support/timeline_test_data.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { group('EventDetails', () { diff --git a/packages/devtools_app/test/flutter/extent_delegate_list_view_test.dart b/packages/devtools_app/test/extent_delegate_list_view_test.dart similarity index 97% rename from packages/devtools_app/test/flutter/extent_delegate_list_view_test.dart rename to packages/devtools_app/test/extent_delegate_list_view_test.dart index cbdf3d1af33..eb2e484b178 100644 --- a/packages/devtools_app/test/flutter/extent_delegate_list_view_test.dart +++ b/packages/devtools_app/test/extent_delegate_list_view_test.dart @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/extent_delegate_list.dart'; +@TestOn('vm') +import 'package:devtools_app/src/extent_delegate_list.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; diff --git a/packages/devtools_app/test/flutter/extent_delegate_test.dart b/packages/devtools_app/test/extent_delegate_test.dart similarity index 98% rename from packages/devtools_app/test/flutter/extent_delegate_test.dart rename to packages/devtools_app/test/extent_delegate_test.dart index 2eee0266d25..df4081fcc64 100644 --- a/packages/devtools_app/test/flutter/extent_delegate_test.dart +++ b/packages/devtools_app/test/extent_delegate_test.dart @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/extent_delegate_list.dart'; +@TestOn('vm') +import 'package:devtools_app/src/extent_delegate_list.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'rendering_tester.dart'; +import 'support/rendering_tester.dart'; class TestRenderSliverBoxChildManager extends RenderSliverBoxChildManager { TestRenderSliverBoxChildManager({ diff --git a/packages/devtools_app/test/flutter/flame_chart_test.dart b/packages/devtools_app/test/flame_chart_test.dart similarity index 98% rename from packages/devtools_app/test/flutter/flame_chart_test.dart rename to packages/devtools_app/test/flame_chart_test.dart index 06056ab655b..1c455d69e1d 100644 --- a/packages/devtools_app/test/flutter/flame_chart_test.dart +++ b/packages/devtools_app/test/flame_chart_test.dart @@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/charts/flutter/flame_chart.dart'; -import 'package:devtools_app/src/flutter/flutter_widgets/linked_scroll_controller.dart'; +import 'package:devtools_app/src/charts/flame_chart.dart'; +import 'package:devtools_app/src/flutter_widgets/linked_scroll_controller.dart'; import 'package:devtools_app/src/profiler/cpu_profile_model.dart'; -import 'package:devtools_app/src/profiler/flutter/cpu_profile_flame_chart.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_model.dart'; +import 'package:devtools_app/src/profiler/cpu_profile_flame_chart.dart'; +import 'package:devtools_app/src/timeline/timeline_model.dart'; import 'package:devtools_app/src/ui/colors.dart'; import 'package:devtools_app/src/utils.dart'; import 'package:devtools_testing/support/cpu_profile_test_data.dart'; -import 'package:devtools_testing/support/flutter/timeline_test_data.dart'; +import 'package:devtools_testing/support/timeline_test_data.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; diff --git a/packages/devtools_app/test/flutter/flex_split_column_test.dart b/packages/devtools_app/test/flex_split_column_test.dart similarity index 97% rename from packages/devtools_app/test/flutter/flex_split_column_test.dart rename to packages/devtools_app/test/flex_split_column_test.dart index 4643207e09f..026d2a37830 100644 --- a/packages/devtools_app/test/flutter/flex_split_column_test.dart +++ b/packages/devtools_app/test/flex_split_column_test.dart @@ -1,7 +1,7 @@ // Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/flex_split_column.dart'; +import 'package:devtools_app/src/flex_split_column.dart'; import 'package:devtools_app/src/utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/devtools_app/test/flutter/utils_test.dart b/packages/devtools_app/test/flutter/utils_test.dart deleted file mode 100644 index 0f3255c0d75..00000000000 --- a/packages/devtools_app/test/flutter/utils_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:devtools_app/src/flutter/utils.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group('LogicalKeySetExtension', () { - testWidgets('meta non-mac', (WidgetTester tester) async { - final keySet = - LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyP); - expect(keySet.describeKeys(), 'Meta-P'); - }); - - testWidgets('meta mac', (WidgetTester tester) async { - final keySet = - LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyP); - expect(keySet.describeKeys(isMacOS: true), '⌘P'); - }); - - testWidgets('ctrl', (WidgetTester tester) async { - final keySet = - LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyP); - expect(keySet.describeKeys(), 'Control-P'); - }); - }); -} diff --git a/packages/devtools_app/test/flutter/flutter_frames_chart_test.dart b/packages/devtools_app/test/flutter_frames_chart_test.dart similarity index 85% rename from packages/devtools_app/test/flutter/flutter_frames_chart_test.dart rename to packages/devtools_app/test/flutter_frames_chart_test.dart index dd2fc57fecb..d62c0787f31 100644 --- a/packages/devtools_app/test/flutter/flutter_frames_chart_test.dart +++ b/packages/devtools_app/test/flutter_frames_chart_test.dart @@ -5,16 +5,16 @@ @TestOn('vm') import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/service_manager.dart'; -import 'package:devtools_app/src/timeline/flutter/flutter_frames_chart.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_model.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_controller.dart'; +import 'package:devtools_app/src/timeline/flutter_frames_chart.dart'; +import 'package:devtools_app/src/timeline/timeline_model.dart'; +import 'package:devtools_app/src/timeline/timeline_controller.dart'; import 'package:devtools_app/src/ui/colors.dart'; -import 'package:devtools_testing/support/flutter/timeline_test_data.dart'; +import 'package:devtools_testing/support/timeline_test_data.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { Future pumpChart( diff --git a/packages/devtools_app/test/import_export_test.dart b/packages/devtools_app/test/import_export_test.dart index 823d57976e5..0572fb3a530 100644 --- a/packages/devtools_app/test/import_export_test.dart +++ b/packages/devtools_app/test/import_export_test.dart @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/config_specific/flutter/import_export/import_export.dart'; +import 'package:devtools_app/src/config_specific/import_export/import_export.dart'; import 'package:test/test.dart'; -import 'flutter/wrappers.dart'; +import 'support/wrappers.dart'; void main() async { group('ImportControllerTest', () { diff --git a/packages/devtools_app/test/flutter/initializer_test.dart b/packages/devtools_app/test/initializer_test.dart similarity index 95% rename from packages/devtools_app/test/flutter/initializer_test.dart rename to packages/devtools_app/test/initializer_test.dart index 4a950bf9c95..960d14d9492 100644 --- a/packages/devtools_app/test/flutter/initializer_test.dart +++ b/packages/devtools_app/test/initializer_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. @TestOn('vm') -import 'package:devtools_app/src/flutter/initializer.dart' +import 'package:devtools_app/src/initializer.dart' hide ensureInspectorDependencies; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/service_manager.dart'; @@ -11,7 +11,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; +import 'support/mocks.dart'; void main() { group('Initializer', () { diff --git a/packages/devtools_app/test/flutter/inspector_screen_test.dart b/packages/devtools_app/test/inspector_screen_test.dart similarity index 96% rename from packages/devtools_app/test/flutter/inspector_screen_test.dart rename to packages/devtools_app/test/inspector_screen_test.dart index f3ed8c36cfb..ad099da7e41 100644 --- a/packages/devtools_app/test/flutter/inspector_screen_test.dart +++ b/packages/devtools_app/test/inspector_screen_test.dart @@ -4,12 +4,12 @@ import 'dart:convert'; -import 'package:devtools_app/src/flutter/common_widgets.dart'; +import 'package:devtools_app/src/common_widgets.dart'; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/inspector/diagnostics_node.dart'; -import 'package:devtools_app/src/inspector/flutter/inspector_screen.dart'; -import 'package:devtools_app/src/inspector/flutter/layout_explorer/flex/flex.dart'; -import 'package:devtools_app/src/inspector/flutter/layout_explorer/layout_explorer.dart'; +import 'package:devtools_app/src/inspector/inspector_screen.dart'; +import 'package:devtools_app/src/inspector/layout_explorer/flex/flex.dart'; +import 'package:devtools_app/src/inspector/layout_explorer/layout_explorer.dart'; import 'package:devtools_app/src/inspector/inspector_controller.dart'; import 'package:devtools_app/src/inspector/inspector_service.dart'; import 'package:devtools_app/src/inspector/inspector_tree.dart'; @@ -19,8 +19,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { InspectorScreen screen; diff --git a/packages/devtools_app/test/flutter/integration/dart_cli_profile_test.dart b/packages/devtools_app/test/integration/dart_cli_profile_test.dart similarity index 99% rename from packages/devtools_app/test/flutter/integration/dart_cli_profile_test.dart rename to packages/devtools_app/test/integration/dart_cli_profile_test.dart index 7ff8c61cd2d..84b8f1b478c 100644 --- a/packages/devtools_app/test/flutter/integration/dart_cli_profile_test.dart +++ b/packages/devtools_app/test/integration/dart_cli_profile_test.dart @@ -8,7 +8,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; -import 'package:devtools_app/src/flutter/app.dart'; +import 'package:devtools_app/src/app.dart'; import 'package:devtools_app/src/framework/framework_core.dart'; import 'package:devtools_app/src/inspector/flutter_widget.dart'; import 'package:devtools_shared/devtools_shared.dart'; diff --git a/packages/devtools_app/test/integration_tests/integration_test.dart b/packages/devtools_app/test/integration_tests/integration_test.dart index 4a120702020..9352f0cf87e 100644 --- a/packages/devtools_app/test/integration_tests/integration_test.dart +++ b/packages/devtools_app/test/integration_tests/integration_test.dart @@ -15,25 +15,28 @@ import 'logging.dart'; void main() { group('integration', () { - setUpAll(() async { - compensateForFlutterTestDirectoryBug(); - final bool testInReleaseMode = - Platform.environment['WEBDEV_RELEASE'] == 'true'; + // TODO(#1965): fix and re-enable integration tests. + // ignore: dead_code + if (false) { + setUpAll(() async { + compensateForFlutterTestDirectoryBug(); + final bool testInReleaseMode = + Platform.environment['WEBDEV_RELEASE'] == 'true'; - webdevFixture = - await WebdevFixture.serve(release: testInReleaseMode, verbose: true); - browserManager = await BrowserManager.create(); - }); + webdevFixture = await WebdevFixture.serve( + release: testInReleaseMode, verbose: true); + browserManager = await BrowserManager.create(); + }); - tearDownAll(() async { - await browserManager?.teardown(); - await webdevFixture?.teardown(); - }); + tearDownAll(() async { + await browserManager?.teardown(); + await webdevFixture?.teardown(); + }); - // TODO(#1965): fix and re-enable integration tests. - group('app', appTests, skip: true); - group('logging', loggingTests, skip: true); - // Temporarily skip tests. See https://github.com/flutter/devtools/issues/1343. - group('debugging', debuggingTests, skip: true); + group('app', appTests, skip: true); + group('logging', loggingTests, skip: true); + // Temporarily skip tests. See https://github.com/flutter/devtools/issues/1343. + group('debugging', debuggingTests, skip: true); + } }, timeout: const Timeout.factor(8)); } diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/arrow_test.dart b/packages/devtools_app/test/layout_explorer/flex/arrow_test.dart similarity index 97% rename from packages/devtools_app/test/flutter/layout_explorer/flex/arrow_test.dart rename to packages/devtools_app/test/layout_explorer/flex/arrow_test.dart index 7fb151274f5..ff181f7df22 100644 --- a/packages/devtools_app/test/flutter/layout_explorer/flex/arrow_test.dart +++ b/packages/devtools_app/test/layout_explorer/flex/arrow_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/inspector/flutter/layout_explorer/flex/arrow.dart'; +import 'package:devtools_app/src/inspector/layout_explorer/flex/arrow.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/flex_test.dart b/packages/devtools_app/test/layout_explorer/flex/flex_test.dart similarity index 98% rename from packages/devtools_app/test/flutter/layout_explorer/flex/flex_test.dart rename to packages/devtools_app/test/layout_explorer/flex/flex_test.dart index 55cfebc2735..b06e7f7e16e 100644 --- a/packages/devtools_app/test/flutter/layout_explorer/flex/flex_test.dart +++ b/packages/devtools_app/test/layout_explorer/flex/flex_test.dart @@ -5,14 +5,14 @@ import 'dart:convert'; import 'package:devtools_app/src/inspector/diagnostics_node.dart'; -import 'package:devtools_app/src/inspector/flutter/layout_explorer/flex/flex.dart'; +import 'package:devtools_app/src/inspector/layout_explorer/flex/flex.dart'; import 'package:devtools_app/src/inspector/inspector_tree.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../inspector_screen_test.dart'; -import '../../wrappers.dart'; +import '../../support/wrappers.dart'; // TODO(albertusangga): Re-enable tests in this files // https://github.com/flutter/devtools/issues/1403 diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_bidirectional_horizontal.png b/packages/devtools_app/test/layout_explorer/flex/goldens/arrow_bidirectional_horizontal.png similarity index 100% rename from packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_bidirectional_horizontal.png rename to packages/devtools_app/test/layout_explorer/flex/goldens/arrow_bidirectional_horizontal.png diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_bidirectional_vertical.png b/packages/devtools_app/test/layout_explorer/flex/goldens/arrow_bidirectional_vertical.png similarity index 100% rename from packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_bidirectional_vertical.png rename to packages/devtools_app/test/layout_explorer/flex/goldens/arrow_bidirectional_vertical.png diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_unidirectional_down.png b/packages/devtools_app/test/layout_explorer/flex/goldens/arrow_unidirectional_down.png similarity index 100% rename from packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_unidirectional_down.png rename to packages/devtools_app/test/layout_explorer/flex/goldens/arrow_unidirectional_down.png diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_unidirectional_left.png b/packages/devtools_app/test/layout_explorer/flex/goldens/arrow_unidirectional_left.png similarity index 100% rename from packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_unidirectional_left.png rename to packages/devtools_app/test/layout_explorer/flex/goldens/arrow_unidirectional_left.png diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_unidirectional_right.png b/packages/devtools_app/test/layout_explorer/flex/goldens/arrow_unidirectional_right.png similarity index 100% rename from packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_unidirectional_right.png rename to packages/devtools_app/test/layout_explorer/flex/goldens/arrow_unidirectional_right.png diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_unidirectional_up.png b/packages/devtools_app/test/layout_explorer/flex/goldens/arrow_unidirectional_up.png similarity index 100% rename from packages/devtools_app/test/flutter/layout_explorer/flex/goldens/arrow_unidirectional_up.png rename to packages/devtools_app/test/layout_explorer/flex/goldens/arrow_unidirectional_up.png diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/goldens/story_of_column_layout.png b/packages/devtools_app/test/layout_explorer/flex/goldens/story_of_column_layout.png similarity index 100% rename from packages/devtools_app/test/flutter/layout_explorer/flex/goldens/story_of_column_layout.png rename to packages/devtools_app/test/layout_explorer/flex/goldens/story_of_column_layout.png diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/goldens/story_of_row_layout.png b/packages/devtools_app/test/layout_explorer/flex/goldens/story_of_row_layout.png similarity index 100% rename from packages/devtools_app/test/flutter/layout_explorer/flex/goldens/story_of_row_layout.png rename to packages/devtools_app/test/layout_explorer/flex/goldens/story_of_row_layout.png diff --git a/packages/devtools_app/test/flutter/layout_explorer/flex/utils_test.dart b/packages/devtools_app/test/layout_explorer/flex/utils_test.dart similarity index 83% rename from packages/devtools_app/test/flutter/layout_explorer/flex/utils_test.dart rename to packages/devtools_app/test/layout_explorer/flex/utils_test.dart index 33acf609129..12cfb682631 100644 --- a/packages/devtools_app/test/flutter/layout_explorer/flex/utils_test.dart +++ b/packages/devtools_app/test/layout_explorer/flex/utils_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/inspector/flutter/layout_explorer/flex/utils.dart'; +import 'package:devtools_app/src/inspector/layout_explorer/flex/utils.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { diff --git a/packages/devtools_app/test/flutter/layout_explorer/inspector_data_models_test.dart b/packages/devtools_app/test/layout_explorer/inspector_data_models_test.dart similarity index 98% rename from packages/devtools_app/test/flutter/layout_explorer/inspector_data_models_test.dart rename to packages/devtools_app/test/layout_explorer/inspector_data_models_test.dart index 2ef17280634..77ca529092a 100644 --- a/packages/devtools_app/test/flutter/layout_explorer/inspector_data_models_test.dart +++ b/packages/devtools_app/test/layout_explorer/inspector_data_models_test.dart @@ -5,8 +5,8 @@ import 'dart:convert'; import 'package:devtools_app/src/inspector/diagnostics_node.dart'; -import 'package:devtools_app/src/inspector/flutter/inspector_data_models.dart'; -import 'package:devtools_app/src/inspector/flutter/layout_explorer/flex/utils.dart'; +import 'package:devtools_app/src/inspector/inspector_data_models.dart'; +import 'package:devtools_app/src/inspector/layout_explorer/flex/utils.dart'; import 'package:flutter/widgets.dart'; import 'package:test/test.dart'; diff --git a/packages/devtools_app/test/flutter/linked_scroll_controller_test.dart b/packages/devtools_app/test/linked_scroll_controller_test.dart similarity index 99% rename from packages/devtools_app/test/flutter/linked_scroll_controller_test.dart rename to packages/devtools_app/test/linked_scroll_controller_test.dart index 44db7d9934a..d29d2039529 100644 --- a/packages/devtools_app/test/flutter/linked_scroll_controller_test.dart +++ b/packages/devtools_app/test/linked_scroll_controller_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/flutter_widgets/linked_scroll_controller.dart'; +import 'package:devtools_app/src/flutter_widgets/linked_scroll_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pedantic/pedantic.dart'; diff --git a/packages/devtools_app/test/logging_controller_test.dart b/packages/devtools_app/test/logging_controller_test.dart index 2b8e5858fe0..f4bb89781d4 100644 --- a/packages/devtools_app/test/logging_controller_test.dart +++ b/packages/devtools_app/test/logging_controller_test.dart @@ -11,7 +11,7 @@ import 'package:devtools_app/src/logging/logging_controller.dart'; import 'package:devtools_app/src/service_manager.dart'; import 'package:test/test.dart'; -import 'flutter/inspector_screen_test.dart'; +import 'inspector_screen_test.dart'; import 'support/mocks.dart'; void main() { diff --git a/packages/devtools_app/test/flutter/logging_screen_test.dart b/packages/devtools_app/test/logging_screen_test.dart similarity index 96% rename from packages/devtools_app/test/flutter/logging_screen_test.dart rename to packages/devtools_app/test/logging_screen_test.dart index f9e099629e7..a460b0515b1 100644 --- a/packages/devtools_app/test/flutter/logging_screen_test.dart +++ b/packages/devtools_app/test/logging_screen_test.dart @@ -6,22 +6,22 @@ import 'dart:async'; import 'package:ansicolor/ansicolor.dart'; -import 'package:devtools_app/src/flutter/common_widgets.dart'; -import 'package:devtools_app/src/flutter/console.dart'; +import 'package:devtools_app/src/common_widgets.dart'; +import 'package:devtools_app/src/console.dart'; import 'package:devtools_app/src/globals.dart'; -import 'package:devtools_app/src/logging/flutter/logging_screen.dart'; +import 'package:devtools_app/src/logging/logging_screen.dart'; import 'package:devtools_app/src/logging/logging_controller.dart'; import 'package:devtools_app/src/service_extensions.dart'; import 'package:devtools_app/src/service_manager.dart'; -import 'package:devtools_app/src/ui/flutter/service_extension_widgets.dart'; +import 'package:devtools_app/src/ui/service_extension_widgets.dart'; import 'package:devtools_app/src/utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; -import '../support/utils.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/utils.dart'; +import 'support/wrappers.dart'; void main() { LoggingScreen screen; diff --git a/packages/devtools_app/test/flutter/memory_screen_test.dart b/packages/devtools_app/test/memory_screen_test.dart similarity index 94% rename from packages/devtools_app/test/flutter/memory_screen_test.dart rename to packages/devtools_app/test/memory_screen_test.dart index 46355929d30..dac968dd786 100644 --- a/packages/devtools_app/test/flutter/memory_screen_test.dart +++ b/packages/devtools_app/test/memory_screen_test.dart @@ -3,18 +3,18 @@ // found in the LICENSE file. @TestOn('vm') -import 'package:devtools_app/src/flutter/common_widgets.dart'; +import 'package:devtools_app/src/common_widgets.dart'; import 'package:devtools_app/src/globals.dart'; -import 'package:devtools_app/src/memory/flutter/memory_chart.dart'; -import 'package:devtools_app/src/memory/flutter/memory_controller.dart'; -import 'package:devtools_app/src/memory/flutter/memory_screen.dart'; +import 'package:devtools_app/src/memory/memory_chart.dart'; +import 'package:devtools_app/src/memory/memory_controller.dart'; +import 'package:devtools_app/src/memory/memory_screen.dart'; import 'package:devtools_app/src/service_manager.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { MemoryScreen screen; diff --git a/packages/devtools_app/test/memory_service_test.dart b/packages/devtools_app/test/memory_service_test.dart index ca945dedf6b..0115a328f2e 100644 --- a/packages/devtools_app/test/memory_service_test.dart +++ b/packages/devtools_app/test/memory_service_test.dart @@ -10,9 +10,13 @@ import 'package:devtools_testing/support/flutter_test_environment.dart'; import 'package:test/test.dart'; void main() async { - final FlutterTestEnvironment env = FlutterTestEnvironment( - const FlutterRunConfiguration(withDebugger: true), - ); + // TODO(https://github.com/flutter/devtools/issues/2053): rewrite. + // ignore: dead_code + if (false) { + final FlutterTestEnvironment env = FlutterTestEnvironment( + const FlutterRunConfiguration(withDebugger: true), + ); - await runMemoryServiceTests(env); + await runMemoryServiceTests(env); + } } diff --git a/packages/devtools_app/test/flutter/navigation_test.dart b/packages/devtools_app/test/navigation_test.dart similarity index 98% rename from packages/devtools_app/test/flutter/navigation_test.dart rename to packages/devtools_app/test/navigation_test.dart index c7d744aaa34..2b460c8023b 100644 --- a/packages/devtools_app/test/flutter/navigation_test.dart +++ b/packages/devtools_app/test/navigation_test.dart @@ -1,4 +1,4 @@ -import 'package:devtools_app/src/flutter/navigation.dart'; +import 'package:devtools_app/src/navigation.dart'; import 'package:devtools_app/src/ui/theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/devtools_app/test/flutter/network_model_test.dart b/packages/devtools_app/test/network_model_test.dart similarity index 95% rename from packages/devtools_app/test/flutter/network_model_test.dart rename to packages/devtools_app/test/network_model_test.dart index a20f9cb994e..4512a8e7972 100644 --- a/packages/devtools_app/test/flutter/network_model_test.dart +++ b/packages/devtools_app/test/network_model_test.dart @@ -4,11 +4,11 @@ @TestOn('vm') import 'package:devtools_app/src/http/http_request_data.dart'; -import 'package:devtools_app/src/network/flutter/network_screen.dart'; +import 'package:devtools_app/src/network/network_screen.dart'; import 'package:devtools_app/src/network/network_controller.dart'; import 'package:test/test.dart'; -import '../support/utils.dart'; +import 'support/utils.dart'; void main() { group('NetworkScreen HttpRequestsTable', () { diff --git a/packages/devtools_app/test/flutter/network_profiler_test.dart b/packages/devtools_app/test/network_profiler_test.dart similarity index 96% rename from packages/devtools_app/test/flutter/network_profiler_test.dart rename to packages/devtools_app/test/network_profiler_test.dart index 396bbe1ceb7..c7e9fa01e6f 100644 --- a/packages/devtools_app/test/flutter/network_profiler_test.dart +++ b/packages/devtools_app/test/network_profiler_test.dart @@ -3,22 +3,22 @@ // found in the LICENSE file. @TestOn('vm') -import 'package:devtools_app/src/flutter/split.dart'; +import 'package:devtools_app/src/split.dart'; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/http/http.dart'; import 'package:devtools_app/src/http/http_request_data.dart'; -import 'package:devtools_app/src/network/flutter/http_request_inspector.dart'; -import 'package:devtools_app/src/network/flutter/http_request_inspector_views.dart'; -import 'package:devtools_app/src/network/flutter/network_screen.dart'; +import 'package:devtools_app/src/network/http_request_inspector.dart'; +import 'package:devtools_app/src/network/http_request_inspector_views.dart'; +import 'package:devtools_app/src/network/network_screen.dart'; import 'package:devtools_app/src/network/network_controller.dart'; import 'package:devtools_app/src/service_manager.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:vm_service/vm_service.dart'; -import '../support/mocks.dart'; -import '../support/utils.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/utils.dart'; +import 'support/wrappers.dart'; NetworkController controller = NetworkController(); diff --git a/packages/devtools_app/test/flutter/network_screen_test.dart b/packages/devtools_app/test/network_screen_test.dart similarity index 87% rename from packages/devtools_app/test/flutter/network_screen_test.dart rename to packages/devtools_app/test/network_screen_test.dart index 80ca05123b9..31e3da468a1 100644 --- a/packages/devtools_app/test/flutter/network_screen_test.dart +++ b/packages/devtools_app/test/network_screen_test.dart @@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/common_widgets.dart'; +import 'package:devtools_app/src/common_widgets.dart'; import 'package:devtools_app/src/globals.dart'; -import 'package:devtools_app/src/network/flutter/network_screen.dart'; +import 'package:devtools_app/src/network/network_screen.dart'; import 'package:devtools_app/src/service_manager.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { NetworkScreen screen; diff --git a/packages/devtools_app/test/flutter/notifications_test.dart b/packages/devtools_app/test/notifications_test.dart similarity index 98% rename from packages/devtools_app/test/flutter/notifications_test.dart rename to packages/devtools_app/test/notifications_test.dart index 49263c112c7..effc555e38d 100644 --- a/packages/devtools_app/test/flutter/notifications_test.dart +++ b/packages/devtools_app/test/notifications_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/notifications.dart'; +import 'package:devtools_app/src/notifications.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/devtools_app/test/flutter/performance_screen_test.dart b/packages/devtools_app/test/performance_screen_test.dart similarity index 93% rename from packages/devtools_app/test/flutter/performance_screen_test.dart rename to packages/devtools_app/test/performance_screen_test.dart index 2653e3de52c..ad1ffb0c64e 100644 --- a/packages/devtools_app/test/flutter/performance_screen_test.dart +++ b/packages/devtools_app/test/performance_screen_test.dart @@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/common_widgets.dart'; +import 'package:devtools_app/src/common_widgets.dart'; import 'package:devtools_app/src/globals.dart'; -import 'package:devtools_app/src/performance/flutter/performance_screen.dart'; +import 'package:devtools_app/src/performance/performance_screen.dart'; import 'package:devtools_app/src/performance/performance_controller.dart'; -import 'package:devtools_app/src/profiler/flutter/cpu_profiler.dart'; +import 'package:devtools_app/src/profiler/cpu_profiler.dart'; import 'package:devtools_app/src/service_manager.dart'; -import 'package:devtools_app/src/ui/flutter/vm_flag_widgets.dart'; +import 'package:devtools_app/src/ui/vm_flag_widgets.dart'; import 'package:devtools_app/src/vm_flags.dart' as vm_flags; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { PerformanceScreen screen; diff --git a/packages/devtools_app/test/flutter/preferences_controller_test.dart b/packages/devtools_app/test/preferences_controller_test.dart similarity index 93% rename from packages/devtools_app/test/flutter/preferences_controller_test.dart rename to packages/devtools_app/test/preferences_controller_test.dart index e9155cd6b16..bbbf0aff7ee 100644 --- a/packages/devtools_app/test/flutter/preferences_controller_test.dart +++ b/packages/devtools_app/test/preferences_controller_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/preferences.dart'; +import 'package:devtools_app/src/preferences.dart'; import 'package:test/test.dart'; void main() { diff --git a/packages/devtools_app/test/flutter/scaffold_test.dart b/packages/devtools_app/test/scaffold_test.dart similarity index 96% rename from packages/devtools_app/test/flutter/scaffold_test.dart rename to packages/devtools_app/test/scaffold_test.dart index 45ac095859e..270d519051a 100644 --- a/packages/devtools_app/test/flutter/scaffold_test.dart +++ b/packages/devtools_app/test/scaffold_test.dart @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/scaffold.dart'; -import 'package:devtools_app/src/flutter/screen.dart'; +import 'package:devtools_app/src/scaffold.dart'; +import 'package:devtools_app/src/screen.dart'; import 'package:devtools_app/src/framework_controller.dart'; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/service_manager.dart'; @@ -11,8 +11,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { group('DevToolsScaffold widget', () { diff --git a/packages/devtools_app/test/flutter/service_extension_widgets_test.dart b/packages/devtools_app/test/service_extension_widgets_test.dart similarity index 97% rename from packages/devtools_app/test/flutter/service_extension_widgets_test.dart rename to packages/devtools_app/test/service_extension_widgets_test.dart index 7a222106ec1..760089fe0a4 100644 --- a/packages/devtools_app/test/flutter/service_extension_widgets_test.dart +++ b/packages/devtools_app/test/service_extension_widgets_test.dart @@ -5,19 +5,19 @@ import 'dart:async'; import 'package:devtools_app/src/core/message_bus.dart'; -import 'package:devtools_app/src/flutter/notifications.dart'; +import 'package:devtools_app/src/notifications.dart'; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/service_extensions.dart'; import 'package:devtools_app/src/service_manager.dart'; import 'package:devtools_app/src/service_registrations.dart'; -import 'package:devtools_app/src/ui/flutter/service_extension_widgets.dart'; +import 'package:devtools_app/src/ui/service_extension_widgets.dart'; import 'package:devtools_app/src/utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { MockServiceManager mockServiceManager; diff --git a/packages/devtools_app/test/flutter/split_test.dart b/packages/devtools_app/test/split_test.dart similarity index 99% rename from packages/devtools_app/test/flutter/split_test.dart rename to packages/devtools_app/test/split_test.dart index c2db748a074..ce5dcc9d8d6 100644 --- a/packages/devtools_app/test/flutter/split_test.dart +++ b/packages/devtools_app/test/split_test.dart @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/split.dart'; +import 'package:devtools_app/src/split.dart'; import 'package:devtools_app/src/utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'wrappers.dart'; +import 'support/wrappers.dart'; void main() { // Note: tester by default has a window size of 800x600. diff --git a/packages/devtools_app/test/support/mocks.dart b/packages/devtools_app/test/support/mocks.dart index 97994f582a1..cb6a691fa6d 100644 --- a/packages/devtools_app/test/support/mocks.dart +++ b/packages/devtools_app/test/support/mocks.dart @@ -5,11 +5,11 @@ import 'dart:async'; import 'package:devtools_app/src/connected_app.dart'; -import 'package:devtools_app/src/debugger/flutter/debugger_controller.dart'; -import 'package:devtools_app/src/flutter/banner_messages.dart'; -import 'package:devtools_app/src/flutter/initializer.dart' as initializer; +import 'package:devtools_app/src/debugger/debugger_controller.dart'; +import 'package:devtools_app/src/banner_messages.dart'; +import 'package:devtools_app/src/initializer.dart' as initializer; import 'package:devtools_app/src/logging/logging_controller.dart'; -import 'package:devtools_app/src/memory/flutter/memory_controller.dart' +import 'package:devtools_app/src/memory/memory_controller.dart' as flutter_memory; import 'package:devtools_app/src/memory/memory_controller.dart'; import 'package:devtools_app/src/performance/performance_controller.dart'; @@ -18,7 +18,7 @@ import 'package:devtools_app/src/profiler/profile_granularity.dart'; import 'package:devtools_app/src/service_extensions.dart' as extensions; import 'package:devtools_app/src/service_manager.dart'; import 'package:devtools_app/src/stream_value_listenable.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_controller.dart'; +import 'package:devtools_app/src/timeline/timeline_controller.dart'; import 'package:devtools_app/src/utils.dart'; import 'package:devtools_app/src/vm_flags.dart' as vm_flags; import 'package:devtools_app/src/vm_service_wrapper.dart'; diff --git a/packages/devtools_app/test/flutter/rendering_tester.dart b/packages/devtools_app/test/support/rendering_tester.dart similarity index 100% rename from packages/devtools_app/test/flutter/rendering_tester.dart rename to packages/devtools_app/test/support/rendering_tester.dart diff --git a/packages/devtools_app/test/flutter/wrappers.dart b/packages/devtools_app/test/support/wrappers.dart similarity index 90% rename from packages/devtools_app/test/flutter/wrappers.dart rename to packages/devtools_app/test/support/wrappers.dart index 884c04e583d..8fdd8724f74 100644 --- a/packages/devtools_app/test/flutter/wrappers.dart +++ b/packages/devtools_app/test/support/wrappers.dart @@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/debugger/flutter/debugger_controller.dart'; -import 'package:devtools_app/src/flutter/banner_messages.dart'; -import 'package:devtools_app/src/flutter/notifications.dart'; -import 'package:devtools_app/src/flutter/theme.dart'; +import 'package:devtools_app/src/debugger/debugger_controller.dart'; +import 'package:devtools_app/src/banner_messages.dart'; +import 'package:devtools_app/src/notifications.dart'; +import 'package:devtools_app/src/theme.dart'; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/logging/logging_controller.dart'; -import 'package:devtools_app/src/memory/flutter/memory_controller.dart'; +import 'package:devtools_app/src/memory/memory_controller.dart'; import 'package:devtools_app/src/network/network_controller.dart'; import 'package:devtools_app/src/performance/performance_controller.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_controller.dart'; +import 'package:devtools_app/src/timeline/timeline_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/devtools_app/test/flutter/table_test.dart b/packages/devtools_app/test/table_test.dart similarity index 99% rename from packages/devtools_app/test/flutter/table_test.dart rename to packages/devtools_app/test/table_test.dart index f4d65e23214..3ce19bf6525 100644 --- a/packages/devtools_app/test/flutter/table_test.dart +++ b/packages/devtools_app/test/table_test.dart @@ -1,4 +1,4 @@ -import 'package:devtools_app/src/flutter/table.dart'; +import 'package:devtools_app/src/table.dart'; import 'package:devtools_app/src/table_data.dart'; import 'package:devtools_app/src/trees.dart'; import 'package:devtools_app/src/utils.dart'; @@ -6,7 +6,7 @@ import 'package:flutter/material.dart' hide TableRow; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'wrappers.dart'; +import 'support/wrappers.dart'; void main() { group('FlatTable view', () { diff --git a/packages/devtools_app/test/flutter/timeline_controller_test.dart b/packages/devtools_app/test/timeline_controller_test.dart similarity index 88% rename from packages/devtools_app/test/flutter/timeline_controller_test.dart rename to packages/devtools_app/test/timeline_controller_test.dart index a15e3b2fc9b..ed4320fd02f 100644 --- a/packages/devtools_app/test/flutter/timeline_controller_test.dart +++ b/packages/devtools_app/test/timeline_controller_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. @TestOn('vm') -import 'package:devtools_testing/flutter/timeline_controller_test.dart'; +import 'package:devtools_testing/timeline_controller_test.dart'; import 'package:devtools_testing/support/flutter_test_driver.dart' show FlutterRunConfiguration; import 'package:devtools_testing/support/flutter_test_environment.dart'; diff --git a/packages/devtools_app/test/flutter/timeline_flame_chart_test.dart b/packages/devtools_app/test/timeline_flame_chart_test.dart similarity index 87% rename from packages/devtools_app/test/flutter/timeline_flame_chart_test.dart rename to packages/devtools_app/test/timeline_flame_chart_test.dart index e25c075cf27..bf5fe3253ab 100644 --- a/packages/devtools_app/test/flutter/timeline_flame_chart_test.dart +++ b/packages/devtools_app/test/timeline_flame_chart_test.dart @@ -4,17 +4,17 @@ import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/service_manager.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_flame_chart.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_screen.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_controller.dart'; -import 'package:devtools_testing/support/flutter/timeline_test_data.dart'; +import 'package:devtools_app/src/timeline/timeline_flame_chart.dart'; +import 'package:devtools_app/src/timeline/timeline_screen.dart'; +import 'package:devtools_app/src/timeline/timeline_controller.dart'; +import 'package:devtools_testing/support/timeline_test_data.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:vm_service/vm_service.dart' as vm_service; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { FakeServiceManager fakeServiceManager; diff --git a/packages/devtools_app/test/flutter/timeline_model_test.dart b/packages/devtools_app/test/timeline_model_test.dart similarity index 98% rename from packages/devtools_app/test/flutter/timeline_model_test.dart rename to packages/devtools_app/test/timeline_model_test.dart index 1a4b4faea56..eaccea4f89b 100644 --- a/packages/devtools_app/test/flutter/timeline_model_test.dart +++ b/packages/devtools_app/test/timeline_model_test.dart @@ -4,12 +4,12 @@ import 'dart:convert'; import 'package:devtools_app/src/profiler/cpu_profile_model.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_model.dart'; +import 'package:devtools_app/src/timeline/timeline_model.dart'; import 'package:devtools_app/src/trace_event.dart'; import 'package:devtools_app/src/utils.dart'; import 'package:devtools_testing/support/cpu_profile_test_data.dart'; -import 'package:devtools_testing/support/flutter/test_utils.dart'; -import 'package:devtools_testing/support/flutter/timeline_test_data.dart'; +import 'package:devtools_testing/support/test_utils.dart'; +import 'package:devtools_testing/support/timeline_test_data.dart'; import 'package:test/test.dart'; void main() { diff --git a/packages/devtools_app/test/flutter/timeline_processor_test.dart b/packages/devtools_app/test/timeline_processor_test.dart similarity index 96% rename from packages/devtools_app/test/flutter/timeline_processor_test.dart rename to packages/devtools_app/test/timeline_processor_test.dart index fb17831dd11..b932e9181ed 100644 --- a/packages/devtools_app/test/flutter/timeline_processor_test.dart +++ b/packages/devtools_app/test/timeline_processor_test.dart @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/timeline/flutter/timeline_controller.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_model.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_processor.dart'; +import 'package:devtools_app/src/timeline/timeline_controller.dart'; +import 'package:devtools_app/src/timeline/timeline_model.dart'; +import 'package:devtools_app/src/timeline/timeline_processor.dart'; import 'package:devtools_app/src/trace_event.dart'; import 'package:devtools_app/src/utils.dart'; -import 'package:devtools_testing/support/flutter/test_utils.dart'; -import 'package:devtools_testing/support/flutter/timeline_test_data.dart'; +import 'package:devtools_testing/support/test_utils.dart'; +import 'package:devtools_testing/support/timeline_test_data.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; diff --git a/packages/devtools_app/test/flutter/timeline_screen_test.dart b/packages/devtools_app/test/timeline_screen_test.dart similarity index 88% rename from packages/devtools_app/test/flutter/timeline_screen_test.dart rename to packages/devtools_app/test/timeline_screen_test.dart index 6ce90b101e7..c803bb89182 100644 --- a/packages/devtools_app/test/flutter/timeline_screen_test.dart +++ b/packages/devtools_app/test/timeline_screen_test.dart @@ -3,23 +3,23 @@ // found in the LICENSE file. @TestOn('vm') -import 'package:devtools_app/src/flutter/common_widgets.dart'; -import 'package:devtools_app/src/flutter/split.dart'; +import 'package:devtools_app/src/common_widgets.dart'; +import 'package:devtools_app/src/split.dart'; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/service_manager.dart'; -import 'package:devtools_app/src/timeline/flutter/event_details.dart'; -import 'package:devtools_app/src/timeline/flutter/flutter_frames_chart.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_flame_chart.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_screen.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_controller.dart'; -import 'package:devtools_testing/support/flutter/timeline_test_data.dart'; +import 'package:devtools_app/src/timeline/event_details.dart'; +import 'package:devtools_app/src/timeline/flutter_frames_chart.dart'; +import 'package:devtools_app/src/timeline/timeline_flame_chart.dart'; +import 'package:devtools_app/src/timeline/timeline_screen.dart'; +import 'package:devtools_app/src/timeline/timeline_controller.dart'; +import 'package:devtools_testing/support/timeline_test_data.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:vm_service/vm_service.dart' as vm_service; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { TimelineScreen screen; diff --git a/packages/devtools_app/test/utils_test.dart b/packages/devtools_app/test/utils_test.dart index e9ba8a97aa9..daaf198b074 100644 --- a/packages/devtools_app/test/utils_test.dart +++ b/packages/devtools_app/test/utils_test.dart @@ -5,7 +5,9 @@ import 'dart:async'; import 'package:devtools_app/src/utils.dart'; -import 'package:test/test.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; void main() { group('utils', () { @@ -476,6 +478,26 @@ void main() { }); }); }); + + group('LogicalKeySetExtension', () { + testWidgets('meta non-mac', (WidgetTester tester) async { + final keySet = + LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyP); + expect(keySet.describeKeys(), 'Meta-P'); + }); + + testWidgets('meta mac', (WidgetTester tester) async { + final keySet = + LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyP); + expect(keySet.describeKeys(isMacOS: true), '⌘P'); + }); + + testWidgets('ctrl', (WidgetTester tester) async { + final keySet = + LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyP); + expect(keySet.describeKeys(), 'Control-P'); + }); + }); } // This was generated from a canvas with font size 14.0. diff --git a/packages/devtools_app/test/flutter/vm_flag_widgets_test.dart b/packages/devtools_app/test/vm_flag_widgets_test.dart similarity index 95% rename from packages/devtools_app/test/flutter/vm_flag_widgets_test.dart rename to packages/devtools_app/test/vm_flag_widgets_test.dart index 7509aca91fa..25e07e3aa78 100644 --- a/packages/devtools_app/test/flutter/vm_flag_widgets_test.dart +++ b/packages/devtools_app/test/vm_flag_widgets_test.dart @@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:devtools_app/src/flutter/banner_messages.dart'; -import 'package:devtools_app/src/flutter/theme.dart'; +import 'package:devtools_app/src/banner_messages.dart'; +import 'package:devtools_app/src/theme.dart'; import 'package:devtools_app/src/globals.dart'; -import 'package:devtools_app/src/performance/flutter/performance_screen.dart'; +import 'package:devtools_app/src/performance/performance_screen.dart'; import 'package:devtools_app/src/profiler/profile_granularity.dart'; import 'package:devtools_app/src/service_manager.dart'; -import 'package:devtools_app/src/ui/flutter/vm_flag_widgets.dart'; +import 'package:devtools_app/src/ui/vm_flag_widgets.dart'; import 'package:devtools_app/src/vm_flags.dart' as vm_flags; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:provider/provider.dart'; import 'package:vm_service/vm_service.dart'; -import '../support/mocks.dart'; -import 'wrappers.dart'; +import 'support/mocks.dart'; +import 'support/wrappers.dart'; void main() { group('Profile Granularity Dropdown', () { diff --git a/packages/devtools_testing/lib/support/flutter/test_utils.dart b/packages/devtools_testing/lib/support/test_utils.dart similarity index 90% rename from packages/devtools_testing/lib/support/flutter/test_utils.dart rename to packages/devtools_testing/lib/support/test_utils.dart index ea4d56f3ecc..188f0ab113b 100644 --- a/packages/devtools_testing/lib/support/flutter/test_utils.dart +++ b/packages/devtools_testing/lib/support/test_utils.dart @@ -6,7 +6,7 @@ import 'dart:convert'; -import 'package:devtools_app/src/timeline/flutter/timeline_model.dart'; +import 'package:devtools_app/src/timeline/timeline_model.dart'; import 'package:devtools_app/src/trace_event.dart'; SyncTimelineEvent testSyncTimelineEvent(TraceEventWrapper eventWrapper) => diff --git a/packages/devtools_testing/lib/support/flutter/timeline_test_data.dart b/packages/devtools_testing/lib/support/timeline_test_data.dart similarity index 99% rename from packages/devtools_testing/lib/support/flutter/timeline_test_data.dart rename to packages/devtools_testing/lib/support/timeline_test_data.dart index 2a4b5778f05..d4a96c982cc 100644 --- a/packages/devtools_testing/lib/support/flutter/timeline_test_data.dart +++ b/packages/devtools_testing/lib/support/timeline_test_data.dart @@ -5,11 +5,11 @@ // ignore_for_file: implementation_imports import 'dart:convert'; -import 'package:devtools_app/src/timeline/flutter/timeline_model.dart'; +import 'package:devtools_app/src/timeline/timeline_model.dart'; import 'package:devtools_app/src/trace_event.dart'; import 'package:devtools_app/src/utils.dart'; -import '../cpu_profile_test_data.dart'; +import 'cpu_profile_test_data.dart'; import 'test_utils.dart'; const testUiThreadId = 1; diff --git a/packages/devtools_testing/lib/flutter/timeline_controller_test.dart b/packages/devtools_testing/lib/timeline_controller_test.dart similarity index 94% rename from packages/devtools_testing/lib/flutter/timeline_controller_test.dart rename to packages/devtools_testing/lib/timeline_controller_test.dart index 8a41432e232..a4a827b1f86 100644 --- a/packages/devtools_testing/lib/flutter/timeline_controller_test.dart +++ b/packages/devtools_testing/lib/timeline_controller_test.dart @@ -6,12 +6,12 @@ // ignore_for_file: invalid_use_of_visible_for_testing_member @TestOn('vm') -import 'package:devtools_app/src/timeline/flutter/timeline_controller.dart'; -import 'package:devtools_app/src/timeline/flutter/timeline_model.dart'; +import 'package:devtools_app/src/timeline/timeline_controller.dart'; +import 'package:devtools_app/src/timeline/timeline_model.dart'; import 'package:test/test.dart'; -import '../support/flutter/timeline_test_data.dart'; -import '../support/flutter_test_environment.dart'; +import 'support/flutter_test_environment.dart'; +import 'support/timeline_test_data.dart'; Future runTimelineControllerTests(FlutterTestEnvironment env) async { TimelineController timelineController; diff --git a/tool/travis.sh b/tool/travis.sh index 2ea7e9f2761..0c1b927667e 100755 --- a/tool/travis.sh +++ b/tool/travis.sh @@ -124,9 +124,9 @@ elif [ "$BOT" = "test_ddc" ]; then # The flutter tool doesn't support excluding a specific set of targets, # so we explicitly provide them. if [ "$PLATFORM" = "vm" ]; then - flutter test test/*.dart test/{core,fixtures,flutter,support,ui}/ + flutter test test/*.dart test/{core,fixtures,support,ui}/ elif [ "$PLATFORM" = "chrome" ]; then - flutter test --platform chrome test/*.dart test/{core,fixtures,flutter,support,ui}/ + flutter test --platform chrome test/*.dart test/{core,fixtures,support,ui}/ else echo "unknown test platform" exit 1 @@ -142,9 +142,9 @@ elif [ "$BOT" = "test_dart2js" ]; then # The flutter tool doesn't support excluding a specific set of targets, # so we explicitly provide them. if [ "$PLATFORM" = "vm" ]; then - WEBDEV_RELEASE=true flutter test test/*.dart test/{core,fixtures,flutter,support,ui}/ + WEBDEV_RELEASE=true flutter test test/*.dart test/{core,fixtures,support,ui}/ elif [ "$PLATFORM" = "chrome" ]; then - WEBDEV_RELEASE=true flutter test --platform chrome test/*.dart test/{core,fixtures,flutter,support,ui}/ + WEBDEV_RELEASE=true flutter test --platform chrome test/*.dart test/{core,fixtures,support,ui}/ else echo "unknown test platform" exit 1