remove some references to DeviceStore
This commit is contained in:
parent
35c5494f19
commit
5ad6a57007
@ -29,6 +29,10 @@ abstract class ApplicationPackage {
|
|||||||
assert(localPath != null);
|
assert(localPath != null);
|
||||||
assert(id != null);
|
assert(id != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get displayName => name;
|
||||||
|
|
||||||
|
String toString() => displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AndroidApk extends ApplicationPackage {
|
class AndroidApk extends ApplicationPackage {
|
||||||
@ -99,6 +103,8 @@ class IOSApp extends ApplicationPackage {
|
|||||||
String projectDir = path.join("ios", ".generated");
|
String projectDir = path.join("ios", ".generated");
|
||||||
return new IOSApp(iosProjectDir: projectDir, iosProjectBundleId: value);
|
return new IOSApp(iosProjectDir: projectDir, iosProjectBundleId: value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get displayName => id;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ApplicationPackageStore {
|
class ApplicationPackageStore {
|
||||||
|
@ -422,14 +422,14 @@ Future<int> buildAndroid({
|
|||||||
// TODO(mpcomplete): move this to Device?
|
// TODO(mpcomplete): move this to Device?
|
||||||
/// This is currently Android specific.
|
/// This is currently Android specific.
|
||||||
Future<int> buildAll(
|
Future<int> buildAll(
|
||||||
DeviceStore devices,
|
List<Device> devices,
|
||||||
ApplicationPackageStore applicationPackages,
|
ApplicationPackageStore applicationPackages,
|
||||||
Toolchain toolchain,
|
Toolchain toolchain,
|
||||||
List<BuildConfiguration> configs, {
|
List<BuildConfiguration> configs, {
|
||||||
String enginePath,
|
String enginePath,
|
||||||
String target: ''
|
String target: ''
|
||||||
}) async {
|
}) async {
|
||||||
for (Device device in devices.all) {
|
for (Device device in devices) {
|
||||||
ApplicationPackage package = applicationPackages.getPackageForPlatform(device.platform);
|
ApplicationPackage package = applicationPackages.getPackageForPlatform(device.platform);
|
||||||
if (package == null)
|
if (package == null)
|
||||||
continue;
|
continue;
|
||||||
@ -438,14 +438,6 @@ Future<int> buildAll(
|
|||||||
if (package != applicationPackages.android)
|
if (package != applicationPackages.android)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// TODO(devoncarew): Remove this warning after a few releases.
|
|
||||||
if (FileSystemEntity.isDirectorySync('apk') && !FileSystemEntity.isDirectorySync('android')) {
|
|
||||||
// Tell people the android directory location changed.
|
|
||||||
printStatus(
|
|
||||||
"Warning: Flutter now looks for Android resources in the android/ directory; "
|
|
||||||
"consider renaming your 'apk/' directory to 'android/'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
int result = await build(toolchain, configs, enginePath: enginePath, target: target);
|
int result = await build(toolchain, configs, enginePath: enginePath, target: target);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return result;
|
return result;
|
||||||
|
@ -256,11 +256,11 @@ class AppDomain extends Domain {
|
|||||||
try {
|
try {
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
command.downloadToolchain(),
|
command.downloadToolchain(),
|
||||||
command.downloadApplicationPackagesAndConnectToDevices(),
|
command.downloadApplicationPackages(),
|
||||||
], eagerError: true);
|
], eagerError: true);
|
||||||
|
|
||||||
int result = await startApp(
|
int result = await startApp(
|
||||||
command.devices,
|
device,
|
||||||
command.applicationPackages,
|
command.applicationPackages,
|
||||||
command.toolchain,
|
command.toolchain,
|
||||||
command.buildConfigurations,
|
command.buildConfigurations,
|
||||||
|
@ -30,10 +30,8 @@ class DevicesCommand extends FlutterCommand {
|
|||||||
} else {
|
} else {
|
||||||
printStatus('${devices.length} connected ${pluralize('device', devices.length)}:\n');
|
printStatus('${devices.length} connected ${pluralize('device', devices.length)}:\n');
|
||||||
|
|
||||||
for (Device device in devices) {
|
for (Device device in devices)
|
||||||
String supportIndicator = device.isSupported() ? '' : ' - unsupported';
|
printStatus(device.fullDescription);
|
||||||
printStatus('${device.name} (${device.id})$supportIndicator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -315,6 +315,6 @@ Future<Null> downloadToolchain(DriveCommand command) async {
|
|||||||
printTrace('Downloading toolchain.');
|
printTrace('Downloading toolchain.');
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
command.downloadToolchain(),
|
command.downloadToolchain(),
|
||||||
command.downloadApplicationPackagesAndConnectToDevices(),
|
command.downloadApplicationPackages(),
|
||||||
], eagerError: true);
|
], eagerError: true);
|
||||||
}
|
}
|
||||||
|
@ -6,35 +6,34 @@ import 'dart:async';
|
|||||||
|
|
||||||
import '../application_package.dart';
|
import '../application_package.dart';
|
||||||
import '../device.dart';
|
import '../device.dart';
|
||||||
|
import '../globals.dart';
|
||||||
import '../runner/flutter_command.dart';
|
import '../runner/flutter_command.dart';
|
||||||
|
|
||||||
class InstallCommand extends FlutterCommand {
|
class InstallCommand extends FlutterCommand {
|
||||||
final String name = 'install';
|
final String name = 'install';
|
||||||
final String description = 'Install Flutter apps on attached devices.';
|
final String description = 'Install a Flutter app on an attached device.';
|
||||||
|
|
||||||
bool get requiresDevice => true;
|
bool get requiresDevice => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> runInProject() async {
|
Future<int> runInProject() async {
|
||||||
await downloadApplicationPackagesAndConnectToDevices();
|
await downloadApplicationPackages();
|
||||||
bool installedAny = await installApp(devices, applicationPackages);
|
|
||||||
return installedAny ? 0 : 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> installApp(
|
Device device = deviceForCommand;
|
||||||
DeviceStore devices,
|
|
||||||
ApplicationPackageStore applicationPackages
|
|
||||||
) async {
|
|
||||||
bool installedSomewhere = false;
|
|
||||||
|
|
||||||
for (Device device in devices.all) {
|
|
||||||
ApplicationPackage package = applicationPackages.getPackageForPlatform(device.platform);
|
ApplicationPackage package = applicationPackages.getPackageForPlatform(device.platform);
|
||||||
if (package == null || device.isAppInstalled(package))
|
|
||||||
continue;
|
|
||||||
if (device.installApp(package))
|
|
||||||
installedSomewhere = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return installedSomewhere;
|
printStatus('Installing $package to $device...');
|
||||||
|
|
||||||
|
return installApp(device, package) ? 0 : 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool installApp(Device device, ApplicationPackage package) {
|
||||||
|
if (package == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (device.isAppInstalled(package))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return device.installApp(package);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ class ListenCommand extends RunCommandBase {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> runInProject() async {
|
Future<int> runInProject() async {
|
||||||
await downloadApplicationPackagesAndConnectToDevices();
|
await downloadApplicationPackages();
|
||||||
await downloadToolchain();
|
await downloadToolchain();
|
||||||
|
|
||||||
List<String> watchCommand = _constructWatchCommand(() sync* {
|
List<String> watchCommand = _constructWatchCommand(() sync* {
|
||||||
@ -42,7 +42,7 @@ class ListenCommand extends RunCommandBase {
|
|||||||
do {
|
do {
|
||||||
printStatus('Updating running Flutter apps...');
|
printStatus('Updating running Flutter apps...');
|
||||||
result = await startApp(
|
result = await startApp(
|
||||||
devices,
|
deviceForCommand,
|
||||||
applicationPackages,
|
applicationPackages,
|
||||||
toolchain,
|
toolchain,
|
||||||
buildConfigurations,
|
buildConfigurations,
|
||||||
|
@ -25,50 +25,28 @@ class LogsCommand extends FlutterCommand {
|
|||||||
bool get requiresDevice => true;
|
bool get requiresDevice => true;
|
||||||
|
|
||||||
Future<int> runInProject() async {
|
Future<int> runInProject() async {
|
||||||
List<Device> devices = await deviceManager.getDevices();
|
Device device = deviceForCommand;
|
||||||
|
|
||||||
if (devices.isEmpty && deviceManager.hasSpecifiedDeviceId) {
|
if (argResults['clear'])
|
||||||
printError("No device found with id '${deviceManager.specifiedDeviceId}'.");
|
device.clearLogs();
|
||||||
return 1;
|
|
||||||
} else if (devices.isEmpty) {
|
|
||||||
printStatus('No connected devices.');
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clear = argResults['clear'];
|
DeviceLogReader logReader = device.logReader;
|
||||||
|
|
||||||
List<DeviceLogReader> readers = new List<DeviceLogReader>();
|
printStatus('Showing $logReader logs:');
|
||||||
for (Device device in devices) {
|
|
||||||
if (clear)
|
|
||||||
device.clearLogs();
|
|
||||||
|
|
||||||
readers.add(device.logReader);
|
// Start reading.
|
||||||
}
|
if (!logReader.isReading)
|
||||||
|
await logReader.start();
|
||||||
|
|
||||||
printStatus('Showing ${readers.join(', ')} logs:');
|
StreamSubscription subscription = logReader.lines.listen(printStatus);
|
||||||
|
|
||||||
List<int> results = await Future.wait(readers.map((DeviceLogReader reader) async {
|
// Wait for the log reader to be finished.
|
||||||
if (!reader.isReading) {
|
int result = await logReader.finished;
|
||||||
// Start reading.
|
|
||||||
await reader.start();
|
|
||||||
}
|
|
||||||
StreamSubscription subscription = reader.lines.listen((String line) {
|
|
||||||
if (devices.length > 1) {
|
|
||||||
// Prefix with the name of the device.
|
|
||||||
printStatus('[${reader.name}] $line');
|
|
||||||
} else {
|
|
||||||
printStatus(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Wait for the log reader to be finished.
|
|
||||||
int result = await reader.finished;
|
|
||||||
subscription.cancel();
|
|
||||||
if (result != 0)
|
|
||||||
printError('Error listening to $reader logs.');
|
|
||||||
return result;
|
|
||||||
}));
|
|
||||||
|
|
||||||
// If all readers failed, return an error.
|
subscription.cancel();
|
||||||
return results.every((int result) => result != 0) ? 1 : 0;
|
|
||||||
|
if (result != 0)
|
||||||
|
printError('Error listening to $logReader logs.');
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
import '../android/android_device.dart';
|
||||||
import '../globals.dart';
|
import '../globals.dart';
|
||||||
import '../runner/flutter_command.dart';
|
import '../runner/flutter_command.dart';
|
||||||
|
|
||||||
@ -28,14 +29,9 @@ class RefreshCommand extends FlutterCommand {
|
|||||||
|
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
downloadToolchain(),
|
downloadToolchain(),
|
||||||
downloadApplicationPackagesAndConnectToDevices(),
|
downloadApplicationPackages(),
|
||||||
], eagerError: true);
|
], eagerError: true);
|
||||||
|
|
||||||
if (devices.android == null) {
|
|
||||||
printError('No device connected.');
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Directory tempDir = await Directory.systemTemp.createTemp('flutter_tools');
|
Directory tempDir = await Directory.systemTemp.createTemp('flutter_tools');
|
||||||
try {
|
try {
|
||||||
String snapshotPath = path.join(tempDir.path, 'snapshot_blob.bin');
|
String snapshotPath = path.join(tempDir.path, 'snapshot_blob.bin');
|
||||||
@ -48,11 +44,13 @@ class RefreshCommand extends FlutterCommand {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = await devices.android.refreshSnapshot(
|
AndroidDevice device = deviceForCommand;
|
||||||
applicationPackages.android, snapshotPath
|
|
||||||
|
bool success = await device.refreshSnapshot(
|
||||||
|
applicationPackages.android, snapshotPath
|
||||||
);
|
);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
printError('Error refreshing snapshot on ${devices.android.name}.');
|
printError('Error refreshing snapshot on $device.');
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import 'package:path/path.dart' as path;
|
|||||||
|
|
||||||
import '../application_package.dart';
|
import '../application_package.dart';
|
||||||
import '../base/common.dart';
|
import '../base/common.dart';
|
||||||
import '../base/utils.dart';
|
|
||||||
import '../build_configuration.dart';
|
import '../build_configuration.dart';
|
||||||
import '../dart/pub.dart';
|
import '../dart/pub.dart';
|
||||||
import '../device.dart';
|
import '../device.dart';
|
||||||
@ -95,7 +94,7 @@ class RunCommand extends RunCommandBase {
|
|||||||
|
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
downloadToolchain(),
|
downloadToolchain(),
|
||||||
downloadApplicationPackagesAndConnectToDevices(),
|
downloadApplicationPackages(),
|
||||||
], eagerError: true);
|
], eagerError: true);
|
||||||
|
|
||||||
bool clearLogs = argResults['clear-logs'];
|
bool clearLogs = argResults['clear-logs'];
|
||||||
@ -109,9 +108,8 @@ class RunCommand extends RunCommandBase {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(devoncarew): Switch this to using [devicesForCommand].
|
|
||||||
int result = await startApp(
|
int result = await startApp(
|
||||||
devices,
|
deviceForCommand,
|
||||||
applicationPackages,
|
applicationPackages,
|
||||||
toolchain,
|
toolchain,
|
||||||
buildConfigurations,
|
buildConfigurations,
|
||||||
@ -132,7 +130,7 @@ class RunCommand extends RunCommandBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<int> startApp(
|
Future<int> startApp(
|
||||||
DeviceStore devices,
|
Device device,
|
||||||
ApplicationPackageStore applicationPackages,
|
ApplicationPackageStore applicationPackages,
|
||||||
Toolchain toolchain,
|
Toolchain toolchain,
|
||||||
List<BuildConfiguration> configs, {
|
List<BuildConfiguration> configs, {
|
||||||
@ -156,10 +154,17 @@ Future<int> startApp(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApplicationPackage package = applicationPackages.getPackageForPlatform(device.platform);
|
||||||
|
|
||||||
|
if (package == null) {
|
||||||
|
printError('No application found for ${device.platform}.');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (install) {
|
if (install) {
|
||||||
printTrace('Running build command.');
|
printTrace('Running build command.');
|
||||||
int result = await buildAll(
|
int result = await buildAll(
|
||||||
devices, applicationPackages, toolchain, configs,
|
<Device>[device], applicationPackages, toolchain, configs,
|
||||||
enginePath: enginePath,
|
enginePath: enginePath,
|
||||||
target: target
|
target: target
|
||||||
);
|
);
|
||||||
@ -172,16 +177,10 @@ Future<int> startApp(
|
|||||||
// plumb a Future through the start command from here, but that seems a little
|
// plumb a Future through the start command from here, but that seems a little
|
||||||
// messy.
|
// messy.
|
||||||
if (stop) {
|
if (stop) {
|
||||||
for (Device device in devices.all) {
|
if (package != null) {
|
||||||
if (!device.isSupported())
|
printTrace("Stopping app '${package.name}' on ${device.name}.");
|
||||||
continue;
|
// We don't wait for the stop command to complete.
|
||||||
|
device.stopApp(package);
|
||||||
ApplicationPackage package = applicationPackages.getPackageForPlatform(device.platform);
|
|
||||||
if (package != null) {
|
|
||||||
printTrace("Stopping app '${package.name}' on ${device.name}.");
|
|
||||||
// We don't wait for the stop command to complete.
|
|
||||||
device.stopApp(package);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,66 +189,42 @@ Future<int> startApp(
|
|||||||
|
|
||||||
if (install) {
|
if (install) {
|
||||||
printTrace('Running install command.');
|
printTrace('Running install command.');
|
||||||
|
|
||||||
// TODO(devoncarew): This fails for ios devices - we haven't built yet.
|
// TODO(devoncarew): This fails for ios devices - we haven't built yet.
|
||||||
await installApp(devices, applicationPackages);
|
await installApp(device, package);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool startedSomething = false;
|
bool startedSomething = false;
|
||||||
int unsupportedCount = 0;
|
|
||||||
|
|
||||||
for (Device device in devices.all) {
|
Map<String, dynamic> platformArgs = <String, dynamic>{};
|
||||||
ApplicationPackage package = applicationPackages.getPackageForPlatform(device.platform);
|
|
||||||
if (package == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!device.isSupported()) {
|
if (traceStartup != null)
|
||||||
printStatus("Skipping unsupported device '${device.name}'. ${device.supportMessage()}");
|
platformArgs['trace-startup'] = traceStartup;
|
||||||
unsupportedCount++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> platformArgs = <String, dynamic>{};
|
printStatus('Starting ${_getDisplayPath(mainPath)} on ${device.name}...');
|
||||||
|
|
||||||
if (traceStartup != null)
|
bool result = await device.startApp(
|
||||||
platformArgs['trace-startup'] = traceStartup;
|
package,
|
||||||
|
toolchain,
|
||||||
|
mainPath: mainPath,
|
||||||
|
route: route,
|
||||||
|
checked: checked,
|
||||||
|
clearLogs: clearLogs,
|
||||||
|
startPaused: startPaused,
|
||||||
|
debugPort: debugPort,
|
||||||
|
platformArgs: platformArgs
|
||||||
|
);
|
||||||
|
|
||||||
printStatus('Starting ${_getDisplayPath(mainPath)} on ${device.name}...');
|
if (!result) {
|
||||||
|
printError('Error starting application on ${device.name}.');
|
||||||
|
} else {
|
||||||
|
startedSomething = true;
|
||||||
|
|
||||||
bool result = await device.startApp(
|
// If the user specified --start-paused (and the device supports it) then
|
||||||
package,
|
// wait for the observatory port to become available before returning from
|
||||||
toolchain,
|
// `startApp()`.
|
||||||
mainPath: mainPath,
|
if (startPaused && device.supportsStartPaused)
|
||||||
route: route,
|
await delayUntilObservatoryAvailable('localhost', debugPort);
|
||||||
checked: checked,
|
|
||||||
clearLogs: clearLogs,
|
|
||||||
startPaused: startPaused,
|
|
||||||
debugPort: debugPort,
|
|
||||||
platformArgs: platformArgs
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
printError('Error starting application on ${device.name}.');
|
|
||||||
} else {
|
|
||||||
startedSomething = true;
|
|
||||||
|
|
||||||
// If the user specified --start-paused (and the device supports it) then
|
|
||||||
// wait for the observatory port to become available before returning from
|
|
||||||
// `startApp()`.
|
|
||||||
if (startPaused && device.supportsStartPaused)
|
|
||||||
await delayUntilObservatoryAvailable('localhost', debugPort);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!startedSomething) {
|
|
||||||
String message = 'Unable to run application';
|
|
||||||
|
|
||||||
if (devices.all.isEmpty) {
|
|
||||||
message += ' - no connected devices.';
|
|
||||||
} else if (unsupportedCount != 0) {
|
|
||||||
message += ' - $unsupportedCount unsupported ${pluralize('device', unsupportedCount)} connected';
|
|
||||||
}
|
|
||||||
|
|
||||||
printError(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return startedSomething ? 0 : 2;
|
return startedSomething ? 0 : 2;
|
||||||
|
@ -31,28 +31,24 @@ class TraceCommand extends FlutterCommand {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> runInProject() async {
|
Future<int> runInProject() async {
|
||||||
await downloadApplicationPackagesAndConnectToDevices();
|
await downloadApplicationPackages();
|
||||||
|
|
||||||
if (devices.android == null) {
|
|
||||||
printError('No device connected, so no trace was completed.');
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ApplicationPackage androidApp = applicationPackages.android;
|
ApplicationPackage androidApp = applicationPackages.android;
|
||||||
|
AndroidDevice device = deviceForCommand;
|
||||||
|
|
||||||
if ((!argResults['start'] && !argResults['stop']) ||
|
if ((!argResults['start'] && !argResults['stop']) ||
|
||||||
(argResults['start'] && argResults['stop'])) {
|
(argResults['start'] && argResults['stop'])) {
|
||||||
// Setting neither flags or both flags means do both commands and wait
|
// Setting neither flags or both flags means do both commands and wait
|
||||||
// duration seconds in between.
|
// duration seconds in between.
|
||||||
devices.android.startTracing(androidApp);
|
device.startTracing(androidApp);
|
||||||
await new Future.delayed(
|
await new Future.delayed(
|
||||||
new Duration(seconds: int.parse(argResults['duration'])),
|
new Duration(seconds: int.parse(argResults['duration'])),
|
||||||
() => _stopTracing(devices.android, androidApp)
|
() => _stopTracing(device, androidApp)
|
||||||
);
|
);
|
||||||
} else if (argResults['stop']) {
|
} else if (argResults['stop']) {
|
||||||
await _stopTracing(devices.android, androidApp);
|
await _stopTracing(device, androidApp);
|
||||||
} else {
|
} else {
|
||||||
devices.android.startTracing(androidApp);
|
device.startTracing(androidApp);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import 'application_package.dart';
|
|||||||
import 'base/common.dart';
|
import 'base/common.dart';
|
||||||
import 'base/utils.dart';
|
import 'base/utils.dart';
|
||||||
import 'build_configuration.dart';
|
import 'build_configuration.dart';
|
||||||
import 'globals.dart';
|
|
||||||
import 'ios/devices.dart';
|
import 'ios/devices.dart';
|
||||||
import 'ios/simulators.dart';
|
import 'ios/simulators.dart';
|
||||||
import 'toolchain.dart';
|
import 'toolchain.dart';
|
||||||
@ -39,10 +38,21 @@ class DeviceManager {
|
|||||||
Future<Device> getDeviceById(String deviceId) async {
|
Future<Device> getDeviceById(String deviceId) async {
|
||||||
deviceId = deviceId.toLowerCase();
|
deviceId = deviceId.toLowerCase();
|
||||||
List<Device> devices = await getAllConnectedDevices();
|
List<Device> devices = await getAllConnectedDevices();
|
||||||
return devices.firstWhere(
|
Device device = devices.firstWhere(
|
||||||
(Device device) => device.id.toLowerCase() == deviceId,
|
(Device device) => device.id.toLowerCase() == deviceId,
|
||||||
orElse: () => null
|
orElse: () => null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (device != null)
|
||||||
|
return device;
|
||||||
|
|
||||||
|
// Match on a close id / name.
|
||||||
|
devices = devices.where((Device device) {
|
||||||
|
return (device.id.toLowerCase().startsWith(deviceId) ||
|
||||||
|
device.name.toLowerCase().startsWith(deviceId));
|
||||||
|
});
|
||||||
|
|
||||||
|
return devices.length == 1 ? devices.first : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the list of connected devices, filtered by any user-specified device id.
|
/// Return the list of connected devices, filtered by any user-specified device id.
|
||||||
@ -130,6 +140,11 @@ abstract class Device {
|
|||||||
|
|
||||||
bool get supportsStartPaused => true;
|
bool get supportsStartPaused => true;
|
||||||
|
|
||||||
|
String get fullDescription {
|
||||||
|
String supportIndicator = isSupported() ? '' : ' - unsupported';
|
||||||
|
return '$name ($id)$supportIndicator';
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether it is an emulated device running on localhost.
|
/// Whether it is an emulated device running on localhost.
|
||||||
bool get isLocalEmulator;
|
bool get isLocalEmulator;
|
||||||
|
|
||||||
@ -186,7 +201,7 @@ abstract class Device {
|
|||||||
return id == other.id;
|
return id == other.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
String toString() => '$runtimeType $id';
|
String toString() => name;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ForwardedPort {
|
class ForwardedPort {
|
||||||
@ -241,77 +256,3 @@ abstract class DeviceLogReader {
|
|||||||
|
|
||||||
String toString() => name;
|
String toString() => name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(devoncarew): Unify this with [DeviceManager].
|
|
||||||
class DeviceStore {
|
|
||||||
DeviceStore({
|
|
||||||
this.android,
|
|
||||||
this.iOS,
|
|
||||||
this.iOSSimulator
|
|
||||||
});
|
|
||||||
|
|
||||||
factory DeviceStore.forConfigs(List<BuildConfiguration> configs) {
|
|
||||||
AndroidDevice android;
|
|
||||||
IOSDevice iOS;
|
|
||||||
IOSSimulator iOSSimulator;
|
|
||||||
|
|
||||||
for (BuildConfiguration config in configs) {
|
|
||||||
switch (config.targetPlatform) {
|
|
||||||
case TargetPlatform.android:
|
|
||||||
assert(android == null);
|
|
||||||
android = _deviceForConfig(config, getAdbDevices());
|
|
||||||
break;
|
|
||||||
case TargetPlatform.iOS:
|
|
||||||
assert(iOS == null);
|
|
||||||
iOS = _deviceForConfig(config, IOSDevice.getAttachedDevices());
|
|
||||||
break;
|
|
||||||
case TargetPlatform.iOSSimulator:
|
|
||||||
assert(iOSSimulator == null);
|
|
||||||
iOSSimulator = _deviceForConfig(config, IOSSimulatorUtils.instance.getAttachedDevices());
|
|
||||||
break;
|
|
||||||
case TargetPlatform.mac:
|
|
||||||
case TargetPlatform.linux:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DeviceStore(android: android, iOS: iOS, iOSSimulator: iOSSimulator);
|
|
||||||
}
|
|
||||||
|
|
||||||
final AndroidDevice android;
|
|
||||||
final IOSDevice iOS;
|
|
||||||
final IOSSimulator iOSSimulator;
|
|
||||||
|
|
||||||
List<Device> get all {
|
|
||||||
List<Device> result = <Device>[];
|
|
||||||
if (android != null)
|
|
||||||
result.add(android);
|
|
||||||
if (iOS != null)
|
|
||||||
result.add(iOS);
|
|
||||||
if (iOSSimulator != null)
|
|
||||||
result.add(iOSSimulator);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Device _deviceForConfig(BuildConfiguration config, List<Device> devices) {
|
|
||||||
Device device;
|
|
||||||
|
|
||||||
if (config.deviceId != null) {
|
|
||||||
// Step 1: If a device identifier is specified, try to find a device
|
|
||||||
// matching that specific identifier
|
|
||||||
device = devices.firstWhere(
|
|
||||||
(Device dev) => (dev.id == config.deviceId),
|
|
||||||
orElse: () => null);
|
|
||||||
} else if (devices.length == 1) {
|
|
||||||
// Step 2: If no identifier is specified and there is only one connected
|
|
||||||
// device, pick that one.
|
|
||||||
device = devices[0];
|
|
||||||
} else if (devices.length > 1) {
|
|
||||||
// Step 3: D:
|
|
||||||
printStatus('Multiple devices are connected, but no device ID was specified.');
|
|
||||||
printStatus('Attempting to launch on all connected devices.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -10,9 +10,9 @@ import 'package:args/command_runner.dart';
|
|||||||
import '../application_package.dart';
|
import '../application_package.dart';
|
||||||
import '../build_configuration.dart';
|
import '../build_configuration.dart';
|
||||||
import '../device.dart';
|
import '../device.dart';
|
||||||
|
import '../flx.dart' as flx;
|
||||||
import '../globals.dart';
|
import '../globals.dart';
|
||||||
import '../toolchain.dart';
|
import '../toolchain.dart';
|
||||||
import '../flx.dart' as flx;
|
|
||||||
import 'flutter_command_runner.dart';
|
import 'flutter_command_runner.dart';
|
||||||
|
|
||||||
typedef bool Validator();
|
typedef bool Validator();
|
||||||
@ -39,19 +39,10 @@ abstract class FlutterCommand extends Command {
|
|||||||
toolchain ??= await Toolchain.forConfigs(buildConfigurations);
|
toolchain ??= await Toolchain.forConfigs(buildConfigurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future downloadApplicationPackagesAndConnectToDevices() async {
|
|
||||||
await downloadApplicationPackages();
|
|
||||||
_connectToDevices();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future downloadApplicationPackages() async {
|
Future downloadApplicationPackages() async {
|
||||||
applicationPackages ??= await ApplicationPackageStore.forConfigs(buildConfigurations);
|
applicationPackages ??= await ApplicationPackageStore.forConfigs(buildConfigurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _connectToDevices() {
|
|
||||||
devices ??= new DeviceStore.forConfigs(buildConfigurations);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> run() {
|
Future<int> run() {
|
||||||
Stopwatch stopwatch = new Stopwatch()..start();
|
Stopwatch stopwatch = new Stopwatch()..start();
|
||||||
|
|
||||||
@ -91,13 +82,20 @@ abstract class FlutterCommand extends Command {
|
|||||||
if (androidOnly)
|
if (androidOnly)
|
||||||
devices = devices.where((Device device) => device.platform == TargetPlatform.android).toList();
|
devices = devices.where((Device device) => device.platform == TargetPlatform.android).toList();
|
||||||
|
|
||||||
// TODO(devoncarew): Switch this to just supporting one connected device?
|
|
||||||
if (devices.isEmpty) {
|
if (devices.isEmpty) {
|
||||||
printStatus('No supported devices connected.');
|
printStatus('No supported devices connected.');
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (devices.length > 1) {
|
||||||
|
printStatus("More than one device connected; please specify a device with "
|
||||||
|
"the '-d <deviceId>' flag.");
|
||||||
|
printStatus('');
|
||||||
|
devices = await deviceManager.getAllConnectedDevices();
|
||||||
|
for (Device device in devices)
|
||||||
|
printStatus(device.fullDescription);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
_deviceForCommand = devices.single;
|
||||||
}
|
}
|
||||||
|
|
||||||
_devicesForCommand = await _getDevicesForCommand();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await runInProject();
|
return await runInProject();
|
||||||
@ -116,38 +114,13 @@ abstract class FlutterCommand extends Command {
|
|||||||
|
|
||||||
Future<int> runInProject();
|
Future<int> runInProject();
|
||||||
|
|
||||||
List<Device> get devicesForCommand => _devicesForCommand;
|
|
||||||
|
|
||||||
Device get deviceForCommand {
|
|
||||||
// TODO(devoncarew): Switch this to just supporting one connected device?
|
|
||||||
return devicesForCommand.isNotEmpty ? devicesForCommand.first : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is caculated in run() if the command has [requiresDevice] specified.
|
// This is caculated in run() if the command has [requiresDevice] specified.
|
||||||
List<Device> _devicesForCommand;
|
Device _deviceForCommand;
|
||||||
|
|
||||||
|
Device get deviceForCommand => _deviceForCommand;
|
||||||
|
|
||||||
ApplicationPackageStore applicationPackages;
|
ApplicationPackageStore applicationPackages;
|
||||||
Toolchain toolchain;
|
Toolchain toolchain;
|
||||||
DeviceStore devices;
|
|
||||||
|
|
||||||
Future<List<Device>> _getDevicesForCommand() async {
|
|
||||||
List<Device> devices = await deviceManager.getDevices();
|
|
||||||
|
|
||||||
if (devices.isEmpty)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (deviceManager.hasSpecifiedDeviceId) {
|
|
||||||
Device device = await deviceManager.getDeviceById(deviceManager.specifiedDeviceId);
|
|
||||||
return device == null ? <Device>[] : <Device>[device];
|
|
||||||
}
|
|
||||||
|
|
||||||
devices = devices.where((Device device) => device.isSupported()).toList();
|
|
||||||
|
|
||||||
if (androidOnly)
|
|
||||||
devices = devices.where((Device device) => device.platform == TargetPlatform.android).toList();
|
|
||||||
|
|
||||||
return devices;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _targetSpecified = false;
|
bool _targetSpecified = false;
|
||||||
|
|
||||||
|
@ -15,18 +15,11 @@ void main() {
|
|||||||
testUsingContext('returns 0 when Android is connected and ready for an install', () {
|
testUsingContext('returns 0 when Android is connected and ready for an install', () {
|
||||||
InstallCommand command = new InstallCommand();
|
InstallCommand command = new InstallCommand();
|
||||||
applyMocksToCommand(command);
|
applyMocksToCommand(command);
|
||||||
MockDeviceStore mockDevices = command.devices;
|
|
||||||
|
|
||||||
when(mockDevices.android.isAppInstalled(any)).thenReturn(false);
|
MockAndroidDevice device = new MockAndroidDevice();
|
||||||
when(mockDevices.android.installApp(any)).thenReturn(true);
|
when(device.isAppInstalled(any)).thenReturn(false);
|
||||||
|
when(device.installApp(any)).thenReturn(true);
|
||||||
when(mockDevices.iOS.isAppInstalled(any)).thenReturn(false);
|
testDeviceManager.addDevice(device);
|
||||||
when(mockDevices.iOS.installApp(any)).thenReturn(false);
|
|
||||||
|
|
||||||
when(mockDevices.iOSSimulator.isAppInstalled(any)).thenReturn(false);
|
|
||||||
when(mockDevices.iOSSimulator.installApp(any)).thenReturn(false);
|
|
||||||
|
|
||||||
testDeviceManager.addDevice(mockDevices.android);
|
|
||||||
|
|
||||||
return createTestCommandRunner(command).run(['install']).then((int code) {
|
return createTestCommandRunner(command).run(['install']).then((int code) {
|
||||||
expect(code, equals(0));
|
expect(code, equals(0));
|
||||||
@ -36,18 +29,11 @@ void main() {
|
|||||||
testUsingContext('returns 0 when iOS is connected and ready for an install', () {
|
testUsingContext('returns 0 when iOS is connected and ready for an install', () {
|
||||||
InstallCommand command = new InstallCommand();
|
InstallCommand command = new InstallCommand();
|
||||||
applyMocksToCommand(command);
|
applyMocksToCommand(command);
|
||||||
MockDeviceStore mockDevices = command.devices;
|
|
||||||
|
|
||||||
when(mockDevices.android.isAppInstalled(any)).thenReturn(false);
|
MockIOSDevice device = new MockIOSDevice();
|
||||||
when(mockDevices.android.installApp(any)).thenReturn(false);
|
when(device.isAppInstalled(any)).thenReturn(false);
|
||||||
|
when(device.installApp(any)).thenReturn(true);
|
||||||
when(mockDevices.iOS.isAppInstalled(any)).thenReturn(false);
|
testDeviceManager.addDevice(device);
|
||||||
when(mockDevices.iOS.installApp(any)).thenReturn(true);
|
|
||||||
|
|
||||||
when(mockDevices.iOSSimulator.isAppInstalled(any)).thenReturn(false);
|
|
||||||
when(mockDevices.iOSSimulator.installApp(any)).thenReturn(false);
|
|
||||||
|
|
||||||
testDeviceManager.addDevice(mockDevices.iOS);
|
|
||||||
|
|
||||||
return createTestCommandRunner(command).run(['install']).then((int code) {
|
return createTestCommandRunner(command).run(['install']).then((int code) {
|
||||||
expect(code, equals(0));
|
expect(code, equals(0));
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_tools/src/android/android_device.dart';
|
import 'package:flutter_tools/src/android/android_device.dart';
|
||||||
import 'package:flutter_tools/src/application_package.dart';
|
import 'package:flutter_tools/src/application_package.dart';
|
||||||
import 'package:flutter_tools/src/build_configuration.dart';
|
import 'package:flutter_tools/src/build_configuration.dart';
|
||||||
@ -45,13 +46,6 @@ class MockIOSSimulator extends Mock implements IOSSimulator {
|
|||||||
bool isSupported() => true;
|
bool isSupported() => true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockDeviceStore extends DeviceStore {
|
|
||||||
MockDeviceStore() : super(
|
|
||||||
android: new MockAndroidDevice(),
|
|
||||||
iOS: new MockIOSDevice(),
|
|
||||||
iOSSimulator: new MockIOSSimulator());
|
|
||||||
}
|
|
||||||
|
|
||||||
class MockDeviceLogReader extends DeviceLogReader {
|
class MockDeviceLogReader extends DeviceLogReader {
|
||||||
String get name => 'MockLogReader';
|
String get name => 'MockLogReader';
|
||||||
|
|
||||||
@ -89,6 +83,5 @@ void applyMocksToCommand(FlutterCommand command) {
|
|||||||
command
|
command
|
||||||
..applicationPackages = new MockApplicationPackageStore()
|
..applicationPackages = new MockApplicationPackageStore()
|
||||||
..toolchain = new MockToolchain()
|
..toolchain = new MockToolchain()
|
||||||
..devices = new MockDeviceStore()
|
|
||||||
..projectRootValidator = () => true;
|
..projectRootValidator = () => true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user