// ───────────────────────────────────────────────────────────────────────────── // :terminal-view (A16) — the XL terminal-render module. // // Wraps Termux `terminal-emulator` (VT100/xterm parser + `TerminalBuffer` scrollback // ring) + `terminal-view` (`TerminalView`/`TerminalRenderer` glyph painter). These two // libraries are Apache-2.0 (plan §9 R2 — they descend from jackpal's Apache-2.0 emulator; // only `termux-shared`/app are GPLv3, and we depend on NEITHER). Consumed from JitPack. // // `RemoteTerminalSession` is the FORK (plan §6.1): it holds a `TerminalEmulator` with NO // local subprocess / NO JNI, feeds remote WS bytes into it off the main thread, and routes // emulator-originated bytes back out through `engineSend`. Depends ONLY on :wire-protocol // (boundary note §3 — the SessionEvent→ByteArray decode is A21's, not here). // // AGP 9 has built-in Kotlin → apply ONLY com.android.library (adding // org.jetbrains.kotlin.android errors). No serialization/compose plugins needed. // // The pure logic (RemoteTerminalSession seam, TerminalGridMath resize formula, // pendingOutput ordering, DECCKM key form) is a LOCAL JVM unit test: `TerminalEmulator` // is pure Java whose exercised path touches no runtime android API, so it drives headless // on `testDebugUnitTest` (android.jar stubs on the classpath, isReturnDefaultValues=true). // Rendering / IME / selection / rotation-rebind are device QA (plan §7). // ───────────────────────────────────────────────────────────────────────────── plugins { id("com.android.library") } android { namespace = "wang.yaojia.webterm.terminalview" compileSdk = 36 defaultConfig { minSdk = 29 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } testOptions { unitTests { // The Termux emulator references a couple of android.* APIs (e.g. Base64 in the // OSC-52 path we never exercise); default-return keeps any incidental android // call from throwing "not mocked" in the headless JVM seam tests. isReturnDefaultValues = true } } } kotlin { jvmToolchain(17) } dependencies { // Boundary note (plan §3): :terminal-view depends ONLY on :wire-protocol. api(project(":wire-protocol")) implementation(libs.kotlinx.coroutines.core) // Provides the `Main` dispatcher on Android — without it `Dispatchers.Main.immediate` // throws "Module with the Main dispatcher is missing" at runtime on-device. implementation(libs.kotlinx.coroutines.android) // Termux VT100/xterm emulator + view (Apache-2.0). Scope is these TWO libs ONLY — // never `termux-shared`/app (GPLv3). JitPack builds them from the termux-app repo. implementation(libs.termux.terminal.view) implementation(libs.termux.terminal.emulator) testImplementation(libs.bundles.unit.test) testRuntimeOnly(libs.junit.platform.launcher) androidTestImplementation(libs.androidx.test.ext.junit) androidTestImplementation(libs.androidx.test.core) androidTestImplementation(libs.androidx.test.runner) } // Local (JVM) unit tests run on the JUnit 5 platform, matching the pure modules. tasks.withType().configureEach { useJUnitPlatform() }