Vier Annahmen des Plans vor jedem Implementierungscode geprüft:
A (SMC): Lüftersteuerung bestätigt — F0md/F1md (klein!) als Auto/Manuell-
Umschalter, F0Tg als Ziel, Grenzen aus F0Mn/F0Mx. SMC-Integer sind
little-endian, nicht big-endian wie im verbreiteten Intel-Beispielcode.
Ladelimit: CHWA/CH0B/CH0C/bfE0/bfF0 existieren auf Mac17,9 nicht.
Key noch nicht identifiziert, deshalb smc-diff.sh für eine
Differenzmessung ohne jeden Schreibzugriff.
B (Media): mediaremote-adapter läuft unter 26.6.1, aus dem Quellcode gebaut.
Liefert vollständige Metadaten inkl. Cover aus Google Chrome — der
Fall, den AppleScript nicht erreicht.
C (Audio): Process Tap + privates Aggregate-Device liefern echte Samples
(469 Callbacks/5 s, 0 stille Puffer). Konflikt gefunden: SoundSource
6.1.1 mit ARK.driver ist bereits installiert.
D (Group): App-Group-Container ist aus einem nicht-sandboxed Prozess erreichbar.
Damit trägt die Sandbox-Entscheidung, die Bridge-App entfällt.
Spikes sind Wegwerfcode zur Verifikation, kein Produktionscode.
61 lines
2.6 KiB
Swift
61 lines
2.6 KiB
Swift
// Spike D — App-Group-Container aus einem NICHT sandboxed Prozess
|
|
//
|
|
// Frage: liefert containerURL(forSecurityApplicationGroupIdentifier:) einen Pfad,
|
|
// wenn der Prozess die App-Group-Entitlement trägt, aber NICHT sandboxed ist?
|
|
// Davon hängt ab, ob Onyx den Calendarr-Snapshot direkt lesen kann oder eine
|
|
// sandboxed Bridge-App braucht.
|
|
//
|
|
// Bauen und signieren: Spikes/build-appgroup-probe.sh
|
|
|
|
import Foundation
|
|
|
|
let groupID = "PP34X97WS3.group.com.scarriffleservices.calendarr"
|
|
|
|
print("App-Group-Probe")
|
|
print("Gruppe: \(groupID)")
|
|
print("Sandboxed: \(ProcessInfo.processInfo.environment["APP_SANDBOX_CONTAINER_ID"] != nil ? "ja" : "nein")")
|
|
print(String(repeating: "─", count: 64))
|
|
|
|
guard let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupID) else {
|
|
print("ERGEBNIS: nil")
|
|
print()
|
|
print("Der Container ist nicht erreichbar. Mögliche Ursachen:")
|
|
print(" 1. Entitlement fehlt oder Signatur ungültig")
|
|
print(" 2. Team-Präfix stimmt nicht byte-genau")
|
|
print(" 3. App-Group ohne Sandbox wird doch nicht gewährt → Bridge-App nötig")
|
|
exit(1)
|
|
}
|
|
|
|
print("ERGEBNIS: \(url.path)")
|
|
print("Existiert: \(FileManager.default.fileExists(atPath: url.path) ? "ja" : "nein (Calendarr lief hier noch nie)")")
|
|
|
|
// Schreibprobe — der Container muss beschreibbar sein, sonst wäre selbst ein
|
|
// eigener Cache dort unmöglich. Berührt widget-cache.json NICHT.
|
|
let probe = url.appendingPathComponent(".onyx-probe")
|
|
do {
|
|
try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true)
|
|
try Data("ok".utf8).write(to: probe)
|
|
try FileManager.default.removeItem(at: probe)
|
|
print("Schreibzugriff: ja")
|
|
} catch {
|
|
print("Schreibzugriff: nein (\(error.localizedDescription))")
|
|
}
|
|
|
|
// Was liegt drin? Nur auflisten, nichts öffnen und nichts verändern.
|
|
if let items = try? FileManager.default.contentsOfDirectory(atPath: url.path), !items.isEmpty {
|
|
print("\nInhalt:")
|
|
for item in items.sorted() { print(" \(item)") }
|
|
} else {
|
|
print("\nContainer ist leer — Calendarr-Mac-App noch nicht gestartet.")
|
|
print("Das ist der Zustand .neverWritten, den das Kalender-Widget anzeigen muss.")
|
|
}
|
|
|
|
// Die Darwin-Notification, auf die Onyx später hört. Nur registrieren, um zu
|
|
// bestätigen, dass das ohne Sandbox funktioniert.
|
|
let name = "com.scarriffleservices.calendarr.snapshot-changed"
|
|
CFNotificationCenterAddObserver(
|
|
CFNotificationCenterGetDarwinNotifyCenter(), nil,
|
|
{ _, _, _, _, _ in print("Darwin-Notification empfangen") },
|
|
name as CFString, nil, .deliverImmediately)
|
|
print("\nDarwin-Observer für '\(name)' registriert (ohne Fehler).")
|