Run camera handler tasks on real host worker threads with controlled main timers
This commit is contained in:
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)
|
||||
Reference in new issue
Block a user