ilabs-flir 2.2.12 → 2.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/Flir/src/main/java/flir/android/FlirManager.kt +89 -265
- package/android/Flir/src/main/java/flir/android/FlirSdkManager.java +77 -533
- package/ios/Flir/src/FlirManager.swift +222 -887
- package/ios/Flir/src/FlirModule.m +111 -109
- package/ios/Flir/src/FlirState.m +16 -5
- package/package.json +1 -1
|
@@ -4,7 +4,6 @@ import android.content.Context
|
|
|
4
4
|
import android.graphics.Bitmap
|
|
5
5
|
import android.util.Log
|
|
6
6
|
import com.facebook.react.bridge.Arguments
|
|
7
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
7
|
import com.facebook.react.bridge.ReactContext
|
|
9
8
|
import com.facebook.react.bridge.WritableArray
|
|
10
9
|
import com.facebook.react.bridge.WritableMap
|
|
@@ -17,17 +16,15 @@ import java.util.concurrent.atomic.AtomicLong
|
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Simplified FlirManager - bridge between React Native and FlirSdkManager
|
|
20
|
-
*
|
|
21
|
-
* Let React Native handle any filtering logic
|
|
19
|
+
* Matches the simplified pattern: scan -> connect -> stream -> disconnect
|
|
22
20
|
*/
|
|
23
21
|
object FlirManager {
|
|
24
22
|
private const val TAG = "FlirManager"
|
|
25
23
|
|
|
26
24
|
private var sdkManager: FlirSdkManager? = null
|
|
27
25
|
private var reactContext: ReactContext? = null
|
|
28
|
-
private var appContext: Context? = null
|
|
29
26
|
|
|
30
|
-
// Frame rate limiting
|
|
27
|
+
// Frame rate limiting for RN events
|
|
31
28
|
private val lastEmitMs = AtomicLong(0)
|
|
32
29
|
private val minEmitIntervalMs = 100L // ~10 fps max for RN events
|
|
33
30
|
|
|
@@ -38,8 +35,12 @@ object FlirManager {
|
|
|
38
35
|
private var isStreaming = false
|
|
39
36
|
private var connectedDeviceId: String? = null
|
|
40
37
|
private var connectedDeviceName: String? = null
|
|
38
|
+
|
|
39
|
+
// Concurrency control
|
|
40
|
+
private val shouldProcessFrames = java.util.concurrent.atomic.AtomicBoolean(false)
|
|
41
|
+
private val isUpdatingTexture = java.util.concurrent.atomic.AtomicBoolean(false)
|
|
41
42
|
|
|
42
|
-
// Latest bitmap
|
|
43
|
+
// Latest bitmap
|
|
43
44
|
private var latestBitmap: Bitmap? = null
|
|
44
45
|
|
|
45
46
|
// Callbacks
|
|
@@ -47,82 +48,49 @@ object FlirManager {
|
|
|
47
48
|
fun onTextureUpdate(bitmap: Bitmap, textureUnit: Int)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
interface TemperatureCallback {
|
|
51
|
-
fun onTemperatureData(temperature: Double, x: Int, y: Int)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
51
|
private var textureCallback: TextureUpdateCallback? = null
|
|
55
|
-
private var temperatureCallback: TemperatureCallback? = null
|
|
56
52
|
|
|
57
53
|
fun setTextureCallback(callback: TextureUpdateCallback?) {
|
|
58
54
|
textureCallback = callback
|
|
59
55
|
}
|
|
60
56
|
|
|
61
|
-
fun setTemperatureCallback(callback: TemperatureCallback?) {
|
|
62
|
-
temperatureCallback = callback
|
|
63
|
-
}
|
|
64
|
-
|
|
65
57
|
fun getLatestBitmap(): Bitmap? = latestBitmap
|
|
66
58
|
|
|
67
|
-
//
|
|
68
|
-
fun setPreferSdkRotation(prefer: Boolean) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
fun
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
fun getBatteryLevel(): Int {
|
|
77
|
-
return sdkManager?.getBatteryLevel() ?: -1
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
fun isBatteryCharging(): Boolean {
|
|
81
|
-
return sdkManager?.isBatteryCharging() ?: false
|
|
82
|
-
}
|
|
59
|
+
// Stubs for removed features
|
|
60
|
+
fun setPreferSdkRotation(prefer: Boolean) { /* No-op */ }
|
|
61
|
+
fun isPreferSdkRotation(): Boolean = false
|
|
62
|
+
fun getBatteryLevel(): Int = -1
|
|
63
|
+
fun isBatteryCharging(): Boolean = false
|
|
64
|
+
fun setPalette(name: String) { /* No-op */ }
|
|
65
|
+
fun getAvailablePalettes(): List<String> = emptyList()
|
|
83
66
|
|
|
84
67
|
/**
|
|
85
68
|
* Initialize the FLIR SDK
|
|
86
69
|
*/
|
|
87
70
|
fun init(context: Context) {
|
|
88
|
-
// Store react context for event emission if it's a React context
|
|
89
|
-
// Always update if we get a valid ReactContext (in case previous was stale)
|
|
90
71
|
if (context is ReactContext) {
|
|
91
|
-
Log.d(TAG, "[Flir-BRIDGE-LOAD] Storing ReactContext for event emission: ${context.javaClass.simpleName}")
|
|
92
72
|
reactContext = context
|
|
93
|
-
} else {
|
|
94
|
-
Log.d(TAG, "[Flir-BRIDGE-LOAD] Context is not ReactContext: ${context.javaClass.simpleName}")
|
|
95
73
|
}
|
|
96
74
|
|
|
97
|
-
if (isInitialized)
|
|
98
|
-
Log.d(TAG, "[Flir-BRIDGE-LOAD] Already initialized")
|
|
99
|
-
return
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
appContext = context.applicationContext
|
|
75
|
+
if (isInitialized) return
|
|
103
76
|
|
|
104
77
|
sdkManager = FlirSdkManager.getInstance(context)
|
|
105
78
|
sdkManager?.setListener(sdkListener)
|
|
106
79
|
sdkManager?.initialize()
|
|
107
80
|
|
|
108
81
|
isInitialized = true
|
|
109
|
-
Log.i(TAG, "
|
|
82
|
+
Log.i(TAG, "FlirManager initialized")
|
|
110
83
|
}
|
|
111
84
|
|
|
112
85
|
/**
|
|
113
|
-
* Start scanning
|
|
86
|
+
* Start scanning
|
|
114
87
|
*/
|
|
115
88
|
fun startDiscovery(retry: Boolean = false) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (!isInitialized && appContext != null) {
|
|
119
|
-
init(appContext!!)
|
|
89
|
+
if (!isInitialized && reactContext != null) {
|
|
90
|
+
init(reactContext!!)
|
|
120
91
|
}
|
|
121
92
|
|
|
122
|
-
if (isScanning && !retry)
|
|
123
|
-
Log.d(TAG, "Already scanning")
|
|
124
|
-
return
|
|
125
|
-
}
|
|
93
|
+
if (isScanning && !retry) return
|
|
126
94
|
|
|
127
95
|
isScanning = true
|
|
128
96
|
emitDeviceState("discovering")
|
|
@@ -141,13 +109,12 @@ object FlirManager {
|
|
|
141
109
|
* Stop scanning
|
|
142
110
|
*/
|
|
143
111
|
fun stopDiscovery() {
|
|
144
|
-
|
|
145
|
-
sdkManager?.stop()
|
|
112
|
+
sdkManager?.stopScan()
|
|
146
113
|
isScanning = false
|
|
147
114
|
}
|
|
148
115
|
|
|
149
116
|
/**
|
|
150
|
-
* Connect to a device
|
|
117
|
+
* Connect to a device
|
|
151
118
|
*/
|
|
152
119
|
fun connectToDevice(deviceId: String) {
|
|
153
120
|
Log.i(TAG, "connectToDevice: $deviceId")
|
|
@@ -156,52 +123,19 @@ object FlirManager {
|
|
|
156
123
|
val identity = devices.find { it.deviceId == deviceId }
|
|
157
124
|
|
|
158
125
|
if (identity != null) {
|
|
159
|
-
|
|
126
|
+
shouldProcessFrames.set(true)
|
|
160
127
|
sdkManager?.connect(identity)
|
|
161
128
|
} else {
|
|
162
|
-
Log.e(TAG, "
|
|
129
|
+
Log.e(TAG, "Device not found: $deviceId")
|
|
163
130
|
emitError("Device not found: $deviceId")
|
|
164
131
|
}
|
|
165
132
|
}
|
|
166
133
|
|
|
167
134
|
/**
|
|
168
|
-
*
|
|
169
|
-
*/
|
|
170
|
-
fun switchToDevice(deviceId: String) {
|
|
171
|
-
if (deviceId == connectedDeviceId) {
|
|
172
|
-
Log.d(TAG, "Already connected to: $deviceId")
|
|
173
|
-
return
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Disconnect current and connect new
|
|
177
|
-
if (isConnected) {
|
|
178
|
-
sdkManager?.disconnect()
|
|
179
|
-
}
|
|
180
|
-
connectToDevice(deviceId)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Start streaming from connected device
|
|
185
|
-
*/
|
|
186
|
-
fun startStream() {
|
|
187
|
-
Log.i(TAG, "startStream")
|
|
188
|
-
sdkManager?.startStream()
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Stop streaming
|
|
193
|
-
*/
|
|
194
|
-
fun stopStream() {
|
|
195
|
-
Log.i(TAG, "[Flir-BRIDGE-STREAMING] stopStream")
|
|
196
|
-
sdkManager?.stopStream()
|
|
197
|
-
isStreaming = false
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Disconnect from current device
|
|
135
|
+
* Disconnect
|
|
202
136
|
*/
|
|
203
137
|
fun disconnect() {
|
|
204
|
-
|
|
138
|
+
shouldProcessFrames.set(false)
|
|
205
139
|
sdkManager?.disconnect()
|
|
206
140
|
isConnected = false
|
|
207
141
|
isStreaming = false
|
|
@@ -213,49 +147,33 @@ object FlirManager {
|
|
|
213
147
|
* Stop everything
|
|
214
148
|
*/
|
|
215
149
|
fun stop() {
|
|
216
|
-
|
|
217
|
-
stopStream()
|
|
150
|
+
shouldProcessFrames.set(false)
|
|
218
151
|
disconnect()
|
|
219
152
|
stopDiscovery()
|
|
220
153
|
latestBitmap = null
|
|
221
154
|
}
|
|
222
155
|
|
|
156
|
+
// Stub legacy methods
|
|
157
|
+
fun startStream() { /* handled automatically by connect */ }
|
|
158
|
+
fun stopStream() { sdkManager?.stopStream() }
|
|
159
|
+
|
|
223
160
|
/**
|
|
224
|
-
* Get temperature
|
|
161
|
+
* Get temperature
|
|
225
162
|
*/
|
|
226
163
|
fun getTemperatureAt(x: Int, y: Int): Double? {
|
|
227
|
-
|
|
164
|
+
val temp = sdkManager?.getTemperatureAt(x, y)
|
|
165
|
+
return if (temp != null && !temp.isNaN()) temp else null
|
|
228
166
|
}
|
|
229
167
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
fun getTemperatureAtNormalized(normalizedX: Double, normalizedY: Double): Double? {
|
|
234
|
-
return sdkManager?.getTemperatureAtNormalized(normalizedX, normalizedY)?.takeIf { !it.isNaN() }
|
|
168
|
+
fun getTemperatureAtNormalized(nx: Double, ny: Double): Double? {
|
|
169
|
+
// Not implemented in simplified version
|
|
170
|
+
return null
|
|
235
171
|
}
|
|
236
172
|
|
|
237
|
-
/**
|
|
238
|
-
* Alias for getTemperatureAt
|
|
239
|
-
*/
|
|
240
173
|
fun getTemperatureAtPoint(x: Int, y: Int): Double? = getTemperatureAt(x, y)
|
|
241
174
|
|
|
242
175
|
/**
|
|
243
|
-
*
|
|
244
|
-
*/
|
|
245
|
-
fun setPalette(name: String) {
|
|
246
|
-
Log.d(TAG, "setPalette: $name")
|
|
247
|
-
sdkManager?.setPalette(name)
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Get available palettes
|
|
252
|
-
*/
|
|
253
|
-
fun getAvailablePalettes(): List<String> {
|
|
254
|
-
return sdkManager?.availablePalettes ?: emptyList()
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Get list of discovered devices
|
|
176
|
+
* Get discovered devices
|
|
259
177
|
*/
|
|
260
178
|
fun getDiscoveredDevices(): List<Identity> {
|
|
261
179
|
return sdkManager?.discoveredDevices ?: emptyList()
|
|
@@ -269,14 +187,11 @@ object FlirManager {
|
|
|
269
187
|
fun isEmulator(): Boolean = connectedDeviceName?.contains("EMULAT", ignoreCase = true) == true
|
|
270
188
|
fun isDeviceConnected(): Boolean = isConnected
|
|
271
189
|
|
|
272
|
-
/**
|
|
273
|
-
* Get connected device info
|
|
274
|
-
*/
|
|
275
190
|
fun getConnectedDeviceInfo(): String {
|
|
276
191
|
return connectedDeviceName ?: "Not connected"
|
|
277
192
|
}
|
|
278
193
|
|
|
279
|
-
|
|
194
|
+
/**
|
|
280
195
|
* Get latest frame as file path (for RN)
|
|
281
196
|
*/
|
|
282
197
|
fun getLatestFramePath(): String? {
|
|
@@ -288,7 +203,6 @@ object FlirManager {
|
|
|
288
203
|
}
|
|
289
204
|
file.absolutePath
|
|
290
205
|
} catch (t: Throwable) {
|
|
291
|
-
Log.e(TAG, "Failed to save frame", t)
|
|
292
206
|
null
|
|
293
207
|
}
|
|
294
208
|
}
|
|
@@ -296,30 +210,24 @@ object FlirManager {
|
|
|
296
210
|
// SDK Listener
|
|
297
211
|
private val sdkListener = object : FlirSdkManager.Listener {
|
|
298
212
|
override fun onDeviceFound(identity: Identity) {
|
|
299
|
-
|
|
213
|
+
// Devices updated event handles the list, but we can log unique finds
|
|
300
214
|
}
|
|
301
215
|
|
|
302
216
|
override fun onDeviceListUpdated(devices: List<Identity>) {
|
|
303
|
-
Log.
|
|
304
|
-
devices.forEach {
|
|
305
|
-
Log.d(TAG, " - ${it.deviceId} (${it.communicationInterface})")
|
|
306
|
-
}
|
|
217
|
+
Log.d(TAG, "Devices found: ${devices.size}")
|
|
307
218
|
emitDevicesFound(devices)
|
|
308
219
|
}
|
|
309
220
|
|
|
310
|
-
override fun onConnected(identity: Identity
|
|
311
|
-
Log.i(TAG, "Connected to: ${identity
|
|
221
|
+
override fun onConnected(identity: Identity) {
|
|
222
|
+
Log.i(TAG, "Connected to: ${identity.deviceId}")
|
|
312
223
|
isConnected = true
|
|
313
|
-
connectedDeviceId = identity
|
|
314
|
-
connectedDeviceName = identity
|
|
224
|
+
connectedDeviceId = identity.deviceId
|
|
225
|
+
connectedDeviceName = identity.deviceId
|
|
315
226
|
emitDeviceState("connected")
|
|
316
|
-
|
|
317
|
-
// Auto-start streaming when connected
|
|
318
|
-
startStream()
|
|
319
227
|
}
|
|
320
228
|
|
|
321
229
|
override fun onDisconnected() {
|
|
322
|
-
Log.i(TAG, "
|
|
230
|
+
Log.i(TAG, "Disconnected")
|
|
323
231
|
isConnected = false
|
|
324
232
|
isStreaming = false
|
|
325
233
|
connectedDeviceId = null
|
|
@@ -328,53 +236,46 @@ object FlirManager {
|
|
|
328
236
|
}
|
|
329
237
|
|
|
330
238
|
override fun onFrame(bitmap: Bitmap) {
|
|
331
|
-
|
|
239
|
+
// IMMEDIATE STOP CHECK
|
|
240
|
+
if (!shouldProcessFrames.get()) {
|
|
332
241
|
return
|
|
333
242
|
}
|
|
334
|
-
|
|
243
|
+
|
|
335
244
|
latestBitmap = bitmap
|
|
336
|
-
isStreaming = true
|
|
337
245
|
|
|
338
|
-
//
|
|
246
|
+
// If this is the first frame, notify JS that we are now streaming
|
|
247
|
+
if (!isStreaming) {
|
|
248
|
+
isStreaming = true
|
|
249
|
+
emitDeviceState("streaming")
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// NON-BLOCKING TEXTURE UPDATE (Drop frames if busy)
|
|
339
253
|
if (textureCallback != null) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
254
|
+
if (isUpdatingTexture.compareAndSet(false, true)) {
|
|
255
|
+
try {
|
|
256
|
+
textureCallback?.onTextureUpdate(bitmap, 0)
|
|
257
|
+
} finally {
|
|
258
|
+
isUpdatingTexture.set(false)
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
// Log.v(TAG, "Dropping frame - texture update busy")
|
|
345
262
|
}
|
|
346
263
|
}
|
|
347
264
|
|
|
348
|
-
//
|
|
349
|
-
emitFrameToReactNative(bitmap)
|
|
265
|
+
// Notify RN - disabled
|
|
266
|
+
// emitFrameToReactNative(bitmap)
|
|
350
267
|
}
|
|
351
268
|
|
|
352
269
|
override fun onError(message: String) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// Parse error code if present (format: "CODE: message")
|
|
356
|
-
val parts = message.split(": ", limit = 2)
|
|
357
|
-
val errorCode = if (parts.size == 2) parts[0] else "FLIR_ERROR"
|
|
358
|
-
val errorMessage = if (parts.size == 2) parts[1] else message
|
|
359
|
-
|
|
360
|
-
// Auto-disable streaming on critical errors to allow retry
|
|
361
|
-
if (errorCode.contains("NATIVE") || errorCode.contains("INIT")) {
|
|
362
|
-
Log.w(TAG, "[Flir-BRIDGE-ERROR] Critical error detected, stopping stream")
|
|
363
|
-
isStreaming = false
|
|
364
|
-
stopStream()
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
emitError(errorCode, errorMessage)
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
override fun onBatteryUpdated(level: Int, isCharging: Boolean) {
|
|
371
|
-
Log.d(TAG, "[Flir-BRIDGE-BATTERY] onBatteryUpdated: level=$level charging=$isCharging")
|
|
372
|
-
emitBatteryState(level, isCharging)
|
|
270
|
+
emitError(message)
|
|
373
271
|
}
|
|
374
272
|
}
|
|
375
273
|
|
|
376
|
-
// React Native
|
|
274
|
+
// React Native Emitters
|
|
275
|
+
|
|
377
276
|
private fun emitFrameToReactNative(bitmap: Bitmap) {
|
|
277
|
+
// PERF: Disabled to reduce bridge traffic
|
|
278
|
+
/*
|
|
378
279
|
val now = System.currentTimeMillis()
|
|
379
280
|
if (now - lastEmitMs.get() < minEmitIntervalMs) return
|
|
380
281
|
lastEmitMs.set(now)
|
|
@@ -388,18 +289,12 @@ object FlirManager {
|
|
|
388
289
|
}
|
|
389
290
|
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
390
291
|
.emit("FlirFrameReceived", params)
|
|
391
|
-
} catch (e: Exception) {
|
|
392
|
-
|
|
393
|
-
}
|
|
292
|
+
} catch (e: Exception) { }
|
|
293
|
+
*/
|
|
394
294
|
}
|
|
395
295
|
|
|
396
296
|
private fun emitDeviceState(state: String) {
|
|
397
|
-
val ctx = reactContext
|
|
398
|
-
if (ctx == null) {
|
|
399
|
-
Log.e(TAG, "[Flir-BRIDGE-ERROR] Cannot emit FlirDeviceConnected($state) - reactContext is null!")
|
|
400
|
-
return
|
|
401
|
-
}
|
|
402
|
-
Log.d(TAG, "[Flir-BRIDGE-CONNECTION] Emitting FlirDeviceConnected: $state")
|
|
297
|
+
val ctx = reactContext ?: return
|
|
403
298
|
try {
|
|
404
299
|
val params = Arguments.createMap().apply {
|
|
405
300
|
putString("state", state)
|
|
@@ -407,28 +302,20 @@ object FlirManager {
|
|
|
407
302
|
putBoolean("isStreaming", isStreaming)
|
|
408
303
|
putBoolean("isEmulator", isEmulator())
|
|
409
304
|
connectedDeviceName?.let { putString("deviceName", it) }
|
|
410
|
-
connectedDeviceId?.let { putString("deviceId", it) }
|
|
411
305
|
}
|
|
412
306
|
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
413
307
|
.emit("FlirDeviceConnected", params)
|
|
414
|
-
} catch (e: Exception) {
|
|
415
|
-
Log.e(TAG, "Failed to emit device state", e)
|
|
416
|
-
}
|
|
308
|
+
} catch (e: Exception) { }
|
|
417
309
|
}
|
|
418
310
|
|
|
419
311
|
private fun emitDevicesFound(devices: List<Identity>) {
|
|
420
|
-
val ctx = reactContext
|
|
421
|
-
if (ctx == null) {
|
|
422
|
-
Log.e(TAG, "Cannot emit FlirDevicesFound - reactContext is null!")
|
|
423
|
-
return
|
|
424
|
-
}
|
|
425
|
-
Log.d(TAG, "Emitting FlirDevicesFound with ${devices.size} devices")
|
|
312
|
+
val ctx = reactContext ?: return
|
|
426
313
|
try {
|
|
427
314
|
val params = Arguments.createMap()
|
|
428
315
|
val devicesArray: WritableArray = Arguments.createArray()
|
|
429
316
|
|
|
430
317
|
devices.forEach { identity ->
|
|
431
|
-
val deviceMap
|
|
318
|
+
val deviceMap = Arguments.createMap().apply {
|
|
432
319
|
putString("id", identity.deviceId)
|
|
433
320
|
putString("name", identity.deviceId)
|
|
434
321
|
putString("communicationType", identity.communicationInterface.name)
|
|
@@ -442,97 +329,34 @@ object FlirManager {
|
|
|
442
329
|
|
|
443
330
|
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
444
331
|
.emit("FlirDevicesFound", params)
|
|
445
|
-
|
|
446
|
-
} catch (e: Exception) {
|
|
447
|
-
Log.e(TAG, "[Flir-BRIDGE-ERROR] Failed to emit devices found", e)
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
private fun emitBatteryState(level: Int, isCharging: Boolean) {
|
|
452
|
-
val ctx = reactContext
|
|
453
|
-
if (ctx == null) {
|
|
454
|
-
Log.w(TAG, "Cannot emit FlirBatteryUpdated - reactContext is null!")
|
|
455
|
-
return
|
|
456
|
-
}
|
|
457
|
-
try {
|
|
458
|
-
val params = Arguments.createMap().apply {
|
|
459
|
-
putInt("level", level)
|
|
460
|
-
putBoolean("isCharging", isCharging)
|
|
461
|
-
}
|
|
462
|
-
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
463
|
-
.emit("FlirBatteryUpdated", params)
|
|
464
|
-
} catch (e: Exception) {
|
|
465
|
-
Log.e(TAG, "Failed to emit battery state", e)
|
|
466
|
-
}
|
|
332
|
+
} catch (e: Exception) { }
|
|
467
333
|
}
|
|
468
334
|
|
|
469
335
|
private fun emitError(message: String) {
|
|
470
|
-
emitError("FLIR_ERROR", message)
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
private fun emitError(errorCode: String, message: String) {
|
|
474
336
|
val ctx = reactContext ?: return
|
|
475
337
|
try {
|
|
476
338
|
val params = Arguments.createMap().apply {
|
|
477
|
-
putString("code", errorCode)
|
|
478
339
|
putString("error", message)
|
|
479
|
-
putString("message", message)
|
|
480
|
-
putBoolean("canRetry", errorCode.contains("NATIVE") || errorCode.contains("INIT"))
|
|
340
|
+
putString("message", message)
|
|
481
341
|
}
|
|
482
342
|
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
483
343
|
.emit("FlirError", params)
|
|
484
|
-
|
|
485
|
-
} catch (e: Exception) {
|
|
486
|
-
Log.e(TAG, "Failed to emit error", e)
|
|
487
|
-
}
|
|
344
|
+
} catch (e: Exception) { }
|
|
488
345
|
}
|
|
489
346
|
|
|
490
|
-
// Legacy
|
|
491
|
-
@JvmStatic
|
|
492
|
-
fun getInstance(): FlirManager = this
|
|
347
|
+
// Legacy methods placeholders
|
|
348
|
+
@JvmStatic fun getInstance(): FlirManager = this
|
|
493
349
|
|
|
494
350
|
interface DiscoveryCallback {
|
|
495
351
|
fun onDeviceFound(deviceName: String)
|
|
496
352
|
fun onDiscoveryTimeout()
|
|
497
353
|
fun onEmulatorEnabled()
|
|
498
354
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
fun
|
|
503
|
-
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// Legacy methods - no-ops or simple forwards
|
|
507
|
-
fun setEmulatorMode(enabled: Boolean) {
|
|
508
|
-
Log.d(TAG, "setEmulatorMode($enabled) - legacy, use startDiscovery() instead")
|
|
509
|
-
if (enabled) {
|
|
510
|
-
startDiscovery(retry = true)
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
fun enableEmulatorMode() = setEmulatorMode(true)
|
|
515
|
-
|
|
516
|
-
fun forceEmulatorMode(type: String = "FLIR_ONE_EDGE") {
|
|
517
|
-
Log.d(TAG, "forceEmulatorMode($type) - legacy, use startDiscovery() instead")
|
|
518
|
-
startDiscovery(retry = true)
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
fun setPreferredEmulatorType(type: String) {
|
|
522
|
-
Log.d(TAG, "setPreferredEmulatorType($type) - legacy, no longer used")
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
fun updateAcol(value: Float) {
|
|
526
|
-
// No-op - not used in simplified version
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Cleanup
|
|
531
|
-
*/
|
|
532
|
-
fun destroy() {
|
|
533
|
-
stop()
|
|
534
|
-
sdkManager?.destroy()
|
|
535
|
-
sdkManager = null
|
|
536
|
-
isInitialized = false
|
|
537
|
-
}
|
|
355
|
+
fun setDiscoveryCallback(callback: DiscoveryCallback?) { /* No-op */ }
|
|
356
|
+
fun setEmulatorMode(enabled: Boolean) { startDiscovery() }
|
|
357
|
+
fun enableEmulatorMode() = startDiscovery()
|
|
358
|
+
fun forceEmulatorMode(type: String = "FLIR_ONE_EDGE") { startDiscovery() }
|
|
359
|
+
fun setPreferredEmulatorType(type: String) { }
|
|
360
|
+
fun updateAcol(value: Float) { }
|
|
361
|
+
fun destroy() { stop() }
|
|
538
362
|
}
|