feat(flow): implement ABCD session policy and host return whitelist

- Scheme A: on-demand session start, inactivity-based expiry, handoff auto-recording
- Scheme B: cold-start overlay with swipe guidance and return alert
- Scheme C+D: HostAppURLRegistry (20 apps) and sourceApplication capture
- Settings: skip app switch toggle and inactivity duration picker
- Add LSApplicationQueriesSchemes for canOpenURL checks

Co-authored-by: Rocky <hkgood@users.noreply.github.com>
This commit is contained in:
Cursor Agent
2026-07-06 07:38:26 +00:00
parent 6489340b2e
commit 13cd7b30f9
25 changed files with 936 additions and 77 deletions
@@ -0,0 +1,28 @@
// HostAppURLRegistryTests.swift
// OSGKeyboardTests
import XCTest
@testable import OSGKeyboardShared
final class HostAppURLRegistryTests: XCTestCase {
func testWeChatLookup() {
let entry = HostAppURLRegistry.lookup(bundleId: "com.tencent.xin")
XCTAssertEqual(entry?.returnURLString, "weixin://")
XCTAssertEqual(entry?.displayNameKey, "hostApp.wechat")
}
func testUnknownBundleReturnsNil() {
XCTAssertNil(HostAppURLRegistry.lookup(bundleId: "com.apple.MobileSMS"))
XCTAssertNil(HostAppURLRegistry.lookup(bundleId: nil))
XCTAssertNil(HostAppURLRegistry.lookup(bundleId: ""))
}
func testQuerySchemesIncludesWeChat() {
XCTAssertTrue(HostAppURLRegistry.querySchemes.contains("weixin"))
}
func testEntriesHaveUniqueBundleIds() {
let ids = HostAppURLRegistry.entries.map(\.bundleId)
XCTAssertEqual(Set(ids).count, ids.count)
}
}