import Foundation
|
|
public struct SystemCriticalWindowDescriptor: Equatable, Sendable {
|
public let ownerName: String
|
public let title: String
|
public let bundleIdentifier: String?
|
public let processIdentifier: Int32?
|
public let layer: Int?
|
|
public init(
|
ownerName: String = "",
|
title: String = "",
|
bundleIdentifier: String? = nil,
|
processIdentifier: Int32? = nil,
|
layer: Int? = nil
|
) {
|
self.ownerName = ownerName
|
self.title = title
|
self.bundleIdentifier = bundleIdentifier
|
self.processIdentifier = processIdentifier
|
self.layer = layer
|
}
|
}
|
|
public enum SystemCriticalWindowClassifier {
|
private static let criticalBundleIdentifiers: Set<String> = [
|
"com.apple.SecurityAgent",
|
"com.apple.CoreServicesUIAgent"
|
]
|
|
private static let criticalOwnerNames: Set<String> = [
|
"SecurityAgent",
|
"CoreServicesUIAgent"
|
]
|
|
private static let rescueWindowBundleIdentifiers: Set<String> = [
|
"com.apple.loginwindow"
|
]
|
|
private static let rescueWindowOwnerNames: Set<String> = [
|
"loginwindow"
|
]
|
|
public static func isSystemCritical(app: AlignerApp) -> Bool {
|
criticalBundleIdentifiers.contains(app.bundleIdentifier)
|
}
|
|
public static func isSystemCritical(_ descriptor: SystemCriticalWindowDescriptor) -> Bool {
|
if let bundleIdentifier = descriptor.bundleIdentifier,
|
criticalBundleIdentifiers.contains(bundleIdentifier)
|
{
|
return true
|
}
|
|
if criticalOwnerNames.contains(descriptor.ownerName) {
|
return true
|
}
|
|
if let bundleIdentifier = descriptor.bundleIdentifier,
|
rescueWindowBundleIdentifiers.contains(bundleIdentifier)
|
{
|
return isRescueWindowTitle(descriptor.title)
|
}
|
|
if rescueWindowOwnerNames.contains(descriptor.ownerName) {
|
return isRescueWindowTitle(descriptor.title)
|
}
|
|
return isRescueWindowTitle(descriptor.title)
|
}
|
|
public static func isSystemCriticalTitle(_ title: String) -> Bool {
|
isRescueWindowTitle(title) || isPermissionPromptTitle(title)
|
}
|
|
private static func isRescueWindowTitle(_ title: String) -> Bool {
|
let normalized = title.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
|
guard !normalized.isEmpty else { return false }
|
|
return normalized == "force quit applications"
|
|| normalized == "force quit"
|
|| normalized == "强制退出应用程序"
|
|| normalized == "强制退出"
|
}
|
|
private static func isPermissionPromptTitle(_ title: String) -> Bool {
|
let normalized = title.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
|
guard !normalized.isEmpty else { return false }
|
|
return normalized == "accessibility permissions"
|
|| normalized == "screen recording permissions"
|
|| normalized == "安全性与隐私权限"
|
|| normalized == "辅助功能权限"
|
|| normalized == "屏幕录制权限"
|
}
|
}
|