Re-enable use of instruments for iOS device lookup (#10838)
This reverts commit b2909a245a607995ce7ec286585cd1f643124f57.
This resubmits the following patches:
1. Use Xcode instruments to list devices (#10801)
Eliminates the dependency on idevice_id from libimobiledevice. Instead,
uses Xcode built-in functionality.
2. Make device discovery asynchronous (#10803)
Migrates DeviceDiscovery.devices and all device-specific lookup to be
asynchronous.
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index bb3eca7..1cc5c96 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -36,11 +36,11 @@
bool get canListAnything => iosWorkflow.canListDevices;
@override
- List<Device> pollingGetDevices() => IOSDevice.getAttachedDevices();
+ Future<List<Device>> pollingGetDevices() => IOSDevice.getAttachedDevices();
}
class IOSDevice extends Device {
- IOSDevice(String id, { this.name }) : super(id) {
+ IOSDevice(String id, { this.name, String sdkVersion }) : _sdkVersion = sdkVersion, super(id) {
_installerPath = _checkForCommand('ideviceinstaller');
_iproxyPath = _checkForCommand('iproxy');
_pusherPath = _checkForCommand(
@@ -55,6 +55,8 @@
String _iproxyPath;
String _pusherPath;
+ final String _sdkVersion;
+
@override
bool get supportsHotMode => true;
@@ -71,14 +73,30 @@
@override
bool get supportsStartPaused => false;
- static List<IOSDevice> getAttachedDevices() {
- if (!iMobileDevice.isInstalled)
+ // Physical device line format to be matched:
+ // My iPhone (10.3.2) [75b90e947c5f429fa67f3e9169fda0d89f0492f1]
+ //
+ // Other formats in output (desktop, simulator) to be ignored:
+ // my-mac-pro [2C10513E-4dA5-405C-8EF5-C44353DB3ADD]
+ // iPhone 6s (9.3) [F6CEE7CF-81EB-4448-81B4-1755288C7C11] (Simulator)
+ static final RegExp _deviceRegex = new RegExp(r'^(.*) +\((.*)\) +\[(.*)\]$');
+
+ static Future<List<IOSDevice>> getAttachedDevices() async {
+ if (!xcode.isInstalled)
return <IOSDevice>[];
final List<IOSDevice> devices = <IOSDevice>[];
- for (String id in iMobileDevice.getAttachedDeviceIDs()) {
- final String name = iMobileDevice.getInfoForDevice(id, 'DeviceName');
- devices.add(new IOSDevice(id, name: name));
+ final Iterable<String> deviceLines = (await xcode.getAvailableDevices())
+ .split('\n')
+ .map((String line) => line.trim());
+ for (String line in deviceLines) {
+ final Match match = _deviceRegex.firstMatch(line);
+ if (match != null) {
+ final String deviceName = match.group(1);
+ final String sdkVersion = match.group(2);
+ final String deviceID = match.group(3);
+ devices.add(new IOSDevice(deviceID, name: deviceName, sdkVersion: sdkVersion));
+ }
}
return devices;
}
@@ -311,11 +329,7 @@
Future<TargetPlatform> get targetPlatform async => TargetPlatform.ios;
@override
- Future<String> get sdkNameAndVersion async => 'iOS $_sdkVersion ($_buildVersion)';
-
- String get _sdkVersion => iMobileDevice.getInfoForDevice(id, 'ProductVersion');
-
- String get _buildVersion => iMobileDevice.getInfoForDevice(id, 'BuildVersion');
+ Future<String> get sdkNameAndVersion async => 'iOS $_sdkVersion';
@override
DeviceLogReader getLogReader({ApplicationPackage app}) {
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 7d1bfa6..1b1317e 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -70,14 +70,6 @@
return await exitsHappyAsync(<String>['idevicename']);
}
- List<String> getAttachedDeviceIDs() {
- return runSync(<String>['idevice_id', '-l'])
- .trim()
- .split('\n')
- .where((String line) => line.isNotEmpty)
- .toList();
- }
-
/// Returns the value associated with the specified `ideviceinfo` key for a device.
///
/// If either the specified key or device does not exist, returns the empty string.
@@ -165,6 +157,13 @@
return _xcodeVersionCheckValid(_xcodeMajorVersion, _xcodeMinorVersion);
}
+
+ Future<String> getAvailableDevices() async {
+ final RunResult result = await runAsync(<String>['/usr/bin/instruments', '-s', 'devices']);
+ if (result.exitCode != 0)
+ throw new ToolExit('Failed to invoke /usr/bin/instruments. Is Xcode installed?');
+ return result.stdout;
+ }
}
bool _xcodeVersionCheckValid(int major, int minor) {
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index 697be3b..92788c6 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -37,7 +37,7 @@
bool get canListAnything => iosWorkflow.canListDevices;
@override
- List<Device> pollingGetDevices() => IOSSimulatorUtils.instance.getAttachedDevices();
+ Future<List<Device>> pollingGetDevices() async => IOSSimulatorUtils.instance.getAttachedDevices();
}
class IOSSimulatorUtils {