diff --git a/MiniSim/MenuItems/SubMenuItem.swift b/MiniSim/MenuItems/SubMenuItem.swift index 32ae7e0..415846a 100644 --- a/MiniSim/MenuItems/SubMenuItem.swift +++ b/MiniSim/MenuItems/SubMenuItem.swift @@ -119,6 +119,17 @@ enum SubMenuItems { accessibilityDescription: "Delete simulator" ) } + + struct DeleteEmulator: SubMenuActionItem { + let title = NSLocalizedString("Delete emulator", comment: "") + let tag = Tags.delete.rawValue + let bootsDevice = false + let needBootedDevice = false + let image = NSImage( + systemSymbolName: "trash", + accessibilityDescription: "Delete emulator" + ) + } } extension SubMenuItems { @@ -131,7 +142,8 @@ extension SubMenuItems { ColdBoot(), NoAudio(), ToggleA11y(), - Paste() + Paste(), + DeleteEmulator() ] static var ios: [SubMenuItem] = [ diff --git a/MiniSim/Service/Adb.swift b/MiniSim/Service/Adb.swift index f7ca1ad..705e1ec 100644 --- a/MiniSim/Service/Adb.swift +++ b/MiniSim/Service/Adb.swift @@ -24,6 +24,7 @@ final class ADB: ADBProtocol { case home = "/Android/sdk" case emulator = "/emulator/emulator" case adb = "/platform-tools/adb" + case avd = "/cmdline-tools/latest/bin/avdmanager" } /** @@ -47,6 +48,10 @@ final class ADB: ADBProtocol { try getAndroidHome() + Paths.adb.rawValue } + static func getAvdPath() throws -> String { + try getAndroidHome() + Paths.avd.rawValue + } + /** Checks if passed path exists and points to `ANDROID_HOME`. */ diff --git a/MiniSim/Service/DeviceService.swift b/MiniSim/Service/DeviceService.swift index f524a1b..ab0424b 100644 --- a/MiniSim/Service/DeviceService.swift +++ b/MiniSim/Service/DeviceService.swift @@ -413,8 +413,19 @@ extension DeviceService { try shellOut(to: "\(adbPath) -s \(deviceId) shell input text \"\(formattedText)\"") } + static func deleteEmulator(device: Device) throws { + let avdPath = try ADB.getAvdPath() + let adbPath = try ADB.getAdbPath() + if device.booted { + guard let deviceId = device.identifier else { + throw DeviceError.deviceNotFound + } + try shellOut(to: "\(adbPath) -s \(deviceId) emu kill") + } + try shellOut(to: "\(avdPath) delete avd -n \"\(device.name)\"") + } + static func handleAndroidAction(device: Device, commandTag: SubMenuItems.Tags, itemName: String) { - queue.async { do { switch commandTag { case .coldBoot: @@ -447,12 +458,27 @@ extension DeviceService { if let command = DeviceService.getCustomCommand(platform: .android, commandName: itemName) { try DeviceService.runCustomCommand(device, command: command) } + + case .delete: + let result = !NSAlert.showQuestionDialog( + title: "Are you sure?", + message: "Are you sure you want to delete this Emulator?" + ) + if result { return } + queue.async { + do { + try DeviceService.deleteEmulator(device: device) + DeviceService.showSuccessMessage(title: "Emulator deleted!", message: device.name) + NotificationCenter.default.post(name: .deviceDeleted, object: nil) + } catch { + NSAlert.showError(message: error.localizedDescription) + } + } default: break } } catch { NSAlert.showError(message: error.localizedDescription) } - } } }