1// Copyright 2018 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5import '../application_package.dart'; 6import '../base/io.dart'; 7import '../base/os.dart'; 8import '../base/platform.dart'; 9import '../base/process_manager.dart'; 10import '../build_info.dart'; 11import '../desktop.dart'; 12import '../device.dart'; 13import '../globals.dart'; 14import '../project.dart'; 15import '../protocol_discovery.dart'; 16import 'application_package.dart'; 17import 'build_linux.dart'; 18import 'linux_workflow.dart'; 19 20/// A device that represents a desktop Linux target. 21class LinuxDevice extends Device { 22 LinuxDevice() : super( 23 'Linux', 24 category: Category.desktop, 25 platformType: PlatformType.linux, 26 ephemeral: false, 27 ); 28 29 @override 30 void clearLogs() { } 31 32 @override 33 DeviceLogReader getLogReader({ ApplicationPackage app }) { 34 return _logReader; 35 } 36 final DesktopLogReader _logReader = DesktopLogReader(); 37 38 // Since the host and target devices are the same, no work needs to be done 39 // to install the application. 40 @override 41 Future<bool> installApp(ApplicationPackage app) async => true; 42 43 // Since the host and target devices are the same, no work needs to be done 44 // to install the application. 45 @override 46 Future<bool> isAppInstalled(ApplicationPackage app) async => true; 47 48 // Since the host and target devices are the same, no work needs to be done 49 // to install the application. 50 @override 51 Future<bool> isLatestBuildInstalled(ApplicationPackage app) async => true; 52 53 @override 54 Future<bool> get isLocalEmulator async => false; 55 56 @override 57 Future<String> get emulatorId async => null; 58 59 @override 60 bool isSupported() => true; 61 62 @override 63 String get name => 'Linux'; 64 65 @override 66 DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder(); 67 68 @override 69 Future<String> get sdkNameAndVersion async => os.name; 70 71 @override 72 Future<LaunchResult> startApp( 73 covariant LinuxApp package, { 74 String mainPath, 75 String route, 76 DebuggingOptions debuggingOptions, 77 Map<String, dynamic> platformArgs, 78 bool prebuiltApplication = false, 79 bool usesTerminalUi = true, 80 bool ipv6 = false, 81 }) async { 82 _lastBuiltMode = debuggingOptions.buildInfo.mode; 83 if (!prebuiltApplication) { 84 await buildLinux( 85 FlutterProject.current().linux, 86 debuggingOptions.buildInfo, 87 target: mainPath, 88 ); 89 } 90 await stopApp(package); 91 final Process process = await processManager.start(<String>[ 92 package.executable(debuggingOptions?.buildInfo?.mode) 93 ]); 94 if (debuggingOptions?.buildInfo?.isRelease == true) { 95 return LaunchResult.succeeded(); 96 } 97 _logReader.initializeProcess(process); 98 final ProtocolDiscovery observatoryDiscovery = ProtocolDiscovery.observatory(_logReader); 99 try { 100 final Uri observatoryUri = await observatoryDiscovery.uri; 101 return LaunchResult.succeeded(observatoryUri: observatoryUri); 102 } catch (error) { 103 printError('Error waiting for a debug connection: $error'); 104 return LaunchResult.failed(); 105 } finally { 106 await observatoryDiscovery.cancel(); 107 } 108 } 109 110 @override 111 Future<bool> stopApp(covariant LinuxApp app) async { 112 return killProcess(app.executable(_lastBuiltMode)); 113 } 114 115 @override 116 Future<TargetPlatform> get targetPlatform async => TargetPlatform.linux_x64; 117 118 // Since the host and target devices are the same, no work needs to be done 119 // to uninstall the application. 120 @override 121 Future<bool> uninstallApp(ApplicationPackage app) async => true; 122 123 @override 124 bool isSupportedForProject(FlutterProject flutterProject) { 125 return flutterProject.linux.existsSync(); 126 } 127 128 // Track the last built mode from startApp. 129 BuildMode _lastBuiltMode; 130} 131 132class LinuxDevices extends PollingDeviceDiscovery { 133 LinuxDevices() : super('linux devices'); 134 135 @override 136 bool get supportsPlatform => platform.isLinux; 137 138 @override 139 bool get canListAnything => linuxWorkflow.canListDevices; 140 141 @override 142 Future<List<Device>> pollingGetDevices() async { 143 if (!canListAnything) { 144 return const <Device>[]; 145 } 146 return <Device>[ 147 LinuxDevice(), 148 ]; 149 } 150 151 @override 152 Future<List<String>> getDiagnostics() async => const <String>[]; 153} 154