1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software distributed under the
11  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
12  * KIND, either express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 package com.android.systemui.unfold.updates.hinge
16 
17 import android.hardware.Sensor
18 import android.hardware.SensorEvent
19 import android.hardware.SensorEventListener
20 import android.hardware.SensorManager
21 import android.os.Handler
22 import android.os.Trace
23 import androidx.core.util.Consumer
24 import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
25 import dagger.assisted.Assisted
26 import dagger.assisted.AssistedFactory
27 import dagger.assisted.AssistedInject
28 import java.util.concurrent.CopyOnWriteArrayList
29 import java.util.concurrent.Executor
30 
31 internal class HingeSensorAngleProvider
32 @AssistedInject
33 constructor(
34     private val sensorManager: SensorManager,
35     @UnfoldSingleThreadBg private val singleThreadBgExecutor: Executor,
36     @Assisted private val listenerHandler: Handler,
37 ) : HingeAngleProvider {
38 
39     private val sensorListener = HingeAngleSensorListener()
40     private val listeners: MutableList<Consumer<Float>> = CopyOnWriteArrayList()
41     var started = false
42 
startnull43     override fun start() {
44         singleThreadBgExecutor.execute {
45             if (started) return@execute
46             Trace.beginSection("HingeSensorAngleProvider#start")
47             val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE)
48             sensorManager.registerListener(
49                 sensorListener,
50                 sensor,
51                 SensorManager.SENSOR_DELAY_FASTEST,
52                 listenerHandler
53             )
54             Trace.endSection()
55 
56             started = true
57         }
58     }
59 
stopnull60     override fun stop() {
61         singleThreadBgExecutor.execute {
62             if (!started) return@execute
63             sensorManager.unregisterListener(sensorListener)
64             started = false
65         }
66     }
67 
removeCallbacknull68     override fun removeCallback(listener: Consumer<Float>) {
69         listeners.remove(listener)
70     }
71 
addCallbacknull72     override fun addCallback(listener: Consumer<Float>) {
73         listeners.add(listener)
74     }
75 
76     private inner class HingeAngleSensorListener : SensorEventListener {
77 
onAccuracyChangednull78         override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
79 
onSensorChangednull80         override fun onSensorChanged(event: SensorEvent) {
81             listeners.forEach { it.accept(event.values[0]) }
82         }
83     }
84 
85     @AssistedFactory
86     interface Factory {
87         /** Creates an [HingeSensorAngleProvider] that sends updates using [handler]. */
createnull88         fun create(handler: Handler): HingeSensorAngleProvider
89     }
90 }
91