예제 #1
0
        public override Task <DiagnosticResult> Examine(SharedState history)
        {
            AndroidSdk.AvdManager avdManager = null;

            var    javaHome = history.GetEnvironmentVariable("JAVA_HOME");
            string java     = null;

            if (!string.IsNullOrEmpty(javaHome) && Directory.Exists(javaHome))
            {
                java = Path.Combine(javaHome, "bin", "java" + (Util.IsWindows ? ".exe" : ""));
            }

            var avds = new List <AndroidSdk.AvdManager.Avd>();

            // Try invoking the java avdmanager library first
            if (File.Exists(java))
            {
                avdManager = new AndroidSdk.AvdManager(java,
                                                       history.GetEnvironmentVariable("ANDROID_SDK_ROOT") ?? history.GetEnvironmentVariable("ANDROID_HOME"));
                avds.AddRange(avdManager.ListAvds());
            }

            // Fallback to manually reading the avd files
            if (!avds.Any())
            {
                avds.AddRange(AndroidSdk.AvdManager.ListAvdsFromFiles());
            }

            if (avds.Any())
            {
                var emu = avds.FirstOrDefault();

                ReportStatus($"Emulator: {emu.Name ?? emu.SdkId} found.", Status.Ok);

                return(Task.FromResult(DiagnosticResult.Ok(this)));
            }

            // If we got here, there are no emulators at all
            var missingEmulators = RequiredEmulators;

            if (!missingEmulators.Any())
            {
                return(Task.FromResult(DiagnosticResult.Ok(this)));
            }

            AndroidSdk.AvdManager.AvdDevice preferredDevice = null;

            try
            {
                if (avdManager != null)
                {
                    var devices = avdManager.ListDevices();

                    preferredDevice = devices.FirstOrDefault(d => d.Name.Contains("pixel", StringComparison.OrdinalIgnoreCase));
                }
            }
            catch (Exception ex)
            {
                var msg = "Unable to find any Android Emulators.  You can use Visual Studio to create one if necessary: [underline]https://docs.microsoft.com/xamarin/android/get-started/installation/android-emulator/device-manager[/]";

                ReportStatus(msg, Status.Warning);

                Util.Exception(ex);
                return(Task.FromResult(
                           new DiagnosticResult(Status.Warning, this, msg)));
            }

            return(Task.FromResult(new DiagnosticResult(
                                       Status.Error,
                                       this,
                                       new Suggestion("Create an Android Emulator",
                                                      missingEmulators.Select(me =>
                                                                              new ActionSolution((sln, cancel) =>
            {
                try
                {
                    var installer = new AndroidSDKInstaller(new Helper(), AndroidManifestType.GoogleV2);
                    installer.Discover();

                    var sdkInstance = installer.FindInstance(null);

                    var installedPackages = sdkInstance.Components.AllInstalled(true);

                    var sdkPackage = installedPackages.FirstOrDefault(p => p.Path.Equals(me.SdkId, StringComparison.OrdinalIgnoreCase));

                    if (sdkPackage == null && (me.AlternateSdkIds?.Any() ?? false))
                    {
                        sdkPackage = installedPackages.FirstOrDefault(p => me.AlternateSdkIds.Any(a => a.Equals(p.Path, StringComparison.OrdinalIgnoreCase)));
                    }

                    var sdkId = sdkPackage?.Path ?? me.SdkId;

                    avdManager.Create($"Android_Emulator_{me.ApiLevel}", sdkId, device: preferredDevice?.Id, tag: "google_apis", force: true, interactive: true);
                    return Task.CompletedTask;
                }
                catch (Exception ex)
                {
                    ReportStatus("Unable to create Emulator.  Use Visual Studio to create one instead: https://docs.microsoft.com/xamarin/android/get-started/installation/android-emulator/device-manager", Status.Warning);
                    Util.Exception(ex);
                }

                return Task.CompletedTask;
            })).ToArray()))));
        }
예제 #2
0
        static IEnumerable <DeviceData> AndroidDevices()
        {
            const int HighPriority = 0;
            const int MedPriority  = 1;
            const int LowPriority  = 2;

            var results = new List <(DeviceData Device, int Priority)>();

            // Get ADB Devices (includes emulators)
            var adb        = new AndroidSdk.Adb();
            var adbDevices = adb.GetDevices() ?? Enumerable.Empty <AndroidSdk.Adb.AdbDevice>();

            // Split out emulators and physical devices
            var emulators = adbDevices?.Where(d => d.IsEmulator)?.Select(e => new { EmulatorName = adb.GetEmulatorName(e.Serial), Emulator = e });
            var devices   = adbDevices?.Where(d => !d.IsEmulator);

            // Physical devices are easy
            foreach (var d in devices)
            {
                results.Add((new DeviceData
                {
                    IsEmulator = false,
                    IsRunning = true,
                    Name = d.Device,
                    Platforms = new[] { "android" },
                    Serial = d.Serial,
                    Version = d.Model
                }, HighPriority));
            }

            // Get all Avds
            var avdManager = new AndroidSdk.AvdManager();
            var avds       = avdManager.ListAvds() ?? Enumerable.Empty <AndroidSdk.AvdManager.Avd>();

            // Look through all avd's to list, but let's be smart and see if any of them
            // are already running (so were listed in the adb devices output)
            foreach (var a in avds)
            {
                var avdConfig = ParseAvdConfigIni(Path.Combine(a.Path, "config.ini"));

                var abi          = avdConfig?["abi.type"] ?? string.Empty;
                var architecture = avdConfig?["hw.cpu.arch"] ?? string.Empty;
                var manufacturer = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(avdConfig?["hw.device.manufacturer"] ?? string.Empty);
                var model        = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(avdConfig?["hw.device.name"] ?? string.Empty);
                var tag          = avdConfig?["tag.display"] ?? string.Empty;

                // See if ADB returned a running instance
                var emulator = emulators.FirstOrDefault(e => e.EmulatorName == a.Name);

                results.Add((new DeviceData
                {
                    IsEmulator = true,
                    IsRunning = emulator != null,
                    Name = a.Name,
                    Details = emulator != null
                                                ? emulator.Emulator.Product + " " + emulator.Emulator.Model
                                                : manufacturer + " " + model + " (" + architecture + ")",
                    Platforms = new[] { "android" },
                    Serial = emulator?.Emulator?.Serial ?? a.Name,
                    Version = a.BasedOn,
                    RuntimeIdentifier = architecture switch
                    {
                        "armeabi-v7a" => "android-arm",
                        "armeabi" => "android-arm",
                        "arm" => "android-arm",
                        "arm64" => "android-arm64",
                        "arm64-v8a" => "android-arm64",
                        "x86" => "android-x86",
                        "x86_64" => "android-x64",
                        _ => "android-arm"
                    }
                }, emulator == null ? LowPriority : MedPriority));