blob: 9f35cfd30606d1254049670d14696da42ceb768d [file] [log] [blame]
// Copyright 2016 The Vanadium 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 'dart:async';
import 'dart:convert';
import 'dart:io';
import '../mobile/device.dart';
import '../mobile/device_spec.dart';
import '../globals.dart';
import '../util.dart';
Future<List<String>> getIOSDeviceIDs() async {
List<String> iosIDs = <String>[];
if (!os.isMacOS) {
return iosIDs;
}
Process process = await Process.start('mobiledevice', ['list_devices']);
RegExp iosIDPattern = new RegExp(r'^(.*)$');
Stream lineStream = process.stdout
.transform(new Utf8Decoder())
.transform(new LineSplitter());
await for (var line in lineStream) {
Match iosIDMatcher = iosIDPattern.firstMatch(line.toString());
if (iosIDMatcher != null) {
String iosID = iosIDMatcher.group(1);
iosIDs.add(iosID);
}
}
return iosIDs;
}
/// Uninstall an ios app
Future<int> uninstallIOSTestedApp(DeviceSpec spec, Device device) async {
String iosProjectProfilePath
= normalizePath(spec.appRootPath, 'ios/Runner.xcodeproj/project.pbxproj');
String iosProjectProfile = await new File(iosProjectProfilePath).readAsString();
RegExp packagePattern
= new RegExp(r'PRODUCT_BUNDLE_IDENTIFIER\s*=\s*(\S+?);', multiLine: true);
Match packageMatcher = packagePattern.firstMatch(iosProjectProfile);
if (packageMatcher == null) {
printError('Package name not found in $iosProjectProfilePath');
return 1;
}
String packageName = packageMatcher.group(1);
Process uninstallProcess = await Process.start(
'mobiledevice',
['uninstall_app', '-u', '${device.id}', '$packageName']
);
Stream lineStream = uninstallProcess.stdout
.transform(new Utf8Decoder())
.transform(new LineSplitter());
await for (var line in lineStream) {
printTrace(
'Uninstall $packageName on device ${device.id}: ${line.toString().trim()}'
);
}
uninstallProcess.stderr.drain();
return uninstallProcess.exitCode;
}
/// Get device property
Future<String> getIOSProperty(String deviceID, String propName) async {
ProcessResult results = await Process.run(
'mobiledevice',
['get_device_prop', '-u', deviceID, propName]
);
return results.stdout.toString().trim();
}
Future<Device> collectIOSDeviceProps(String deviceID, {String groupKey}) async {
String modelName = iosDeviceInfo['productId-to-modelName'][
await getIOSProperty(deviceID, 'ProductType')
];
num diagonalSize = iosDeviceInfo['modelName-to-screenSize'][modelName];
return new Device(
properties: <String, String> {
'platform': 'ios',
'device-id': deviceID,
'model-name': modelName,
'os-version': expandOSVersion(
await getIOSProperty(deviceID, 'ProductVersion')
),
'screen-size': categorizeScreenSize(diagonalSize)
},
groupKey: groupKey
);
}
// The information is based on https://www.theiphonewiki.com/wiki/Models
// For now, we only support iPhone and iPad (mini)
final dynamic iosDeviceInfo =
{
'productId-to-modelName': {
// iPhone
'iPhone1,1': 'iPhone',
'iPhone1,2': 'iPhone 3G',
'iPhone2,1': 'iPhone 3GS',
'iPhone3,1': 'iPhone 4',
'iPhone3,2': 'iPhone 4',
'iPhone3,3': 'iPhone 4',
'iPhone4,1': 'iPhone 4S',
'iPhone5,1': 'iPhone 5',
'iPhone5,2': 'iPhone 5',
'iPhone5,3': 'iPhone 5C',
'iPhone5,4': 'iPhone 5C',
'iPhone6,1': 'iPhone 5S',
'iPhone6,2': 'iPhone 5S',
'iPhone7,2': 'iPhone 6',
'iPhone7,1': 'iPhone 6 Plus',
'iPhone8,1': 'iPhone 6S',
'iPhone8,2': 'iPhone 6S Plus',
'iPhone8,4': 'iPhone SE',
// iPad and iPad mini
'iPad1,1': 'iPad',
'iPad2,1': 'iPad 2',
'iPad2,2': 'iPad 2',
'iPad2,3': 'iPad 2',
'iPad2,4': 'iPad 2',
'iPad3,1': 'iPad 3',
'iPad3,2': 'iPad 3',
'iPad3,3': 'iPad 3',
'iPad3,4': 'iPad 4',
'iPad3,5': 'iPad 4',
'iPad3,6': 'iPad 4',
'iPad4,1': 'iPad Air',
'iPad4,2': 'iPad Air',
'iPad4,3': 'iPad Air',
'iPad5,3': 'iPad Air 2',
'iPad5,4': 'iPad Air 2',
'iPad6,3': 'iPad Pro (9.7 inch)',
'iPad6,4': 'iPad Pro (9.7 inch)',
'iPad6,7': 'iPad Pro (12.9 inch)',
'iPad6,8': 'iPad Pro (12.9 inch)',
'iPad2,5': 'iPad mini',
'iPad2,6': 'iPad mini',
'iPad2,7': 'iPad mini',
'iPad4,4': 'iPad mini 2',
'iPad4,5': 'iPad mini 2',
'iPad4,6': 'iPad mini 2',
'iPad4,7': 'iPad mini 3',
'iPad4,8': 'iPad mini 3',
'iPad4,9': 'iPad mini 3',
'iPad5,1': 'iPad mini 4',
'iPad5,2': 'iPad mini 4'
},
'modelName-to-screenSize': {
// iPhone
'iPhone': 3.5,
'iPhone 3G': 3.5,
'iPhone 3GS': 3.5,
'iPhone 4': 3.5,
'iPhone 4S': 3.5,
'iPhone 5': 4,
'iPhone 5S': 4,
'iPhone 5C': 4,
'iPhone 6': 4.7,
'iPhone 6 Plus': 5.5,
'iPhone 6S': 4.7,
'iPhone 6S Plus': 5.5,
'iPhone SE': 4,
// iPad
'iPad': 9.7,
'iPad 2': 9.7,
'iPad 3': 9.7,
'iPad 4': 9.7,
'iPad Air': 9.7,
'iPad Air 2': 9.7,
'iPad Pro (9.7 inch)': 9.7,
'iPad Pro (12.9 inch)': 12.9,
'iPad mini': 7.9,
'iPad mini 2': 7.9,
'iPad mini 3': 7.9,
'iPad mini 4': 7.9
}
};