1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2014 The Flutter 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:args/args.dart';
import '../base/common.dart';
import '../base/utils.dart';
import '../doctor_validator.dart';
import '../emulator.dart';
import '../globals.dart' as globals;
import '../runner/flutter_command.dart';
class EmulatorsCommand extends FlutterCommand {
EmulatorsCommand() {
argParser.addOption('launch',
help: 'The full or partial ID of the emulator to launch.');
argParser.addFlag('cold',
help: 'Used with the "--launch" flag to cold boot the emulator instance (Android only).',
negatable: false);
argParser.addFlag('create',
help: 'Creates a new Android emulator based on a Pixel device.',
negatable: false);
argParser.addOption('name',
help: 'Used with the "--create" flag. Specifies a name for the emulator being created.');
}
@override
final String name = 'emulators';
@override
final String description = 'List, launch and create emulators.';
@override
final String category = FlutterCommandCategory.tools;
@override
final List<String> aliases = <String>['emulator'];
@override
Future<FlutterCommandResult> runCommand() async {
if (globals.doctor!.workflows.every((Workflow w) => !w.canListEmulators)) {
throwToolExit(
'Unable to find any emulator sources. Please ensure you have some\n'
'Android AVD images ${globals.platform.isMacOS ? 'or an iOS Simulator ' : ''}available.',
exitCode: 1);
}
final ArgResults argumentResults = argResults!;
if (argumentResults.wasParsed('launch')) {
final bool coldBoot = argumentResults.wasParsed('cold');
await _launchEmulator(stringArg('launch')!, coldBoot: coldBoot);
} else if (argumentResults.wasParsed('create')) {
await _createEmulator(name: stringArg('name'));
} else {
final String? searchText =
argumentResults.rest != null && argumentResults.rest.isNotEmpty
? argumentResults.rest.first
: null;
await _listEmulators(searchText);
}
return FlutterCommandResult.success();
}
Future<void> _launchEmulator(String id, { required bool coldBoot }) async {
final List<Emulator> emulators =
await emulatorManager!.getEmulatorsMatching(id);
if (emulators.isEmpty) {
globals.printStatus("No emulator found that matches '$id'.");
} else if (emulators.length > 1) {
_printEmulatorList(
emulators,
"More than one emulator matches '$id':",
);
} else {
await emulators.first.launch(coldBoot: coldBoot);
}
}
Future<void> _createEmulator({ String? name }) async {
final CreateEmulatorResult createResult =
await emulatorManager!.createEmulator(name: name);
if (createResult.success) {
globals.printStatus("Emulator '${createResult.emulatorName}' created successfully.");
} else {
globals.printStatus("Failed to create emulator '${createResult.emulatorName}'.\n");
final String? error = createResult.error;
if (error != null) {
globals.printStatus(error.trim());
}
_printAdditionalInfo();
}
}
Future<void> _listEmulators(String? searchText) async {
final List<Emulator> emulators = searchText == null
? await emulatorManager!.getAllAvailableEmulators()
: await emulatorManager!.getEmulatorsMatching(searchText);
if (emulators.isEmpty) {
globals.printStatus('No emulators available.');
_printAdditionalInfo(showCreateInstruction: true);
} else {
_printEmulatorList(
emulators,
'${emulators.length} available ${pluralize('emulator', emulators.length)}:',
);
}
}
void _printEmulatorList(List<Emulator> emulators, String message) {
globals.printStatus('$message\n');
Emulator.printEmulators(emulators, globals.logger);
_printAdditionalInfo(showCreateInstruction: true, showRunInstruction: true);
}
void _printAdditionalInfo({
bool showRunInstruction = false,
bool showCreateInstruction = false,
}) {
globals.printStatus('');
if (showRunInstruction) {
globals.printStatus(
"To run an emulator, run 'flutter emulators --launch <emulator id>'.");
}
if (showCreateInstruction) {
globals.printStatus(
"To create a new emulator, run 'flutter emulators --create [--name xyz]'.");
}
if (showRunInstruction || showCreateInstruction) {
globals.printStatus('');
}
// TODO(dantup): Update this link to flutter.dev if/when we have a better page.
// That page can then link out to these places if required.
globals.printStatus('You can find more information on managing emulators at the links below:\n'
' https://developer.android.com/studio/run/managing-avds\n'
' https://developer.android.com/studio/command-line/avdmanager');
}
}