123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- //
- // Copyright © 2025 osy. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- import AppIntents
- @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
- struct UTMStatusActionIntent: UTMIntent {
- static let title: LocalizedStringResource = "Get Virtual Machine Status"
- static let description = IntentDescription("Get the status of a virtual machine.")
- static var parameterSummary: some ParameterSummary {
- Summary("Get \(\.$vmEntity) status")
- }
- @Dependency
- var data: UTMData
- @Parameter(title: "Virtual Machine", requestValueDialog: "Select a virtual machine")
- var vmEntity: UTMVirtualMachineEntity
- @MainActor
- func perform(with vm: any UTMVirtualMachine, boxed: VMData) async throws -> some ReturnsValue<UTMVirtualMachineState> {
- return .result(value: vm.state)
- }
- }
- @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
- struct UTMStartActionIntent: UTMIntent {
- static let title: LocalizedStringResource = "Start Virtual Machine"
- static let description = IntentDescription("Start a virtual machine.")
- static var parameterSummary: some ParameterSummary {
- Summary("Start \(\.$vmEntity)") {
- \.$isRecovery
- \.$isDisposible
- }
- }
- @Dependency
- var data: UTMData
- @Parameter(title: "Virtual Machine", requestValueDialog: "Select a virtual machine")
- var vmEntity: UTMVirtualMachineEntity
- @Parameter(title: "Recovery", description: "Boot into recovery mode. Only supported on Apple Virtualization backend.", default: false)
- var isRecovery: Bool
- @Parameter(title: "Disposible", description: "Do not save any changes to disk. Only supported on QEMU backend.", default: false)
- var isDisposible: Bool
- @MainActor
- func perform(with vm: any UTMVirtualMachine, boxed: VMData) async throws -> some IntentResult {
- var options = UTMVirtualMachineStartOptions()
- if isRecovery {
- #if os(macOS)
- guard vm is UTMAppleVirtualMachine else {
- throw UTMIntentError.unsupportedBackend
- }
- options.insert(.bootRecovery)
- #else
- throw UTMIntentError.unsupportedBackend
- #endif
- }
- if isDisposible {
- guard vm is UTMQemuVirtualMachine else {
- throw UTMIntentError.unsupportedBackend
- }
- options.insert(.bootDisposibleMode)
- }
- data.run(vm: boxed, options: options)
- if !vm.isHeadless {
- if #available(iOS 26, macOS 26, tvOS 26, watchOS 26, visionOS 26, *), systemContext.currentMode.canContinueInForeground {
- try await continueInForeground(alwaysConfirm: false)
- }
- }
- return .result()
- }
- }
- @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
- struct UTMStopActionIntent: UTMIntent {
- static let title: LocalizedStringResource = "Stop Virtual Machine"
- static let description = IntentDescription("Stop a virtual machine.")
- static var parameterSummary: some ParameterSummary {
- Summary("Stop \(\.$vmEntity) by \(\.$method)")
- }
- @Dependency
- var data: UTMData
- @Parameter(title: "Virtual Machine", requestValueDialog: "Select a virtual machine")
- var vmEntity: UTMVirtualMachineEntity
- @Parameter(title: "Stop Method", description: "Intensity of the stop action.", default: .force)
- var method: UTMVirtualMachineStopMethod
- @MainActor
- func perform(with vm: any UTMVirtualMachine, boxed: VMData) async throws -> some IntentResult {
- try await vm.stop(usingMethod: method)
- return .result()
- }
- }
- @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
- extension UTMVirtualMachineStopMethod: AppEnum {
- static let typeDisplayRepresentation: TypeDisplayRepresentation =
- TypeDisplayRepresentation(
- name: "Stop Method"
- )
- static let caseDisplayRepresentations: [UTMVirtualMachineStopMethod: DisplayRepresentation] = [
- .request: DisplayRepresentation(title: "Request", subtitle: "Sends power down request to the guest. This simulates pressing the power button on a PC."),
- .force: DisplayRepresentation(title: "Force", subtitle: "Tells the VM process to shut down with risk of data corruption. This simulates holding down the power button on a PC."),
- .kill: DisplayRepresentation(title: "Killing", subtitle: "Force kill the VM process with high risk of data corruption."),
- ]
- }
- @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
- struct UTMPauseActionIntent: UTMIntent {
- static let title: LocalizedStringResource = "Pause Virtual Machine"
- static let description = IntentDescription("Pause a virtual machine.")
- static var parameterSummary: some ParameterSummary {
- Summary("Pause \(\.$vmEntity)") {
- \.$isSaveState
- }
- }
- @Dependency
- var data: UTMData
- @Parameter(title: "Virtual Machine", requestValueDialog: "Select a virtual machine")
- var vmEntity: UTMVirtualMachineEntity
- @Parameter(title: "Save State", description: "Create a snapshot of the virtual machine state.", default: false)
- var isSaveState: Bool
- @MainActor
- func perform(with vm: any UTMVirtualMachine, boxed: VMData) async throws -> some IntentResult {
- try await vm.pause()
- if isSaveState {
- try await vm.save()
- }
- return .result()
- }
- }
- @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
- struct UTMResumeActionIntent: UTMIntent {
- static let title: LocalizedStringResource = "Resume Virtual Machine"
- static let description = IntentDescription("Resume a virtual machine.")
- static var parameterSummary: some ParameterSummary {
- Summary("Resume \(\.$vmEntity)")
- }
- @Dependency
- var data: UTMData
- @Parameter(title: "Virtual Machine", requestValueDialog: "Select a virtual machine")
- var vmEntity: UTMVirtualMachineEntity
- @MainActor
- func perform(with vm: any UTMVirtualMachine, boxed: VMData) async throws -> some IntentResult {
- try await vm.resume()
- if vm.isHeadless {
- if #available(iOS 26, macOS 26, tvOS 26, watchOS 26, visionOS 26, *), systemContext.currentMode.canContinueInForeground {
- try await continueInForeground(alwaysConfirm: false)
- }
- }
- return .result()
- }
- }
- @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
- struct UTMRestartActionIntent: UTMIntent {
- static let title: LocalizedStringResource = "Restart Virtual Machine"
- static let description = IntentDescription("Restart a virtual machine.")
- static var parameterSummary: some ParameterSummary {
- Summary("Restart \(\.$vmEntity)")
- }
- @Dependency
- var data: UTMData
- @Parameter(title: "Virtual Machine", requestValueDialog: "Select a virtual machine")
- var vmEntity: UTMVirtualMachineEntity
- @MainActor
- func perform(with vm: any UTMVirtualMachine, boxed: VMData) async throws -> some IntentResult {
- try await vm.restart()
- if vm.isHeadless {
- if #available(iOS 26, macOS 26, tvOS 26, watchOS 26, visionOS 26, *), systemContext.currentMode.canContinueInForeground {
- try await continueInForeground(alwaysConfirm: false)
- }
- }
- return .result()
- }
- }
|