async Task <bool> CreateDevicePair(ILog log, ISimulatorDevice device, ISimulatorDevice companion_device, string runtime, string devicetype, bool create_device) { if (create_device) { // watch device is already paired to some other phone. Create a new watch device var matchingDevices = await FindOrCreateDevicesAsync(log, runtime, devicetype, force : true); var unPairedDevices = matchingDevices.Where((v) => !AvailableDevicePairs.Any((SimDevicePair p) => { return(p.Gizmo == v.UDID); })); if (device != null) { // If we're creating a new watch device, assume that the one we were given is not usable. unPairedDevices = unPairedDevices.Where((v) => v.UDID != device.UDID); } if (unPairedDevices?.Any() != true) { return(false); } device = unPairedDevices.First(); } log.WriteLine($"Creating device pair for '{device.Name}' and '{companion_device.Name}'"); var capturedLog = new StringBuilder(); var pairLog = new CallbackLog((string value) => { log.WriteImpl(value); capturedLog.Append(value); }); var rv = await Harness.ExecuteXcodeCommandAsync("simctl", new [] { "pair", device.UDID, companion_device.UDID }, pairLog, TimeSpan.FromMinutes(1)); if (!rv.Succeeded) { if (!create_device) { var try_creating_device = false; var captured_log = capturedLog.ToString(); try_creating_device |= captured_log.Contains("At least one of the requested devices is already paired with the maximum number of supported devices and cannot accept another pairing."); try_creating_device |= captured_log.Contains("The selected devices are already paired with each other."); if (try_creating_device) { log.WriteLine($"Could not create device pair for '{device.Name}' ({device.UDID}) and '{companion_device.Name}' ({companion_device.UDID}), but will create a new watch device and try again."); return(await CreateDevicePair(log, device, companion_device, runtime, devicetype, true)); } } log.WriteLine($"Could not create device pair for '{device.Name}' ({device.UDID}) and '{companion_device.Name}' ({companion_device.UDID})"); return(false); } return(true); }
// Will return all devices that match the runtime + devicetype (even if a new device was created, any other devices will also be returned) async Task <IEnumerable <ISimulatorDevice> > FindOrCreateDevicesAsync(ILog log, string runtime, string devicetype, bool force = false) { if (runtime == null || devicetype == null) { return(null); } IEnumerable <ISimulatorDevice> devices = null; if (!force) { devices = AvailableDevices.Where((SimDevice v) => v.SimRuntime == runtime && v.SimDeviceType == devicetype); if (devices.Any()) { return(devices); } } var rv = await Harness.ExecuteXcodeCommandAsync("simctl", new [] { "create", CreateName(devicetype, runtime), devicetype, runtime }, log, TimeSpan.FromMinutes(1)); if (!rv.Succeeded) { log.WriteLine($"Could not create device for runtime={runtime} and device type={devicetype}."); return(null); } await LoadAsync(log, force : true); devices = AvailableDevices.Where((ISimulatorDevice v) => v.SimRuntime == runtime && v.SimDeviceType == devicetype); if (!devices.Any()) { log.WriteLine($"No devices loaded after creating it? runtime={runtime} device type={devicetype}."); return(null); } return(devices); }