feat(soter): wire supervisor into App startup

Start SoterProcessSupervisor from App.main() so the Layer-A forge
mounts on the on-demand soterserver process. prepareEnvironment() now
returns the system Context it previously discarded; main() hands it to
start() after keystore init and before Looper.loop(). start() runs on
its own HandlerThread and returns at once, so neither the blocking
keystore loop nor the message loop is affected.

The stub types ActivityThread.getSystemContext() as a bare ContextImpl,
so the Context cast warns CAST_NEVER_SUCCEEDS; the real ContextImpl does
extend Context, so it is runtime-safe and the warning is suppressed.

Checkpoint 10.W. compileDebugKotlin clean.
This commit is contained in:
Enginex0
2026-06-26 16:13:03 +01:00
parent 6b84c76f10
commit a4875dc200
@@ -13,6 +13,7 @@ import org.matrix.TEESimulator.config.ConfigurationManager
import org.matrix.TEESimulator.interception.keystore.AbstractKeystoreInterceptor import org.matrix.TEESimulator.interception.keystore.AbstractKeystoreInterceptor
import org.matrix.TEESimulator.interception.keystore.Keystore2Interceptor import org.matrix.TEESimulator.interception.keystore.Keystore2Interceptor
import org.matrix.TEESimulator.interception.keystore.KeystoreInterceptor import org.matrix.TEESimulator.interception.keystore.KeystoreInterceptor
import org.matrix.TEESimulator.interception.soter.SoterProcessSupervisor
import org.matrix.TEESimulator.logging.SystemLogger import org.matrix.TEESimulator.logging.SystemLogger
import org.matrix.TEESimulator.pki.NativeCertGen import org.matrix.TEESimulator.pki.NativeCertGen
import org.matrix.TEESimulator.util.AndroidDeviceUtils import org.matrix.TEESimulator.util.AndroidDeviceUtils
@@ -39,7 +40,7 @@ object App {
} }
try { try {
prepareEnvironment() val systemContext = prepareEnvironment()
// Spoof boot-state props before any hook attaches, so keystore2's // Spoof boot-state props before any hook attaches, so keystore2's
// cached snapshot reflects the spoofed values. // cached snapshot reflects the spoofed values.
@@ -62,6 +63,10 @@ object App {
NativeCertGen.initialize("/data/adb/modules/tricky_store/libcertgen.so") NativeCertGen.initialize("/data/adb/modules/tricky_store/libcertgen.so")
// Mount the SOTER forge on the on-demand soterserver process. The supervisor
// binds and (re)injects on its own thread, returning at once so it never blocks the loop.
SoterProcessSupervisor.start(systemContext)
// This starts the message queue processing. It blocks here indefinitely // This starts the message queue processing. It blocks here indefinitely
// processing messages until Looper.myLooper().quit() is called. // processing messages until Looper.myLooper().quit() is called.
Looper.loop() Looper.loop()
@@ -72,7 +77,7 @@ object App {
} }
/** Initializes the necessary Android framework internals to satisfy KeyStore requirements. */ /** Initializes the necessary Android framework internals to satisfy KeyStore requirements. */
private fun prepareEnvironment() { private fun prepareEnvironment(): Context {
// 1. Prepare Main Looper // 1. Prepare Main Looper
if (Looper.getMainLooper() == null) { if (Looper.getMainLooper() == null) {
@Suppress("deprecation") Looper.prepareMainLooper() @Suppress("deprecation") Looper.prepareMainLooper()
@@ -81,8 +86,10 @@ object App {
// 2. Initialize ActivityThread for the current process // 2. Initialize ActivityThread for the current process
val activityThread = ActivityThread.systemMain() val activityThread = ActivityThread.systemMain()
// 3. Get the system context // 3. Get the system context. The stub declares getSystemContext(): ContextImpl
val systemContext = activityThread.getSystemContext() // (a bare class), so cast to the Context it really is at runtime for the wiring.
@Suppress("CAST_NEVER_SUCCEEDS")
val systemContext = activityThread.getSystemContext() as Context
// 4. Create a dummy Application object and attach the context // 4. Create a dummy Application object and attach the context
val app = Application() val app = Application()
@@ -97,6 +104,8 @@ object App {
ActivityThread::class.java.getDeclaredField("mInitialApplication") ActivityThread::class.java.getDeclaredField("mInitialApplication")
mInitialApplicationField.isAccessible = true mInitialApplicationField.isAccessible = true
mInitialApplicationField.set(activityThread, app) mInitialApplicationField.set(activityThread, app)
return systemContext
} }
/** /**