Unverified Commit c584a5ea authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Migrate fuchsia_device to null safety (#95438)

parent 38cffc9c
......@@ -2,10 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:meta/meta.dart';
import '../artifacts.dart';
import '../asset.dart';
import '../base/common.dart';
......@@ -45,12 +41,13 @@ Future<void> _validateCmxFile(FuchsiaProject fuchsiaProject) async {
// 3. Using these manifests, use the Fuchsia SDK 'pm' tool to create the
// Fuchsia package.
Future<void> buildFuchsia({
@required FuchsiaProject fuchsiaProject,
@required TargetPlatform targetPlatform,
@required String target, // E.g., lib/main.dart
required FuchsiaProject fuchsiaProject,
required TargetPlatform targetPlatform,
String? target, // E.g., lib/main.dart
BuildInfo buildInfo = BuildInfo.debug,
String runnerPackageSource = FuchsiaPackageServer.toolHost,
}) async {
final String targetPath = target ??= 'lib/main.dart';
await _validateCmxFile(fuchsiaProject);
final Directory outDir = globals.fs.directory(getFuchsiaBuildDirectory());
if (!outDir.existsSync()) {
......@@ -58,18 +55,18 @@ Future<void> buildFuchsia({
}
await _timedBuildStep('fuchsia-kernel-compile',
() => fuchsiaSdk.fuchsiaKernelCompiler.build(
fuchsiaProject: fuchsiaProject, target: target, buildInfo: buildInfo));
() => fuchsiaSdk!.fuchsiaKernelCompiler.build(
fuchsiaProject: fuchsiaProject, target: targetPath, buildInfo: buildInfo));
if (buildInfo.usesAot) {
await _timedBuildStep('fuchsia-gen-snapshot',
() => _genSnapshot(fuchsiaProject, target, buildInfo, targetPlatform));
() => _genSnapshot(fuchsiaProject, targetPath, buildInfo, targetPlatform));
}
await _timedBuildStep('fuchsia-build-assets',
() => _buildAssets(fuchsiaProject, target, buildInfo));
() => _buildAssets(fuchsiaProject, targetPath, buildInfo));
await _timedBuildStep('fuchsia-build-package',
() => _buildPackage(fuchsiaProject, target, buildInfo, runnerPackageSource));
() => _buildPackage(fuchsiaProject, targetPath, buildInfo, runnerPackageSource));
}
Future<void> _genSnapshot(
......@@ -84,7 +81,7 @@ Future<void> _genSnapshot(
final String elf = globals.fs.path.join(outDir, 'elf.aotsnapshot');
final String genSnapshot = globals.artifacts.getArtifactPath(
final String genSnapshot = globals.artifacts!.getArtifactPath(
Artifact.genSnapshot,
platform: targetPlatform,
mode: buildInfo.mode,
......@@ -118,7 +115,7 @@ Future<void> _buildAssets(
BuildInfo buildInfo,
) async {
final String assetDir = getAssetBuildDirectory();
final AssetBundle assets = await buildAssets(
final AssetBundle? assets = await buildAssets(
manifestPath: fuchsiaProject.project.pubspecFile.path,
packagesPath: fuchsiaProject.project.packagesFile.path,
assetDirPath: assetDir,
......@@ -148,7 +145,7 @@ Future<void> _buildAssets(
}
void _rewriteCmx(BuildMode mode, String runnerPackageSource, File src, File dst) {
final Map<String, dynamic> cmx = castStringKeyedMap(json.decode(src.readAsStringSync()));
final Map<String, Object?> cmx = castStringKeyedMap(json.decode(src.readAsStringSync())) ?? <String, Object?>{};
// If the app author has already specified the runner in the cmx file, then
// do not override it with something else.
if (cmx.containsKey('runner')) {
......@@ -171,7 +168,6 @@ void _rewriteCmx(BuildMode mode, String runnerPackageSource, File src, File dst)
break;
default:
throwToolExit('Fuchsia does not support build mode "$mode"');
break;
}
cmx['runner'] = 'fuchsia-pkg://$runnerPackageSource/$runner#meta/$runner.cmx';
dst.writeAsStringSync(json.encode(cmx));
......@@ -218,7 +214,10 @@ Future<void> _buildPackage(
manifestFile.writeAsStringSync('meta/package=$pkgDir/meta/package\n',
mode: FileMode.append);
final FuchsiaPM fuchsiaPM = fuchsiaSdk.fuchsiaPM;
final FuchsiaPM? fuchsiaPM = fuchsiaSdk?.fuchsiaPM;
if (fuchsiaPM == null) {
return;
}
if (!await fuchsiaPM.init(pkgDir, appName)) {
return;
}
......
......@@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'package:meta/meta.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
import '../application_package.dart';
import '../artifacts.dart';
......@@ -36,19 +35,13 @@ import 'session_control.dart';
import 'tiles_ctl.dart';
/// The [FuchsiaDeviceTools] instance.
FuchsiaDeviceTools get fuchsiaDeviceTools => context.get<FuchsiaDeviceTools>();
FuchsiaDeviceTools get fuchsiaDeviceTools => context.get<FuchsiaDeviceTools>()!;
/// Fuchsia device-side tools.
class FuchsiaDeviceTools {
FuchsiaPkgctl _pkgctl;
FuchsiaPkgctl get pkgctl => _pkgctl ??= FuchsiaPkgctl();
FuchsiaTilesCtl _tilesCtl;
FuchsiaTilesCtl get tilesCtl => _tilesCtl ??= FuchsiaTilesCtl();
FuchsiaSessionControl _sessionControl;
FuchsiaSessionControl get sessionControl =>
_sessionControl ??= FuchsiaSessionControl();
late final FuchsiaPkgctl pkgctl = FuchsiaPkgctl();
late final FuchsiaTilesCtl tilesCtl = FuchsiaTilesCtl();
late final FuchsiaSessionControl sessionControl = FuchsiaSessionControl();
}
final String _ipv4Loopback = InternetAddress.loopbackIPv4.address;
......@@ -81,21 +74,21 @@ class _FuchsiaLogReader extends DeviceLogReader {
static final RegExp _flutterLogOutput = RegExp(r'INFO: \S+\(flutter\): ');
final FuchsiaDevice _device;
final ApplicationPackage _app;
final ApplicationPackage? _app;
final SystemClock _systemClock;
@override
String get name => _device.name;
Stream<String> _logLines;
Stream<String>? _logLines;
@override
Stream<String> get logLines {
final Stream<String> logStream = fuchsiaSdk.syslogs(_device.id);
final Stream<String>? logStream = fuchsiaSdk?.syslogs(_device.id);
_logLines ??= _processLogs(logStream);
return _logLines;
return _logLines ?? const Stream<String>.empty();
}
Stream<String> _processLogs(Stream<String> lines) {
Stream<String>? _processLogs(Stream<String>? lines) {
if (lines == null) {
return null;
}
......@@ -104,9 +97,10 @@ class _FuchsiaLogReader extends DeviceLogReader {
final DateTime startTime = _systemClock.now();
// Determine if line comes from flutter, and optionally whether it matches
// the correct fuchsia module.
final RegExp matchRegExp = _app == null
final ApplicationPackage? app = _app;
final RegExp matchRegExp = app == null
? _flutterLogOutput
: RegExp('INFO: ${_app.name}(\\.cmx)?\\(flutter\\): ');
: RegExp('INFO: ${app.name}(\\.cmx)?\\(flutter\\): ');
return Stream<String>.eventTransformed(
lines,
(EventSink<String> output) => _FuchsiaLogSink(output, matchRegExp, startTime),
......@@ -136,7 +130,7 @@ class _FuchsiaLogSink implements EventSink<String> {
if (!_matchRegExp.hasMatch(line)) {
return;
}
final String rawDate = _utcDateOutput.firstMatch(line)?.group(0);
final String? rawDate = _utcDateOutput.firstMatch(line)?.group(0);
if (rawDate == null) {
return;
}
......@@ -149,7 +143,7 @@ class _FuchsiaLogSink implements EventSink<String> {
}
@override
void addError(Object error, [StackTrace stackTrace]) {
void addError(Object error, [StackTrace? stackTrace]) {
_outputSink.addError(error, stackTrace);
}
......@@ -162,10 +156,10 @@ class _FuchsiaLogSink implements EventSink<String> {
/// Device discovery for Fuchsia devices.
class FuchsiaDevices extends PollingDeviceDiscovery {
FuchsiaDevices({
@required Platform platform,
@required FuchsiaWorkflow fuchsiaWorkflow,
@required FuchsiaSdk fuchsiaSdk,
@required Logger logger,
required Platform platform,
required FuchsiaWorkflow fuchsiaWorkflow,
required FuchsiaSdk fuchsiaSdk,
required Logger logger,
}) : _platform = platform,
_fuchsiaWorkflow = fuchsiaWorkflow,
_fuchsiaSdk = fuchsiaSdk,
......@@ -184,12 +178,12 @@ class FuchsiaDevices extends PollingDeviceDiscovery {
bool get canListAnything => _fuchsiaWorkflow.canListDevices;
@override
Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
Future<List<Device>> pollingGetDevices({ Duration? timeout }) async {
if (!_fuchsiaWorkflow.canListDevices) {
return <Device>[];
}
// TODO(omerlevran): Remove once soft transition is complete fxb/67602.
final List<String> text = (await _fuchsiaSdk.listDevices(
final List<String>? text = (await _fuchsiaSdk.listDevices(
timeout: timeout,
))?.split('\n');
if (text == null || text.isEmpty) {
......@@ -197,7 +191,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery {
}
final List<FuchsiaDevice> devices = <FuchsiaDevice>[];
for (final String line in text) {
final FuchsiaDevice device = await _parseDevice(line);
final FuchsiaDevice? device = await _parseDevice(line);
if (device == null) {
continue;
}
......@@ -209,7 +203,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery {
@override
Future<List<String>> getDiagnostics() async => const <String>[];
Future<FuchsiaDevice> _parseDevice(String text) async {
Future<FuchsiaDevice?> _parseDevice(String text) async {
final String line = text.trim();
// ['ip', 'device name']
final List<String> words = line.split(' ');
......@@ -219,7 +213,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery {
final String name = words[1];
// TODO(omerlevran): Add support for resolve on the FuchsiaSdk Object.
final String resolvedHost = await _fuchsiaSdk.fuchsiaFfx.resolve(name);
final String? resolvedHost = await _fuchsiaSdk.fuchsiaFfx.resolve(name);
if (resolvedHost == null) {
_logger.printError('Failed to resolve host for Fuchsia device `$name`');
return null;
......@@ -233,7 +227,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery {
class FuchsiaDevice extends Device {
FuchsiaDevice(String id, {this.name}) : super(
FuchsiaDevice(String id, {required this.name}) : super(
id,
platformType: PlatformType.fuchsia,
category: null,
......@@ -256,14 +250,12 @@ class FuchsiaDevice extends Device {
Future<bool> get isLocalEmulator async => false;
@override
Future<String> get emulatorId async => null;
Future<String?> get emulatorId async => null;
@override
bool get supportsStartPaused => false;
bool _isSession;
Future<bool> get isSession async => _isSession ??= await _initIsSession();
late final Future<bool> isSession = _initIsSession();
/// Determine if the Fuchsia device is running a session based build.
///
......@@ -280,7 +272,7 @@ class FuchsiaDevice extends Device {
@override
Future<bool> isAppInstalled(
ApplicationPackage app, {
String userIdentifier,
String? userIdentifier,
}) async => false;
@override
......@@ -289,13 +281,13 @@ class FuchsiaDevice extends Device {
@override
Future<bool> installApp(
ApplicationPackage app, {
String userIdentifier,
String? userIdentifier,
}) => Future<bool>.value(false);
@override
Future<bool> uninstallApp(
ApplicationPackage app, {
String userIdentifier,
String? userIdentifier,
}) async => false;
@override
......@@ -307,13 +299,13 @@ class FuchsiaDevice extends Device {
@override
Future<LaunchResult> startApp(
covariant FuchsiaApp package, {
String mainPath,
String route,
DebuggingOptions debuggingOptions,
Map<String, dynamic> platformArgs,
String? mainPath,
String? route,
required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object?>{},
bool prebuiltApplication = false,
bool ipv6 = false,
String userIdentifier,
String? userIdentifier,
}) async {
if (await isSession) {
globals.printTrace('Running on a session framework based build.');
......@@ -356,7 +348,7 @@ class FuchsiaDevice extends Device {
final Status status = globals.logger.startProgress(
'Starting Fuchsia application $appName...',
);
FuchsiaPackageServer fuchsiaPackageServer;
FuchsiaPackageServer? fuchsiaPackageServer;
bool serverRegistered = false;
String fuchsiaUrl;
try {
......@@ -379,7 +371,7 @@ class FuchsiaDevice extends Device {
// Serve the flutter_runner.
final File flutterRunnerArchive =
globals.fs.file(globals.artifacts.getArtifactPath(
globals.fs.file(globals.artifacts!.getArtifactPath(
Artifact.fuchsiaFlutterRunner,
platform: await targetPlatform,
mode: debuggingOptions.buildInfo.mode,
......@@ -455,7 +447,7 @@ class FuchsiaDevice extends Device {
} finally {
// Try to un-teach the package controller about the package server if
// needed.
if (serverRegistered) {
if (serverRegistered && fuchsiaPackageServer != null) {
await fuchsiaDeviceTools.pkgctl.rmRepo(this, fuchsiaPackageServer);
}
// Shutdown the package server and delete the package repo;
......@@ -493,7 +485,7 @@ class FuchsiaDevice extends Device {
@override
Future<bool> stopApp(
covariant FuchsiaApp app, {
String userIdentifier,
String? userIdentifier,
}) async {
if (await isSession) {
// Currently there are no way to close a running app programmatically
......@@ -510,11 +502,9 @@ class FuchsiaDevice extends Device {
return true;
}
TargetPlatform _targetPlatform;
Future<TargetPlatform> _queryTargetPlatform() async {
const TargetPlatform defaultTargetPlatform = TargetPlatform.fuchsia_arm64;
if (!globals.fuchsiaArtifacts.hasSshConfig) {
if (!globals.fuchsiaArtifacts!.hasSshConfig) {
globals.printTrace('Could not determine Fuchsia target platform because '
'Fuchsia ssh configuration is missing.\n'
'Defaulting to arm64.');
......@@ -574,12 +564,12 @@ class FuchsiaDevice extends Device {
}
@override
Future<TargetPlatform> get targetPlatform async => _targetPlatform ??= await _queryTargetPlatform();
late final Future<TargetPlatform> targetPlatform = _queryTargetPlatform();
@override
Future<String> get sdkNameAndVersion async {
const String defaultName = 'Fuchsia';
if (!globals.fuchsiaArtifacts.hasSshConfig) {
if (!globals.fuchsiaArtifacts!.hasSshConfig) {
globals.printTrace('Could not determine Fuchsia sdk name or version '
'because Fuchsia ssh configuration is missing.');
return defaultName;
......@@ -600,18 +590,18 @@ class FuchsiaDevice extends Device {
@override
DeviceLogReader getLogReader({
ApplicationPackage app,
ApplicationPackage? app,
bool includePastLogs = false,
}) {
assert(!includePastLogs, 'Past log reading not supported on Fuchsia.');
return _logReader ??= _FuchsiaLogReader(this, globals.systemClock, app);
}
_FuchsiaLogReader _logReader;
_FuchsiaLogReader? _logReader;
@override
DevicePortForwarder get portForwarder =>
_portForwarder ??= _FuchsiaPortForwarder(this);
DevicePortForwarder _portForwarder;
DevicePortForwarder? _portForwarder;
@visibleForTesting
set portForwarder(DevicePortForwarder forwarder) {
......@@ -621,17 +611,12 @@ class FuchsiaDevice extends Device {
@override
void clearLogs() {}
bool _ipv6;
/// [true] if the current host address is IPv6.
bool get ipv6 => _ipv6 ??= isIPv6Address(id);
late final bool ipv6 = isIPv6Address(id);
/// Return the address that the device should use to communicate with the
/// host.
Future<String> get hostAddress async {
if (_cachedHostAddress != null) {
return _cachedHostAddress;
}
late final Future<String> hostAddress = () async {
final RunResult result = await shell(r'echo $SSH_CONNECTION');
void fail() {
throwToolExit('Failed to get local address, aborting.\n$result');
......@@ -647,10 +632,8 @@ class FuchsiaDevice extends Device {
if (addr.isEmpty) {
fail();
}
return _cachedHostAddress = addr;
}
String _cachedHostAddress;
return addr;
}();
/// List the ports currently running a dart observatory.
Future<List<int>> servicePorts() async {
......@@ -679,7 +662,7 @@ class FuchsiaDevice extends Device {
if (line == '') {
continue;
}
final int port = int.tryParse(line);
final int? port = int.tryParse(line);
if (port != null) {
ports.add(port);
}
......@@ -690,14 +673,15 @@ class FuchsiaDevice extends Device {
/// Run `command` on the Fuchsia device shell.
Future<RunResult> shell(String command) async {
if (globals.fuchsiaArtifacts.sshConfig == null) {
final File? sshConfig = globals.fuchsiaArtifacts?.sshConfig;
if (sshConfig == null) {
throwToolExit('Cannot interact with device. No ssh config.\n'
'Try setting FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR.');
}
return globals.processUtils.run(<String>[
'ssh',
'-F',
globals.fuchsiaArtifacts.sshConfig.absolute.path,
sshConfig.absolute.path,
id, // Device's IP address.
command,
]);
......@@ -705,14 +689,15 @@ class FuchsiaDevice extends Device {
/// Transfer the file [origin] from the device to [destination].
Future<RunResult> scp(String origin, String destination) async {
if (globals.fuchsiaArtifacts.sshConfig == null) {
final File? sshConfig = globals.fuchsiaArtifacts!.sshConfig;
if (sshConfig == null) {
throwToolExit('Cannot interact with device. No ssh config.\n'
'Try setting FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR.');
}
return globals.processUtils.run(<String>[
'scp',
'-F',
globals.fuchsiaArtifacts.sshConfig.absolute.path,
sshConfig.absolute.path,
'$id:$origin',
destination,
]);
......@@ -733,11 +718,13 @@ class FuchsiaDevice extends Device {
final FlutterVmService vmService = await connectToVmService(uri, logger: globals.logger);
final List<FlutterView> flutterViews = await vmService.getFlutterViews();
for (final FlutterView flutterView in flutterViews) {
if (flutterView.uiIsolate == null) {
final vm_service.IsolateRef? uiIsolate = flutterView.uiIsolate;
if (uiIsolate == null) {
continue;
}
if (flutterView.uiIsolate.name.contains(isolateName)) {
return vmService.httpAddress.port;
final int? port = vmService.httpAddress?.port;
if (port != null && uiIsolate.name?.contains(isolateName) == true) {
return port;
}
}
} on SocketException catch (err) {
......@@ -780,12 +767,12 @@ class FuchsiaIsolateDiscoveryProtocol {
final Future<void> Function(Device, Uri, bool) _ddsStarter;
// whether to only poll once.
final bool _pollOnce;
Timer _pollingTimer;
Status _status;
Timer? _pollingTimer;
Status? _status;
FutureOr<Uri> get uri {
if (_uri != null) {
return _uri;
return _uri!;
}
_status ??= globals.logger.startProgress(
'Waiting for a connection from $_isolateName on ${_device.name}...',
......@@ -797,7 +784,7 @@ class FuchsiaIsolateDiscoveryProtocol {
});
}
Uri _uri;
Uri? _uri;
void dispose() {
if (!_foundUri.isCompleted) {
......@@ -812,7 +799,7 @@ class FuchsiaIsolateDiscoveryProtocol {
Future<void> _findIsolate() async {
final List<int> ports = await _device.servicePorts();
for (final int port in ports) {
FlutterVmService service;
FlutterVmService? service;
if (_ports.containsKey(port)) {
service = _ports[port];
} else {
......@@ -820,30 +807,32 @@ class FuchsiaIsolateDiscoveryProtocol {
try {
final Uri uri = Uri.parse('http://[$_ipv6Loopback]:$localPort');
await _ddsStarter(_device, uri, true);
service = await _vmServiceConnector(_device.dds.uri);
service = await _vmServiceConnector(_device.dds.uri!);
_ports[port] = service;
} on SocketException catch (err) {
globals.printTrace('Failed to connect to $localPort: $err');
continue;
}
}
final List<FlutterView> flutterViews = await service.getFlutterViews();
final List<FlutterView> flutterViews = await service?.getFlutterViews() ?? <FlutterView>[];
for (final FlutterView flutterView in flutterViews) {
if (flutterView.uiIsolate == null) {
final vm_service.IsolateRef? uiIsolate = flutterView.uiIsolate;
if (uiIsolate == null) {
continue;
}
if (flutterView.uiIsolate.name.contains(_isolateName)) {
final int? port = service?.httpAddress?.port;
if (port != null && uiIsolate.name?.contains(_isolateName) == true) {
_foundUri.complete(_device.ipv6
? Uri.parse('http://[$_ipv6Loopback]:${service.httpAddress.port}/')
: Uri.parse('http://$_ipv4Loopback:${service.httpAddress.port}/'));
_status.stop();
? Uri.parse('http://[$_ipv6Loopback]:$port/')
: Uri.parse('http://$_ipv4Loopback:$port/'));
_status?.stop();
return;
}
}
}
if (_pollOnce) {
_foundUri.completeError(Exception('Max iterations exceeded'));
_status.stop();
_status?.stop();
return;
}
_pollingTimer = Timer(_pollDuration, _findIsolate);
......@@ -857,18 +846,23 @@ class _FuchsiaPortForwarder extends DevicePortForwarder {
final Map<int, Process> _processes = <int, Process>{};
@override
Future<int> forward(int devicePort, {int hostPort}) async {
Future<int> forward(int devicePort, {int? hostPort}) async {
hostPort ??= await globals.os.findFreePort();
if (hostPort == 0) {
throwToolExit('Failed to forward port $devicePort. No free host-side ports');
}
final File? sshConfig = globals.fuchsiaArtifacts?.sshConfig;
if (sshConfig == null) {
throwToolExit('Cannot interact with device. No ssh config.\n'
'Try setting FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR.');
}
// Note: the provided command works around a bug in -N, see US-515
// for more explanation.
final List<String> command = <String>[
'ssh',
'-6',
'-F',
globals.fuchsiaArtifacts.sshConfig.absolute.path,
sshConfig.absolute.path,
'-nNT',
'-vvv',
'-f',
......@@ -895,12 +889,17 @@ class _FuchsiaPortForwarder extends DevicePortForwarder {
@override
Future<void> unforward(ForwardedPort forwardedPort) async {
_forwardedPorts.remove(forwardedPort);
final Process process = _processes.remove(forwardedPort.hostPort);
final Process? process = _processes.remove(forwardedPort.hostPort);
process?.kill();
final File? sshConfig = globals.fuchsiaArtifacts?.sshConfig;
if (sshConfig == null) {
// Nothing to cancel.
return;
}
final List<String> command = <String>[
'ssh',
'-F',
globals.fuchsiaArtifacts.sshConfig.absolute.path,
sshConfig.absolute.path,
'-O',
'cancel',
'-vvv',
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import '../base/process.dart';
import 'fuchsia_device.dart';
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import '../base/process.dart';
import 'fuchsia_device.dart';
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import '../base/process.dart';
import '../globals.dart' as globals;
......@@ -23,7 +21,7 @@ class FuchsiaTilesCtl {
/// found.
static Future<int> findAppKey(FuchsiaDevice device, String appName) async {
final FuchsiaTilesCtl tilesCtl = fuchsiaDeviceTools.tilesCtl;
final Map<int, String> runningApps = await tilesCtl.list(device);
final Map<int, String>? runningApps = await tilesCtl.list(device);
if (runningApps == null) {
globals.printTrace('tiles_ctl is not running');
return -1;
......@@ -39,7 +37,7 @@ class FuchsiaTilesCtl {
/// Ensures that tiles is running on the device.
static Future<bool> ensureStarted(FuchsiaDevice device) async {
final FuchsiaTilesCtl tilesCtl = fuchsiaDeviceTools.tilesCtl;
final Map<int, String> runningApps = await tilesCtl.list(device);
final Map<int, String>? runningApps = await tilesCtl.list(device);
if (runningApps == null) {
return tilesCtl.start(device);
}
......@@ -58,7 +56,7 @@ class FuchsiaTilesCtl {
///
/// Returns an empty mapping if tiles_ctl is running but no apps are running.
/// Returns null if tiles_ctl is not running.
Future<Map<int, String>> list(FuchsiaDevice device) async {
Future<Map<int, String>?> list(FuchsiaDevice device) async {
// Output of tiles_ctl list has the format:
// Found 1 tiles:
// Tile key 1 url fuchsia-pkg://fuchsia.com/stocks#meta/stocks.cmx ...
......@@ -75,9 +73,11 @@ class FuchsiaTilesCtl {
for (final String line in result.stdout.split('\n')) {
final List<String> words = line.split(' ');
if (words.isNotEmpty && words[0] == 'Tile') {
final int key = int.tryParse(words[2]);
final String url = words[4];
tiles[key] = url;
final int? key = int.tryParse(words[2]);
if (key != null) {
final String url = words[4];
tiles[key] = url;
}
}
}
return tiles;
......
......@@ -91,7 +91,7 @@ void main() {
final FakeFuchsiaWorkflow fuchsiaWorkflow = FakeFuchsiaWorkflow(canListDevices: false);
final FuchsiaDevices fuchsiaDevices = FuchsiaDevices(
platform: FakePlatform(),
fuchsiaSdk: null,
fuchsiaSdk: FakeFuchsiaSdk(devices: 'ignored'),
fuchsiaWorkflow: fuchsiaWorkflow,
logger: BufferLogger.test(),
);
......@@ -154,7 +154,7 @@ void main() {
testUsingContext('disposing device disposes the portForwarder', () async {
final FakePortForwarder portForwarder = FakePortForwarder();
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
device.portForwarder = portForwarder;
await device.dispose();
......@@ -162,7 +162,7 @@ void main() {
});
testWithoutContext('default capabilities', () async {
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory);
memoryFileSystem.directory('fuchsia').createSync(recursive: true);
memoryFileSystem.file('pubspec.yaml').createSync();
......@@ -174,13 +174,13 @@ void main() {
});
test('is ephemeral', () {
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(device.ephemeral, true);
});
testWithoutContext('supported for project', () async {
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory);
memoryFileSystem.directory('fuchsia').createSync(recursive: true);
memoryFileSystem.file('pubspec.yaml').createSync();
......@@ -189,7 +189,7 @@ void main() {
});
testWithoutContext('not supported for project', () async {
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory);
memoryFileSystem.file('pubspec.yaml').createSync();
......@@ -197,7 +197,7 @@ void main() {
});
testUsingContext('targetPlatform does not throw when sshConfig is missing', () async {
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64);
}, overrides: <Type, Generator>{
......@@ -212,7 +212,7 @@ void main() {
stdout: 'aarch64',
));
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64);
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
......@@ -226,7 +226,7 @@ void main() {
stdout: 'x86_64',
));
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.targetPlatform, TargetPlatform.fuchsia_x64);
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
......@@ -240,7 +240,7 @@ void main() {
stdout: 'fe80::8c6c:2fff:fe3d:c5e1%ethp0003 50666 fe80::5054:ff:fe63:5e7a%ethp0003 22',
));
final FuchsiaDevice device = FuchsiaDevice('id');
final FuchsiaDevice device = FuchsiaDevice('id', name: 'device');
expect(await device.hostAddress, 'fe80::8c6c:2fff:fe3d:c5e1%25ethp0003');
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
......@@ -254,7 +254,7 @@ void main() {
exitCode: 1,
));
final FuchsiaDevice device = FuchsiaDevice('id');
final FuchsiaDevice device = FuchsiaDevice('id', name: 'device');
await expectLater(() => device.hostAddress, throwsToolExit());
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
......@@ -267,7 +267,7 @@ void main() {
command: <String>['ssh', '-F', '/ssh_config', 'id', r'echo $SSH_CONNECTION'],
));
final FuchsiaDevice device = FuchsiaDevice('id');
final FuchsiaDevice device = FuchsiaDevice('id', name: 'device');
expect(() async => device.hostAddress, throwsToolExit());
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
......@@ -289,7 +289,7 @@ void main() {
processManager.addCommand(const FakeCommand(
command: <String>['ssh', '-F', '/artifact', 'id', 'find /hub -name vmservice-port'],
));
final FuchsiaDevice device = FuchsiaDevice('id');
final FuchsiaDevice device = FuchsiaDevice('id', name: 'device');
await expectLater(device.servicePorts, throwsToolExit(message: 'No Dart Observatories found. Are you running a debug build?'));
}, overrides: <Type, Generator>{
......@@ -766,7 +766,7 @@ void main() {
});
testUsingContext('does not throw on non-existent ssh config', () async {
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.sdkNameAndVersion, equals('Fuchsia'));
}, overrides: <Type, Generator>{
......@@ -780,7 +780,7 @@ void main() {
command: <String>['ssh', '-F', '/ssh_config', '123', 'cat /pkgfs/packages/build-info/0/data/version'],
stdout: 'version'
));
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.sdkNameAndVersion, equals('Fuchsia version'));
}, overrides: <Type, Generator>{
......@@ -794,7 +794,7 @@ void main() {
command: <String>['ssh', '-F', '/ssh_config', '123', 'cat /pkgfs/packages/build-info/0/data/version'],
exitCode: 1,
));
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.sdkNameAndVersion, equals('Fuchsia'));
}, overrides: <Type, Generator>{
......@@ -807,7 +807,7 @@ void main() {
processManager.addCommand(const FakeCommand(
command: <String>['ssh', '-F', '/ssh_config', '123', 'cat /pkgfs/packages/build-info/0/data/version'],
));
final FuchsiaDevice device = FuchsiaDevice('123');
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.sdkNameAndVersion, equals('Fuchsia'));
}, overrides: <Type, Generator>{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment