Run camera handler tasks on real host worker threads with controlled main timers

This commit is contained in:
evgeny committed 2026-10-29 13:34:24 +01:00
1 parent d88d77c14d
commit 278efd574e
3 files changed
+49 -5

No files matched your search

@@ -0,0 +1,3 @@
package android.annotation
annotation class SuppressLint(vararg val value: String)
@@ -3,12 +3,18 @@ package android.os
import java.util.concurrent.ConcurrentLinkedQueue
/** Только JVM: main очередь и таймеры исполняет тест, worker остаётся настоящим Thread. */
class Looper private constructor() {
class Looper internal constructor(private val threaded: Boolean = false) {
private data class Task(val handler: Handler, val action: Runnable, val deadline: Long)
private val tasks = ConcurrentLinkedQueue<Task>()
private var now = 0L
@Volatile private var now = 0L
@Volatile private var quitting = false
private val monitor = Object()
private fun time(): Long = if (threaded) System.nanoTime() / 1_000_000 else now
internal fun post(handler: Handler, action: Runnable, delay: Long): Boolean {
tasks.add(Task(handler, action, now + delay)); return true
synchronized(monitor) {
if (quitting) return false
tasks.add(Task(handler, action, time() + delay)); monitor.notifyAll(); return true
}
}
internal fun remove(handler: Handler, action: Runnable) { tasks.removeIf { it.handler === handler && it.action === action } }
fun advanceBy(delay: Long) {
@@ -18,10 +24,41 @@ class Looper private constructor() {
if (tasks.remove(next)) next.action.run()
}
}
companion object { private val main = Looper(); fun getMainLooper() = main }
internal fun loop() {
current.set(this)
while (true) {
val next = synchronized(monitor) {
val ready = tasks.filter { it.deadline <= time() }.minByOrNull { it.deadline }
if (ready == null && quitting) return
if (ready == null) monitor.wait(2)
ready
}
if (next != null && tasks.remove(next)) next.action.run()
}
}
internal fun quit(): Boolean = synchronized(monitor) { quitting = true; monitor.notifyAll(); true }
companion object {
private val main = Looper()
private val mainThread = Thread.currentThread()
private val current = ThreadLocal<Looper>()
fun getMainLooper() = main
fun myLooper(): Looper? = if (Thread.currentThread() === mainThread) main else current.get()
}
}
class Handler(private val looper: Looper) {
companion object { var rejectDelayed = false }
companion object { var rejectDelayed = false; var rejectImmediate = false }
fun post(action: Runnable): Boolean = !rejectImmediate && looper.post(this, action, 0)
fun postDelayed(action: Runnable, delay: Long): Boolean = !rejectDelayed && looper.post(this, action, delay)
fun removeCallbacks(action: Runnable) = looper.remove(this, action)
}
class HandlerThread(name: String) : Thread(name) {
val looper = Looper(true)
init { isDaemon = true }
override fun run() { looper.loop() }
fun quitSafely() = looper.quit()
}
object SystemClock {
fun elapsedRealtime(): Long = System.nanoTime() / 1_000_000
fun elapsedRealtimeNanos(): Long = System.nanoTime()
}
@@ -0,0 +1,4 @@
package android.util
data class Size(val width: Int, val height: Int)
data class Range<T : Comparable<T>>(val lower: T, val upper: T)