Exemple #1
0
        public async Task LoadDevices(ILog log, bool includeLocked = false, bool forceRefresh = false, bool listExtraData = false)
        {
            await _semaphore.WaitAsync();

            if (_loaded)
            {
                if (!forceRefresh)
                {
                    _semaphore.Release();
                    return;
                }

                _supportedRuntimes.Reset();
                _supportedDeviceTypes.Reset();
                _availableDevices.Reset();
                _availableDevicePairs.Reset();
            }

            var tmpfile = Path.GetTempFileName();

            try
            {
                var arguments = new MlaunchArguments(
                    new ListSimulatorsArgument(tmpfile),
                    new XmlOutputFormatArgument());

                var result = await _processManager.ExecuteCommandAsync(arguments, log, timeout : TimeSpan.FromSeconds(30));

                if (!result.Succeeded)
                {
                    // mlaunch can sometimes return 0 but hang and timeout. It still outputs returns valid content to the tmp file
                    log.WriteLine($"mlaunch failed when listing simulators but trying to parse the results anyway");
                }

                var fileInfo = new FileInfo(tmpfile);
                if (!fileInfo.Exists || fileInfo.Length == 0)
                {
                    throw new Exception($"Failed to list simulators - no XML with devices found. " +
                                        $"mlaunch {(result.TimedOut ? "timed out" : "exited")} with {result.ExitCode})");
                }

                var xmlContent = File.ReadAllText(tmpfile);

                log.WriteLine("Simulator listing returned:" + Environment.NewLine + xmlContent);

                var simulatorData = new XmlDocument();
                simulatorData.LoadWithoutNetworkAccess(tmpfile);
                foreach (XmlNode?sim in simulatorData.SelectNodes("/MTouch/Simulator/SupportedRuntimes/SimRuntime"))
                {
                    if (sim == null)
                    {
                        continue;
                    }

                    _supportedRuntimes.Add(new SimRuntime(
                                               name: sim.SelectSingleNode("Name").InnerText,
                                               identifier: sim.SelectSingleNode("Identifier").InnerText,
                                               version: long.Parse(sim.SelectSingleNode("Version").InnerText)));
                }

                foreach (XmlNode?sim in simulatorData.SelectNodes("/MTouch/Simulator/SupportedDeviceTypes/SimDeviceType"))
                {
                    if (sim == null)
                    {
                        continue;
                    }

                    _supportedDeviceTypes.Add(new SimDeviceType(
                                                  name: sim.SelectSingleNode("Name").InnerText,
                                                  identifier: sim.SelectSingleNode("Identifier").InnerText,
                                                  productFamilyId: sim.SelectSingleNode("ProductFamilyId").InnerText,
                                                  minRuntimeVersion: long.Parse(sim.SelectSingleNode("MinRuntimeVersion").InnerText),
                                                  maxRuntimeVersion: long.Parse(sim.SelectSingleNode("MaxRuntimeVersion").InnerText),
                                                  supports64Bits: bool.Parse(sim.SelectSingleNode("Supports64Bits").InnerText)));
                }

                foreach (XmlNode?sim in simulatorData.SelectNodes("/MTouch/Simulator/AvailableDevices/SimDevice"))
                {
                    if (sim == null)
                    {
                        continue;
                    }

                    _availableDevices.Add(new SimulatorDevice(_processManager, new TCCDatabase(_processManager))
                    {
                        Name          = sim.Attributes["Name"].Value,
                        UDID          = sim.Attributes["UDID"].Value,
                        SimRuntime    = sim.SelectSingleNode("SimRuntime").InnerText,
                        SimDeviceType = sim.SelectSingleNode("SimDeviceType").InnerText,
                        DataPath      = sim.SelectSingleNode("DataPath").InnerText,
                        LogPath       = sim.SelectSingleNode("LogPath").InnerText,
                    });
                }

                var sim_device_pairs = simulatorData.
                                       SelectNodes("/MTouch/Simulator/AvailableDevicePairs/SimDevicePair").
                                       Cast <XmlNode>().
                                       // There can be duplicates, so remove those.
                                       Distinct(new SimulatorXmlNodeComparer());

                foreach (XmlNode sim in sim_device_pairs)
                {
                    _availableDevicePairs.Add(new SimDevicePair(
                                                  uDID: sim.Attributes["UDID"].Value,
                                                  companion: sim.SelectSingleNode("Companion").InnerText,
                                                  gizmo: sim.SelectSingleNode("Gizmo").InnerText));
                }
            }
            finally
            {
                _loaded = true;
                _supportedRuntimes.SetCompleted();
                _supportedDeviceTypes.SetCompleted();
                _availableDevices.SetCompleted();
                _availableDevicePairs.SetCompleted();
                File.Delete(tmpfile);
                _semaphore.Release();
            }
        }
        public async Task LoadDevices(ILog log, bool includeLocked = false, bool forceRefresh = false, bool listExtraData = false)
        {
            if (loaded)
            {
                if (!forceRefresh)
                {
                    return;
                }
                connectedDevices.Reset();
            }

            loaded = true;

            var tmpfile = Path.GetTempFileName();

            try {
                using (var process = new Process()) {
                    var arguments = new MlaunchArguments(
                        new ListDevicesArgument(tmpfile),
                        new XmlOutputFormatArgument());

                    if (listExtraData)
                    {
                        arguments.Add(new ListExtraDataArgument());
                    }

                    var task = processManager.RunAsync(process, arguments, log, timeout: TimeSpan.FromSeconds(120));
                    log.WriteLine("Launching {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);

                    var result = await task;

                    if (!result.Succeeded)
                    {
                        throw new Exception("Failed to list devices.");
                    }
                    log.WriteLine("Result:");
                    log.WriteLine(File.ReadAllText(tmpfile));
                    log.Flush();

                    var doc = new XmlDocument();
                    doc.LoadWithoutNetworkAccess(tmpfile);

                    foreach (XmlNode dev in doc.SelectNodes("/MTouch/Device"))
                    {
                        var d = GetDevice(dev);
                        if (d == null)
                        {
                            continue;
                        }
                        if (!includeLocked && d.IsLocked)
                        {
                            log.WriteLine($"Skipping device {d.Name} ({d.DeviceIdentifier}) because it's locked.");
                            continue;
                        }
                        if (d.IsUsableForDebugging.HasValue && !d.IsUsableForDebugging.Value)
                        {
                            log.WriteLine($"Skipping device {d.Name} ({d.DeviceIdentifier}) because it's not usable for debugging.");
                            continue;
                        }
                        connectedDevices.Add(d);
                    }
                }
            } finally {
                connectedDevices.SetCompleted();
                File.Delete(tmpfile);
                log.Flush();
            }
        }
        public async Task LoadAsync(ILog log, bool extra_data = false, bool removed_locked = false, bool force = false)
        {
            if (loaded)
            {
                if (!force)
                {
                    return;
                }
                connected_devices.Reset();
            }

            loaded = true;

            await Task.Run(async() => {
                var tmpfile = Path.GetTempFileName();
                try {
                    using (var process = new Process()) {
                        process.StartInfo.FileName = Harness.MlaunchPath;
                        var arguments = new MlaunchArguments(
                            (MlaunchArgumentType.SdkRoot, Harness.XcodeRoot),
                            (MlaunchArgumentType.ListDev, tmpfile),
                            (MlaunchArgumentType.OutputFormat, "xml")
                            );
                        if (extra_data)
                        {
                            arguments.Add(MlaunchArgumentType.ListExtraData);
                        }
                        log.WriteLine("Launching {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
                        var rv = await ProcessManager.RunAsync(process, arguments, log, timeout: TimeSpan.FromSeconds(120));
                        if (!rv.Succeeded)
                        {
                            throw new Exception("Failed to list devices.");
                        }
                        log.WriteLine("Result:");
                        log.WriteLine(File.ReadAllText(tmpfile));
                        log.Flush();

                        var doc = new XmlDocument();
                        doc.LoadWithoutNetworkAccess(tmpfile);

                        foreach (XmlNode dev in doc.SelectNodes("/MTouch/Device"))
                        {
                            var usable = dev.SelectSingleNode("IsUsableForDebugging")?.InnerText;
                            Device d   = new Device {
                                DeviceIdentifier    = dev.SelectSingleNode("DeviceIdentifier")?.InnerText,
                                DeviceClass         = dev.SelectSingleNode("DeviceClass")?.InnerText,
                                CompanionIdentifier = dev.SelectSingleNode("CompanionIdentifier")?.InnerText,
                                Name                 = dev.SelectSingleNode("Name")?.InnerText,
                                BuildVersion         = dev.SelectSingleNode("BuildVersion")?.InnerText,
                                ProductVersion       = dev.SelectSingleNode("ProductVersion")?.InnerText,
                                ProductType          = dev.SelectSingleNode("ProductType")?.InnerText,
                                InterfaceType        = dev.SelectSingleNode("InterfaceType")?.InnerText,
                                IsUsableForDebugging = usable == null ? (bool?)null : ((bool?)(usable == "True")),
                            };
                            bool.TryParse(dev.SelectSingleNode("IsLocked")?.InnerText, out var locked);
                            d.IsLocked = locked;
                            if (removed_locked && d.IsLocked)
                            {
                                log.WriteLine($"Skipping device {d.Name} ({d.DeviceIdentifier}) because it's locked.");
                                continue;
                            }
                            if (d.IsUsableForDebugging.HasValue && !d.IsUsableForDebugging.Value)
                            {
                                log.WriteLine($"Skipping device {d.Name} ({d.DeviceIdentifier}) because it's not usable for debugging.");
                                continue;
                            }
                            connected_devices.Add(d);
                        }
                    }
                } finally {
                    connected_devices.SetCompleted();
                    File.Delete(tmpfile);
                    log.Flush();
                }
            });
        }