diff --git a/tools/chatgui-android/router-tests/build.gradle.kts b/tools/chatgui-android/router-tests/build.gradle.kts index 781cd94b..f45b51b5 100644 --- a/tools/chatgui-android/router-tests/build.gradle.kts +++ b/tools/chatgui-android/router-tests/build.gradle.kts @@ -9,6 +9,7 @@ kotlin { kotlin.srcDir(providers.gradleProperty("routerSourceDir").getOrElse("../app/src/main/java")) kotlin.include("android/**", "com/utun/chat/RouterHostApp.kt", "com/utun/chat/data/RouterHostEnvironment.kt", "com/utun/chat/data/CallAudioRouter.kt", "com/utun/chat/data/CoreActivity.kt", + "com/utun/chat/data/ProximityManager.kt", "com/utun/chat/data/NetworkActivityMonitor.kt", "com/utun/chat/data/NetworkChangeMonitor.kt") } } diff --git a/tools/chatgui-android/router-tests/src/main/kotlin/android/content/Context.kt b/tools/chatgui-android/router-tests/src/main/kotlin/android/content/Context.kt index c072f9a1..442b192f 100644 --- a/tools/chatgui-android/router-tests/src/main/kotlin/android/content/Context.kt +++ b/tools/chatgui-android/router-tests/src/main/kotlin/android/content/Context.kt @@ -2,22 +2,28 @@ package android.content import android.media.AudioManager import android.net.ConnectivityManager +import android.hardware.SensorManager import com.utun.chat.data.HostConfigProvider -/** Только host-тест: управляемые AudioManager/ConnectivityManager, без устройств/разрешений ОС. */ +/** Только host-тест: управляемые Android managers, без устройств/разрешений ОС. */ class Context { - companion object { const val AUDIO_SERVICE = "audio" } + companion object { const val AUDIO_SERVICE = "audio"; const val SENSOR_SERVICE = "sensor" } var permissionGranted = true var connectivityManager: ConnectivityManager? = ConnectivityManager() + var sensorManager: SensorManager? = SensorManager() val configProvider = HostConfigProvider() val applicationContext: Context get() = this - fun getSystemService(name: String): Any { - check(name == AUDIO_SERVICE) - return AudioManager.shared + fun getSystemService(name: String): Any? = when (name) { + AUDIO_SERVICE -> AudioManager.shared + SENSOR_SERVICE -> sensorManager + else -> error("Unknown service: $name") } fun getSystemService(type: Class): T? { - check(type == ConnectivityManager::class.java) - return type.cast(connectivityManager) + return type.cast(when (type) { + ConnectivityManager::class.java -> connectivityManager + SensorManager::class.java -> sensorManager + else -> error("Unknown service: $type") + }) } fun checkSelfPermission(name: String): Int = if (permissionGranted) 0 else -1 } diff --git a/tools/chatgui-android/router-tests/src/main/kotlin/android/hardware/HostSensors.kt b/tools/chatgui-android/router-tests/src/main/kotlin/android/hardware/HostSensors.kt new file mode 100644 index 00000000..abcc7b8a --- /dev/null +++ b/tools/chatgui-android/router-tests/src/main/kotlin/android/hardware/HostSensors.kt @@ -0,0 +1,50 @@ +package android.hardware + +import android.os.Handler +import android.os.Looper + +/** Только host-тест: очередь датчика, результаты регистрации и ошибки ОС задаёт тест. */ +class Sensor(val maximumRange: Float = 5f) { companion object { const val TYPE_PROXIMITY = 8 } } +class SensorEvent(val sensor: Sensor, val values: FloatArray) +interface SensorEventListener { + fun onSensorChanged(event: SensorEvent) + fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) +} + +class SensorManager { + companion object { const val SENSOR_DELAY_NORMAL = 3 } + data class Registration(val listener: SensorEventListener, val sensor: Sensor, val handler: Handler) + var sensor: Sensor? = Sensor() + var acceptRegistration = true + var failRegistration = false + var failRemoval = false + var registerAttempts = 0 + var removeAttempts = 0 + val registrations = mutableListOf() + val active = mutableSetOf() + + fun getDefaultSensor(type: Int): Sensor? { check(type == Sensor.TYPE_PROXIMITY); return sensor } + fun registerListener(listener: SensorEventListener, sensor: Sensor, delay: Int, + handler: Handler = Handler(Looper.getMainLooper())): Boolean { + check(delay == SENSOR_DELAY_NORMAL) + registerAttempts++ + registrations.add(Registration(listener, sensor, handler)) + check(!failRegistration) { "sensor registration unavailable" } + if (!acceptRegistration) return false + active.add(listener) + return true + } + fun unregisterListener(listener: SensorEventListener) { + removeAttempts++ + check(!failRemoval) { "sensor removal unavailable" } + active.remove(listener) + } + + /** Можно доставить и старую регистрацию: модель события, уже переданного ОС в очередь приложения. */ + fun deliver(index: Int, distance: Float) { + val registration = registrations[index] + registration.handler.post { + registration.listener.onSensorChanged(SensorEvent(registration.sensor, floatArrayOf(distance))) + } + } +}