Skip to content

Commit 2114436

Browse files
authored
Move platform-specific log-reading implementation details from ResidentRunner/FlutterDevice to DeviceLogReader implementations (#156181)
Cleans up flutter/flutter#155800. In summary, `ResidentRunner`/`FlutterDevice` have branching behavior around logging that depends on the type of `DeviceLogReader` on the `FlutterDevice` instance. Let's instead move this behavior to the `DeviceLogReader` implementations. My apologies for the large diff. Much of this is a refactor that was a bit too difficult to separate into its own commits. Here are the main two changes * Replaces the mutable `connectedVmService` field on the `DeviceLogReader` class with a new method `provideVmService`. This serves largely the same purpose as the mutable field, but it allows for asynchronous code. This is where we put the logic that used to exist in `FlutterDevice.tryInitLogReader`. * Removes the `tryInitLogReader` method from `FlutterDevice`. This method served to set the `appPid` field on the `FlutterDevice`'s `DeviceLogReader` instance. This was only used in the case of Android to filter out logs unrelated to the flutter app coming from the device, so we can move this logic to `AdbLogReader`'s implementation of `provideVmService`.
1 parent 4b818b5 commit 2114436

22 files changed

+136
-127
lines changed

packages/flutter_tools/lib/src/android/android_device.dart

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:async';
66

77
import 'package:meta/meta.dart';
88
import 'package:process/process.dart';
9+
import 'package:vm_service/vm_service.dart';
910

1011
import '../application_package.dart';
1112
import '../base/common.dart' show throwToolExit;
@@ -21,6 +22,7 @@ import '../device_port_forwarder.dart';
2122
import '../device_vm_service_discovery_for_attach.dart';
2223
import '../project.dart';
2324
import '../protocol_discovery.dart';
25+
import '../vmservice.dart';
2426
import 'android.dart';
2527
import 'android_builder.dart';
2628
import 'android_console.dart';
@@ -618,6 +620,7 @@ class AndroidDevice extends Device {
618620
await AdbLogReader.createLogReader(
619621
this,
620622
_processManager,
623+
_logger,
621624
),
622625
portForwarder: portForwarder,
623626
hostPort: debuggingOptions.hostVmServicePort,
@@ -796,12 +799,14 @@ class AndroidDevice extends Device {
796799
return _pastLogReader ??= await AdbLogReader.createLogReader(
797800
this,
798801
_processManager,
802+
_logger,
799803
includePastLogs: true,
800804
);
801805
} else {
802806
return _logReader ??= await AdbLogReader.createLogReader(
803807
this,
804808
_processManager,
809+
_logger,
805810
);
806811
}
807812
}
@@ -1042,15 +1047,20 @@ class AndroidMemoryInfo extends MemoryInfo {
10421047

10431048
/// A log reader that logs from `adb logcat`.
10441049
class AdbLogReader extends DeviceLogReader {
1045-
AdbLogReader._(this._adbProcess, this.name);
1050+
AdbLogReader._(this._adbProcess, this.name, this._logger);
10461051

10471052
@visibleForTesting
1048-
factory AdbLogReader.test(Process adbProcess, String name) = AdbLogReader._;
1053+
factory AdbLogReader.test(
1054+
Process adbProcess,
1055+
String name,
1056+
Logger logger,
1057+
) = AdbLogReader._;
10491058

10501059
/// Create a new [AdbLogReader] from an [AndroidDevice] instance.
10511060
static Future<AdbLogReader> createLogReader(
10521061
AndroidDevice device,
1053-
ProcessManager processManager, {
1062+
ProcessManager processManager,
1063+
Logger logger, {
10541064
bool includePastLogs = false,
10551065
}) async {
10561066
// logcat -T is not supported on Android releases before Lollipop.
@@ -1085,11 +1095,15 @@ class AdbLogReader extends DeviceLogReader {
10851095
]);
10861096
}
10871097
final Process process = await processManager.start(device.adbCommandForDevice(args));
1088-
return AdbLogReader._(process, device.name);
1098+
return AdbLogReader._(process, device.name, logger);
10891099
}
10901100

1101+
int? _appPid;
1102+
10911103
final Process _adbProcess;
10921104

1105+
final Logger _logger;
1106+
10931107
@override
10941108
final String name;
10951109

@@ -1101,6 +1115,17 @@ class AdbLogReader extends DeviceLogReader {
11011115
@override
11021116
Stream<String> get logLines => _linesController.stream;
11031117

1118+
@override
1119+
Future<void> provideVmService(FlutterVmService connectedVmService) async {
1120+
final VM? vm = await connectedVmService.getVmGuarded();
1121+
if (vm == null) {
1122+
_logger.printError('An error occurred when setting up filtering for adb logs. '
1123+
'Unable to communicate with the VM service.');
1124+
} else {
1125+
_appPid = vm.pid;
1126+
}
1127+
}
1128+
11041129
void _start() {
11051130
// We expect logcat streams to occasionally contain invalid utf-8,
11061131
// see: https://github.com/flutter/flutter/pull/8864.
@@ -1189,7 +1214,7 @@ class AdbLogReader extends DeviceLogReader {
11891214
_fatalCrash = false;
11901215
}
11911216
}
1192-
} else if (appPid != null && int.parse(logMatch.group(1)!) == appPid) {
1217+
} else if (_appPid != null && int.parse(logMatch.group(1)!) == _appPid) {
11931218
acceptLine = !_surfaceSyncerSpam.hasMatch(line);
11941219

11951220
if (_fatalLog.hasMatch(line)) {

packages/flutter_tools/lib/src/custom_devices/custom_device.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import '../device_port_forwarder.dart';
2323
import '../features.dart';
2424
import '../project.dart';
2525
import '../protocol_discovery.dart';
26+
import '../vmservice.dart';
2627
import 'custom_device_config.dart';
2728
import 'custom_device_workflow.dart';
2829
import 'custom_devices_config.dart';
@@ -111,6 +112,9 @@ class CustomDeviceLogReader extends DeviceLogReader {
111112

112113
@override
113114
Stream<String> get logLines => logLinesController.stream;
115+
116+
@override
117+
Future<void> provideVmService(FlutterVmService connectedVmService) async { }
114118
}
115119

116120
/// A [DevicePortForwarder] that uses commands to forward / unforward a port.

packages/flutter_tools/lib/src/desktop_device.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import 'device_port_forwarder.dart';
1919
import 'globals.dart' as globals;
2020
import 'macos/macos_device.dart';
2121
import 'protocol_discovery.dart';
22+
import 'vmservice.dart';
2223

2324
/// A partial implementation of Device for desktop-class devices to inherit
2425
/// from, containing implementations that are common to all desktop devices.
@@ -384,4 +385,7 @@ class DesktopLogReader extends DeviceLogReader {
384385
void dispose() {
385386
// Nothing to dispose.
386387
}
388+
389+
@override
390+
Future<void> provideVmService(FlutterVmService connectedVmService) async { }
387391
}

packages/flutter_tools/lib/src/device.dart

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,14 +1440,11 @@ abstract class DeviceLogReader {
14401440

14411441
/// Some logs can be obtained from a VM service stream.
14421442
/// Set this after the VM services are connected.
1443-
FlutterVmService? connectedVMService;
1443+
Future<void> provideVmService(FlutterVmService connectedVmService);
14441444

14451445
@override
14461446
String toString() => name;
14471447

1448-
/// Process ID of the app on the device.
1449-
int? appPid;
1450-
14511448
// Clean up resources allocated by log reader e.g. subprocesses
14521449
void dispose();
14531450
}
@@ -1466,17 +1463,14 @@ class NoOpDeviceLogReader implements DeviceLogReader {
14661463
@override
14671464
final String name;
14681465

1469-
@override
1470-
int? appPid;
1471-
1472-
@override
1473-
FlutterVmService? connectedVMService;
1474-
14751466
@override
14761467
Stream<String> get logLines => const Stream<String>.empty();
14771468

14781469
@override
14791470
void dispose() { }
1471+
1472+
@override
1473+
Future<void> provideVmService(FlutterVmService connectedVmService) async {}
14801474
}
14811475

14821476
/// Append --null_assertions to any existing Dart VM flags if

packages/flutter_tools/lib/src/drive/drive_service.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,7 @@ class FlutterDriverService extends DriverService {
231231
_vmService = await _vmServiceConnector(uri, device: _device, logger: _logger);
232232
final DeviceLogReader logReader = await device.getLogReader(app: _applicationPackage);
233233
logReader.logLines.listen(_logger.printStatus);
234-
235-
final vm_service.VM vm = await _vmService.service.getVM();
236-
logReader.appPid = vm.pid;
234+
await logReader.provideVmService(_vmService);
237235
}
238236

239237
@override

packages/flutter_tools/lib/src/ios/devices.dart

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,16 +1300,12 @@ class IOSDeviceLogReader extends DeviceLogReader {
13001300
@override
13011301
Stream<String> get logLines => linesController.stream;
13021302

1303-
@override
1304-
FlutterVmService? get connectedVMService => _connectedVMService;
1305-
FlutterVmService? _connectedVMService;
1303+
FlutterVmService? _connectedVmService;
13061304

13071305
@override
1308-
set connectedVMService(FlutterVmService? connectedVmService) {
1309-
if (connectedVmService != null) {
1310-
_listenToUnifiedLoggingEvents(connectedVmService);
1311-
}
1312-
_connectedVMService = connectedVmService;
1306+
Future<void> provideVmService(FlutterVmService connectedVmService) async {
1307+
await _listenToUnifiedLoggingEvents(connectedVmService);
1308+
_connectedVmService = connectedVmService;
13131309
}
13141310

13151311
static const int minimumUniversalLoggingSdkVersion = 13;
@@ -1360,7 +1356,7 @@ class IOSDeviceLogReader extends DeviceLogReader {
13601356
// CoreDevice and has iOS 13 or greater.
13611357
// When using `ios-deploy` and the Dart VM, prefer the more complete logs
13621358
// from the attached debugger, if available.
1363-
if (connectedVMService != null && (_iosDeployDebugger == null || !_iosDeployDebugger!.debuggerAttached)) {
1359+
if (_connectedVmService != null && (_iosDeployDebugger == null || !_iosDeployDebugger!.debuggerAttached)) {
13641360
return _IOSDeviceLogSources(
13651361
primarySource: IOSDeviceLogSource.unifiedLogging,
13661362
fallbackSource: IOSDeviceLogSource.iosDeploy,

packages/flutter_tools/lib/src/ios/simulators.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import '../globals.dart' as globals;
2626
import '../macos/xcode.dart';
2727
import '../project.dart';
2828
import '../protocol_discovery.dart';
29+
import '../vmservice.dart';
2930
import 'application_package.dart';
3031
import 'mac.dart';
3132
import 'plist_parser.dart';
@@ -1022,6 +1023,9 @@ class _IOSSimulatorLogReader extends DeviceLogReader {
10221023
void dispose() {
10231024
_stop();
10241025
}
1026+
1027+
@override
1028+
Future<void> provideVmService(FlutterVmService connectedVmService) async { }
10251029
}
10261030

10271031
class _IOSSimulatorDevicePortForwarder extends DevicePortForwarder {

packages/flutter_tools/lib/src/proxied_devices/devices.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import '../device_port_forwarder.dart';
2020
import '../device_vm_service_discovery_for_attach.dart';
2121
import '../project.dart';
2222
import '../resident_runner.dart';
23+
import '../vmservice.dart';
2324
import 'debounce_data_stream.dart';
2425
import 'file_transfer.dart';
2526

@@ -517,6 +518,9 @@ class _ProxiedLogReader extends DeviceLogReader {
517518
});
518519
}
519520
}
521+
522+
@override
523+
Future<void> provideVmService(FlutterVmService connectedVmService) async { }
520524
}
521525

522526
/// A port forwarded by a [ProxiedPortForwarder].

packages/flutter_tools/lib/src/resident_runner.dart

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import 'package:meta/meta.dart';
88
import 'package:package_config/package_config.dart';
99
import 'package:vm_service/vm_service.dart' as vm_service;
1010

11-
import 'android/android_device.dart';
1211
import 'application_package.dart';
1312
import 'artifacts.dart';
1413
import 'asset.dart';
@@ -346,7 +345,8 @@ class FlutterDevice {
346345
globals.printTrace('Successfully connected to service protocol: $vmServiceUri');
347346

348347
vmService = service;
349-
(await device!.getLogReader(app: package)).connectedVMService = vmService;
348+
await (await device!.getLogReader(app: package))
349+
.provideVmService(vmService!);
350350
completer.complete();
351351
await subscription.cancel();
352352
}, onError: (dynamic error) {
@@ -417,24 +417,6 @@ class FlutterDevice {
417417
_loggingSubscription = null;
418418
}
419419

420-
/// Attempts to set up reading logs from the Flutter app on the device.
421-
///
422-
/// This can fail if the device if no longer connected.
423-
Future<void> tryInitLogReader() async {
424-
final vm_service.VM? vm = await vmService!.getVmGuarded();
425-
final DeviceLogReader logReader = await device!.getLogReader(app: package);
426-
if (vm == null && logReader is AdbLogReader) {
427-
// TODO(andrewkolos): This is a temporary, hacky fix for
428-
// https://github.com/flutter/flutter/issues/155795 that emphasizes
429-
// simplicity for the sake of being suitable for cherry-picking.
430-
globals.printError(
431-
'Unable to initiate adb log filtering for device'
432-
'${device?.name}. Logs from the device may be more verbose than usual.',
433-
);
434-
}
435-
logReader.appPid = vm?.pid;
436-
}
437-
438420
Future<int> runHot({
439421
required HotRunner hotRunner,
440422
String? route,

packages/flutter_tools/lib/src/run_cold.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ class ColdRunner extends ResidentRunner {
104104
if (device!.vmService == null) {
105105
continue;
106106
}
107-
await device.tryInitLogReader();
108107
globals.printTrace('Connected to ${device.device!.name}');
109108
}
110109

@@ -153,9 +152,6 @@ class ColdRunner extends ResidentRunner {
153152
return 2;
154153
}
155154

156-
for (final FlutterDevice? device in flutterDevices) {
157-
await device!.tryInitLogReader();
158-
}
159155
for (final FlutterDevice? device in flutterDevices) {
160156
final List<FlutterView> views = await device!.vmService!.getFlutterViews();
161157
for (final FlutterView view in views) {

0 commit comments

Comments
 (0)