-
Notifications
You must be signed in to change notification settings - Fork 1
/
GazeTrackerManager.kt
214 lines (189 loc) · 7.09 KB
/
GazeTrackerManager.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
package camp.visual.android.kotlin.sample.manager
import android.content.Context
import camp.visual.gazetracker.GazeTracker
import camp.visual.gazetracker.callback.*
import camp.visual.gazetracker.constant.*
import camp.visual.gazetracker.gaze.GazeInfo
import java.lang.ref.WeakReference
enum class SeeSoInitializeState {
default, initializing, initialized
}
class GazeTrackerManager private constructor(context: Context) {
private val initializationCallbacks: MutableList<InitializationCallback> = ArrayList()
private val statusCallbacks: MutableList<StatusCallback> = ArrayList()
private val gazeCallbacks: MutableList<GazeCallback> = ArrayList()
private val calibrationCallbacks: MutableList<CalibrationCallback> = ArrayList()
private val userStatusCallbacks: MutableList<UserStatusCallback> = ArrayList()
// state control
var isInitWithUserOption = false
var initializeState: SeeSoInitializeState = SeeSoInitializeState.default
private val mContext: WeakReference<Context> = WeakReference(context)
private var gazeTracker: GazeTracker? = null
// TODO: change licence key
private val SEESO_LICENSE_KEY = "your license key"
companion object {
private var instance: GazeTrackerManager? = null
fun makeNewInstance(context: Context): GazeTrackerManager? {
instance.also { it?.deInitGazeTracker() }
instance = GazeTrackerManager(context)
return instance
}
}
fun isTracking(): Boolean {
return gazeTracker?.isTracking ?: false
}
fun isCalibrating(): Boolean {
return gazeTracker?.isCalibrating ?: false
}
fun initGazeTracker(callback: InitializationCallback, isInitWithUserOption: Boolean) {
initializationCallbacks.add(callback)
var userOption: UserStatusOption? = null
if (isInitWithUserOption) {
userOption = UserStatusOption()
userOption.useAll()
this.isInitWithUserOption = true
}
initializeState = SeeSoInitializeState.initializing
GazeTracker.initGazeTracker(
mContext.get(),
SEESO_LICENSE_KEY,
initializationCallback,
userOption
)
}
fun deInitGazeTracker() {
gazeTracker?.also { GazeTracker.deinitGazeTracker(it) }
gazeTracker = null
isInitWithUserOption = false
initializeState = SeeSoInitializeState.default
}
fun setGazeTrackerCallbacks(vararg callbacks: GazeTrackerCallback?) {
for (callback in callbacks) {
when (callback) {
is GazeCallback -> gazeCallbacks.add(callback)
is CalibrationCallback -> calibrationCallbacks.add(callback)
is StatusCallback -> statusCallbacks.add(callback)
is UserStatusCallback -> userStatusCallbacks.add(callback)
}
}
}
fun setGazeTrackingFps(fps: Int): Boolean {
return gazeTracker?.setTrackingFPS(fps) ?: false
}
fun startGazeTracking(): Boolean {
gazeTracker?.also {
it.startTracking()
return true
}
return false
}
fun stopGazeTracking(): Boolean {
gazeTracker?.also {
it.stopTracking()
return true
}
return false
}
// Start Calibration
fun startCalibration(modeType: CalibrationModeType?, criteria: AccuracyCriteria?): Boolean {
return if (isTracking()) {
gazeTracker?.startCalibration(modeType, criteria)
true
} else {
false
}
}
// Start Collect calibration sample data
fun startCollectionCalibrationSamples(): Boolean {
return if (isCalibrating()) {
gazeTracker?.startCollectSamples()
true
} else {
false
}
}
// inner callbacks
private val initializationCallback: InitializationCallback = object : InitializationCallback {
override fun onInitialized(tracker: GazeTracker?, error: InitializationErrorType?) {
initializeState = SeeSoInitializeState.initialized
gazeTracker = tracker
for (initializationCallback in initializationCallbacks) {
initializationCallback.onInitialized(gazeTracker, error)
}
initializationCallbacks.clear()
gazeTracker?.setCallbacks(
gazeCallback,
calibrationCallback,
statusCallback,
userStatusCallback
)
}
}
private val gazeCallback = object : GazeCallback {
override fun onGaze(gazeInfo: GazeInfo?) {
for (gazeCallback in gazeCallbacks) {
gazeCallback.onGaze(gazeInfo)
}
}
}
private val calibrationCallback: CalibrationCallback = object : CalibrationCallback {
override fun onCalibrationProgress(progress: Float) {
for (calibrationCallback in calibrationCallbacks) {
calibrationCallback.onCalibrationProgress(progress)
}
}
override fun onCalibrationNextPoint(x: Float, y: Float) {
for (calibrationCallback in calibrationCallbacks) {
calibrationCallback.onCalibrationNextPoint(x, y)
}
}
override fun onCalibrationFinished(calibrationData: DoubleArray) {
for (calibrationCallback in calibrationCallbacks) {
calibrationCallback.onCalibrationFinished(calibrationData)
}
}
}
private val statusCallback: StatusCallback = object : StatusCallback {
override fun onStarted() {
for (statusCallback in statusCallbacks) {
statusCallback.onStarted()
}
}
override fun onStopped(statusErrorType: StatusErrorType) {
for (statusCallback in statusCallbacks) {
statusCallback.onStopped(statusErrorType)
}
}
}
private val userStatusCallback: UserStatusCallback = object : UserStatusCallback {
override fun onAttention(timestampBegin: Long, timestampEnd: Long, score: Float) {
for (userStatusCallback in userStatusCallbacks) {
userStatusCallback.onAttention(timestampBegin, timestampEnd, score)
}
}
override fun onBlink(
timestamp: Long,
isBlinkLeft: Boolean,
isBlinkRight: Boolean,
isBlink: Boolean,
leftOpenness: Float,
rightOpenness: Float
) {
for (userStatusCallback in userStatusCallbacks) {
userStatusCallback.onBlink(
timestamp,
isBlinkLeft,
isBlinkRight,
isBlink,
leftOpenness,
rightOpenness
)
}
}
override fun onDrowsiness(timestamp: Long, isDrowsiness: Boolean, intensity: Float) {
for (userStatusCallback in userStatusCallbacks) {
userStatusCallback.onDrowsiness(timestamp, isDrowsiness, intensity);
}
}
}
}