ilabs-flir 1.0.3 → 1.0.5
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/build.gradle.kts +14 -27
- package/android/Flir/libs/androidsdk-release.aar +0 -0
- package/android/Flir/libs/thermalsdk-release.aar +0 -0
- package/android/Flir/src/main/java/flir/android/FlirCommands.java +40 -15
- package/android/Flir/src/main/java/flir/android/FlirDownloadManager.kt +26 -46
- package/android/Flir/src/main/java/flir/android/FlirManager.kt +265 -42
- package/android/Flir/src/main/java/flir/android/FlirModule.kt +32 -0
- package/android/Flir/src/main/java/flir/android/FlirSDKLoader.kt +84 -195
- package/android/Flir/src/main/java/flir/android/FlirSdkManager.java +667 -797
- package/package.json +1 -1
- package/sdk-manifest.json +14 -7
- package/src/index.d.ts +21 -1
- package/android/Flir/libs/flir-stubs.jar +0 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/ErrorCodeException.java +0 -14
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/ImageBuffer.java +0 -11
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/JavaImageBuffer.java +0 -35
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/Palette.java +0 -15
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/PaletteManager.java +0 -16
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/Point.java +0 -11
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/ThermalImage.java +0 -23
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/ThermalValue.java +0 -9
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/CameraType.java +0 -8
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/CommunicationInterface.java +0 -16
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/Identity.java +0 -23
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/IpSettings.java +0 -9
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/connectivity/ConnectionStatusListener.java +0 -7
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/remote/OnReceived.java +0 -5
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/remote/OnRemoteError.java +0 -7
- package/android/Flir/src/main/java/flir/android/CameraHandler.java +0 -224
- package/android/Flir/src/main/java/flir/android/FlirConnectionManager.java +0 -354
- package/android/Flir/src/main/java/flir/android/FlirController.kt +0 -11
- package/android/Flir/src/main/java/flir/android/FlirDiscoveryManager.java +0 -236
- package/android/Flir/src/main/java/flir/android/FrameDataHolder.java +0 -14
|
@@ -4,6 +4,7 @@ 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.WritableArray
|
|
7
8
|
import com.facebook.react.bridge.WritableMap
|
|
8
9
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
9
10
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
@@ -13,16 +14,27 @@ import java.util.concurrent.atomic.AtomicLong
|
|
|
13
14
|
|
|
14
15
|
object FlirManager {
|
|
15
16
|
private val TAG = "FlirManager"
|
|
17
|
+
private val FLOW_TAG = "FLIR_FLOW" // Matching FlirSdkManager flow tag
|
|
16
18
|
private var sdkManager: FlirSdkManager? = null
|
|
17
19
|
private val lastEmitMs = AtomicLong(0)
|
|
18
20
|
private val minEmitIntervalMs = 333L // ~3 fps
|
|
19
21
|
private var discoveryStarted = false
|
|
20
22
|
private var reactContext: ThemedReactContext? = null
|
|
23
|
+
private var appContext: Context? = null
|
|
24
|
+
private var frameCount = 0 // For tracking first frame
|
|
21
25
|
|
|
22
26
|
// Emulator and device state tracking
|
|
23
27
|
private var isEmulatorMode = false
|
|
24
28
|
private var isPhysicalDeviceConnected = false
|
|
25
29
|
private var connectedDeviceName: String? = null
|
|
30
|
+
private var connectedDeviceId: String? = null
|
|
31
|
+
private var isStreaming = false
|
|
32
|
+
|
|
33
|
+
// Current emulator type preference
|
|
34
|
+
private var preferredEmulatorType = FlirSdkManager.EmulatorType.FLIR_ONE_EDGE
|
|
35
|
+
|
|
36
|
+
// Discovered devices cache
|
|
37
|
+
private var discoveredDevices: List<FlirSdkManager.DeviceInfo> = emptyList()
|
|
26
38
|
|
|
27
39
|
// GL texture callback support for native filters
|
|
28
40
|
interface TextureUpdateCallback {
|
|
@@ -63,7 +75,17 @@ object FlirManager {
|
|
|
63
75
|
/**
|
|
64
76
|
* Check if a physical FLIR device is connected
|
|
65
77
|
*/
|
|
66
|
-
fun isDeviceConnected(): Boolean = isPhysicalDeviceConnected
|
|
78
|
+
fun isDeviceConnected(): Boolean = isPhysicalDeviceConnected || isEmulatorMode
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check if currently streaming
|
|
82
|
+
*/
|
|
83
|
+
fun isStreaming(): Boolean = isStreaming
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get list of discovered devices
|
|
87
|
+
*/
|
|
88
|
+
fun getDiscoveredDevices(): List<FlirSdkManager.DeviceInfo> = discoveredDevices
|
|
67
89
|
|
|
68
90
|
/**
|
|
69
91
|
* Get information about the connected device
|
|
@@ -75,13 +97,37 @@ object FlirManager {
|
|
|
75
97
|
else -> "Physical device ($connectedDeviceName)"
|
|
76
98
|
}
|
|
77
99
|
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Set preferred emulator type (FLIR_ONE_EDGE or FLIR_ONE)
|
|
103
|
+
*/
|
|
104
|
+
fun setPreferredEmulatorType(type: String) {
|
|
105
|
+
preferredEmulatorType = when (type.uppercase()) {
|
|
106
|
+
"FLIR_ONE" -> FlirSdkManager.EmulatorType.FLIR_ONE
|
|
107
|
+
else -> FlirSdkManager.EmulatorType.FLIR_ONE_EDGE
|
|
108
|
+
}
|
|
109
|
+
Log.d(TAG, "Preferred emulator type set to: $preferredEmulatorType")
|
|
110
|
+
sdkManager?.setEmulatorType(preferredEmulatorType)
|
|
111
|
+
}
|
|
78
112
|
|
|
79
113
|
fun init(context: Context) {
|
|
114
|
+
// Avoid re-initialization if already done
|
|
115
|
+
if (sdkManager != null) {
|
|
116
|
+
Log.i(FLOW_TAG, "[FlirManager] init() called but already initialized, skipping")
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
appContext = context.applicationContext
|
|
121
|
+
Log.i(FLOW_TAG, "[FlirManager] init() called - initializing SDK Manager")
|
|
80
122
|
try {
|
|
81
|
-
// Initialize SDK manager with listener
|
|
123
|
+
// Initialize SDK manager with listener matching FlirSdkManager.Listener interface
|
|
82
124
|
sdkManager = FlirSdkManager(object : FlirSdkManager.Listener {
|
|
83
125
|
override fun onFrame(bitmap: Bitmap) {
|
|
84
126
|
latestBitmap = bitmap
|
|
127
|
+
if (frameCount == 0) {
|
|
128
|
+
Log.i(FLOW_TAG, "[FlirManager] FIRST FRAME received: ${bitmap.width}x${bitmap.height}")
|
|
129
|
+
}
|
|
130
|
+
frameCount++
|
|
85
131
|
textureCallback?.onTextureUpdate(bitmap, 0)
|
|
86
132
|
emitFrameToReactNative(bitmap)
|
|
87
133
|
}
|
|
@@ -90,64 +136,164 @@ object FlirManager {
|
|
|
90
136
|
temperatureCallback?.onTemperatureData(temp, x, y)
|
|
91
137
|
}
|
|
92
138
|
|
|
93
|
-
override fun onDeviceFound(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
139
|
+
override fun onDeviceFound(deviceId: String, deviceName: String, isEmulator: Boolean) {
|
|
140
|
+
Log.i(FLOW_TAG, "[FlirManager] Device found: $deviceName (id=$deviceId, emulator=$isEmulator)")
|
|
141
|
+
Log.d(TAG, "Device found: $deviceName (id=$deviceId, emulator=$isEmulator)")
|
|
142
|
+
discoveryCallback?.onDeviceFound(deviceName)
|
|
97
143
|
}
|
|
98
|
-
|
|
99
|
-
override fun
|
|
100
|
-
|
|
101
|
-
|
|
144
|
+
|
|
145
|
+
override fun onDeviceListUpdated(devices: MutableList<FlirSdkManager.DeviceInfo>) {
|
|
146
|
+
discoveredDevices = devices.toList()
|
|
147
|
+
Log.i(FLOW_TAG, "[FlirManager] Device list updated: ${devices.size} devices")
|
|
148
|
+
Log.i(TAG, "Device list updated: ${devices.size} devices")
|
|
149
|
+
devices.forEach {
|
|
150
|
+
Log.d(TAG, " - ${it.deviceName} (${it.commInterface}, emu=${it.isEmulator})")
|
|
151
|
+
}
|
|
152
|
+
emitDevicesFound(devices)
|
|
153
|
+
|
|
154
|
+
// Auto-connect to first device if available
|
|
155
|
+
if (devices.isNotEmpty()) {
|
|
156
|
+
val first = devices[0]
|
|
157
|
+
connectedDeviceName = first.deviceName
|
|
158
|
+
connectedDeviceId = first.deviceId
|
|
159
|
+
isEmulatorMode = first.isEmulator
|
|
160
|
+
isPhysicalDeviceConnected = !first.isEmulator
|
|
161
|
+
|
|
162
|
+
Log.i(FLOW_TAG, "[FlirManager] Auto-connecting to first device: ${first.deviceName}")
|
|
163
|
+
// Connect to the device
|
|
164
|
+
sdkManager?.connectToDevice(first.deviceId)
|
|
165
|
+
}
|
|
102
166
|
}
|
|
103
|
-
|
|
104
|
-
override fun
|
|
105
|
-
|
|
167
|
+
|
|
168
|
+
override fun onDeviceConnected(deviceId: String, deviceName: String, isEmulator: Boolean) {
|
|
169
|
+
connectedDeviceId = deviceId
|
|
170
|
+
connectedDeviceName = deviceName
|
|
171
|
+
this@FlirManager.isEmulatorMode = isEmulator
|
|
172
|
+
isPhysicalDeviceConnected = !isEmulator
|
|
173
|
+
|
|
174
|
+
Log.i(TAG, "Device connected: $deviceName (id=$deviceId, emulator=$isEmulator)")
|
|
175
|
+
emitDeviceState("connected", !isEmulator)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
override fun onDeviceDisconnected() {
|
|
179
|
+
Log.i(TAG, "Device disconnected")
|
|
180
|
+
isPhysicalDeviceConnected = false
|
|
181
|
+
isEmulatorMode = false
|
|
182
|
+
isStreaming = false
|
|
183
|
+
connectedDeviceId = null
|
|
184
|
+
connectedDeviceName = null
|
|
185
|
+
emitDeviceState("disconnected", false)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
override fun onDiscoveryStarted() {
|
|
189
|
+
Log.i(TAG, "Discovery started")
|
|
190
|
+
emitDeviceState("discovering", false)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
override fun onDiscoveryTimeout() {
|
|
194
|
+
Log.w(TAG, "Discovery timeout - no devices found")
|
|
195
|
+
discoveryCallback?.onDiscoveryTimeout()
|
|
196
|
+
emitDeviceState("discovery_timeout", false)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
override fun onStreamStarted(streamType: String) {
|
|
200
|
+
isStreaming = true
|
|
201
|
+
Log.i(TAG, "Streaming started: $streamType")
|
|
202
|
+
emitDeviceState("streaming", isPhysicalDeviceConnected)
|
|
106
203
|
}
|
|
107
|
-
|
|
204
|
+
|
|
205
|
+
override fun onError(error: String) {
|
|
206
|
+
Log.e(TAG, "SDK Error: $error")
|
|
207
|
+
emitError(error)
|
|
208
|
+
}
|
|
209
|
+
}, context)
|
|
108
210
|
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
method.invoke(null, context.applicationContext)
|
|
114
|
-
Log.i(TAG, "FLIR SDK initialized via reflection")
|
|
115
|
-
} catch (e: ClassNotFoundException) {
|
|
116
|
-
Log.w(TAG, "FLIR SDK not found on classpath, will attempt DexClassLoader")
|
|
117
|
-
} catch (e: Throwable) {
|
|
118
|
-
Log.w(TAG, "FLIR SDK init failed: ${e.message}")
|
|
119
|
-
}
|
|
211
|
+
// Set emulator type preference
|
|
212
|
+
sdkManager?.setEmulatorType(preferredEmulatorType)
|
|
213
|
+
|
|
214
|
+
Log.i(TAG, "FlirManager initialized with comprehensive SDK manager")
|
|
120
215
|
} catch (t: Throwable) {
|
|
121
216
|
Log.e(TAG, "FlirManager init failed", t)
|
|
122
217
|
}
|
|
123
218
|
}
|
|
124
219
|
|
|
125
|
-
|
|
126
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Start discovery with the specified parameters
|
|
222
|
+
* @param isEmuMode If true, immediately start emulator without physical device discovery
|
|
223
|
+
*/
|
|
224
|
+
fun startDiscoveryAndConnect(context: ThemedReactContext, isEmuMode: Boolean = false) {
|
|
225
|
+
Log.i(FLOW_TAG, "[FlirManager] startDiscoveryAndConnect called: isEmuMode=$isEmuMode, discoveryStarted=$discoveryStarted, preferredEmulatorType=$preferredEmulatorType")
|
|
226
|
+
|
|
227
|
+
if (discoveryStarted && !isEmuMode) {
|
|
228
|
+
Log.i(FLOW_TAG, "[FlirManager] Discovery already started, skipping")
|
|
229
|
+
return
|
|
230
|
+
}
|
|
127
231
|
discoveryStarted = true
|
|
128
232
|
reactContext = context
|
|
233
|
+
frameCount = 0 // Reset frame counter
|
|
129
234
|
|
|
130
235
|
emitDeviceState("discovering", false)
|
|
131
236
|
|
|
132
237
|
try {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
238
|
+
// Set emulator type preference before discovery
|
|
239
|
+
Log.i(FLOW_TAG, "[FlirManager] Setting emulator type: $preferredEmulatorType")
|
|
240
|
+
sdkManager?.setEmulatorType(preferredEmulatorType)
|
|
241
|
+
|
|
242
|
+
// Start discovery (forceEmulator=isEmuMode)
|
|
243
|
+
Log.i(FLOW_TAG, "[FlirManager] Calling sdkManager.startDiscovery(forceEmulator=$isEmuMode)")
|
|
244
|
+
Log.i(TAG, "Starting discovery (forceEmulator=$isEmuMode)")
|
|
245
|
+
sdkManager?.startDiscovery(isEmuMode)
|
|
138
246
|
} catch (t: Throwable) {
|
|
247
|
+
Log.e(FLOW_TAG, "[FlirManager] startDiscoveryAndConnect failed: ${t.message}")
|
|
139
248
|
Log.e(TAG, "startDiscoveryAndConnect failed", t)
|
|
140
249
|
emitDeviceState("error", false)
|
|
141
250
|
}
|
|
142
251
|
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Legacy overload for backward compatibility
|
|
255
|
+
*/
|
|
256
|
+
fun startDiscoveryAndConnect(context: ThemedReactContext) {
|
|
257
|
+
startDiscoveryAndConnect(context, isEmuMode = false)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Switch to a specific device by ID
|
|
262
|
+
*/
|
|
263
|
+
fun switchToDevice(deviceId: String) {
|
|
264
|
+
if (deviceId == connectedDeviceId) {
|
|
265
|
+
Log.d(TAG, "Already connected to device: $deviceId")
|
|
266
|
+
return
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
Log.i(TAG, "Switching to device: $deviceId")
|
|
270
|
+
sdkManager?.connectToDevice(deviceId)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Start emulator mode
|
|
275
|
+
*/
|
|
276
|
+
fun startEmulator(type: FlirSdkManager.EmulatorType = preferredEmulatorType) {
|
|
277
|
+
Log.i(TAG, "Starting emulator: $type")
|
|
278
|
+
sdkManager?.setEmulatorType(type)
|
|
279
|
+
sdkManager?.startDiscovery(true) // forceEmulator = true
|
|
280
|
+
}
|
|
143
281
|
|
|
144
282
|
fun stop() {
|
|
283
|
+
Log.i(TAG, "Stopping FlirManager")
|
|
284
|
+
|
|
285
|
+
// Stop the SDK manager
|
|
286
|
+
sdkManager?.stop()
|
|
287
|
+
|
|
288
|
+
// Reset state
|
|
145
289
|
discoveryStarted = false
|
|
146
290
|
isPhysicalDeviceConnected = false
|
|
147
291
|
isEmulatorMode = false
|
|
292
|
+
isStreaming = false
|
|
148
293
|
connectedDeviceName = null
|
|
294
|
+
connectedDeviceId = null
|
|
149
295
|
latestBitmap = null
|
|
150
|
-
|
|
296
|
+
discoveredDevices = emptyList()
|
|
151
297
|
}
|
|
152
298
|
|
|
153
299
|
fun getLatestFramePath(): String? {
|
|
@@ -193,15 +339,59 @@ object FlirManager {
|
|
|
193
339
|
params.putString("state", state)
|
|
194
340
|
params.putBoolean("isPhysical", isPhysical)
|
|
195
341
|
params.putBoolean("isEmulator", isEmulatorMode)
|
|
196
|
-
params.putBoolean("isConnected", isPhysicalDeviceConnected)
|
|
342
|
+
params.putBoolean("isConnected", isPhysicalDeviceConnected || isEmulatorMode)
|
|
343
|
+
params.putBoolean("isStreaming", isStreaming)
|
|
197
344
|
|
|
198
345
|
connectedDeviceName?.let {
|
|
199
346
|
params.putString("deviceName", it)
|
|
200
347
|
}
|
|
348
|
+
connectedDeviceId?.let {
|
|
349
|
+
params.putString("deviceId", it)
|
|
350
|
+
}
|
|
201
351
|
|
|
202
352
|
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
203
353
|
.emit("FlirDeviceConnected", params)
|
|
204
|
-
} catch (e: Exception) {
|
|
354
|
+
} catch (e: Exception) {
|
|
355
|
+
Log.e(TAG, "Failed to emit device state", e)
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
private fun emitDevicesFound(devices: List<FlirSdkManager.DeviceInfo>) {
|
|
360
|
+
val ctx = reactContext ?: return
|
|
361
|
+
try {
|
|
362
|
+
val params = Arguments.createMap()
|
|
363
|
+
val devicesArray: WritableArray = Arguments.createArray()
|
|
364
|
+
|
|
365
|
+
devices.forEach { device ->
|
|
366
|
+
val deviceMap: WritableMap = Arguments.createMap()
|
|
367
|
+
deviceMap.putString("id", device.deviceId)
|
|
368
|
+
deviceMap.putString("name", device.deviceName)
|
|
369
|
+
deviceMap.putString("communicationType", device.commInterface.name)
|
|
370
|
+
deviceMap.putBoolean("isEmulator", device.isEmulator)
|
|
371
|
+
devicesArray.pushMap(deviceMap)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
params.putArray("devices", devicesArray)
|
|
375
|
+
params.putInt("count", devices.size)
|
|
376
|
+
|
|
377
|
+
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
378
|
+
.emit("FlirDevicesFound", params)
|
|
379
|
+
} catch (e: Exception) {
|
|
380
|
+
Log.e(TAG, "Failed to emit devices found", e)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
private fun emitError(message: String) {
|
|
385
|
+
val ctx = reactContext ?: return
|
|
386
|
+
try {
|
|
387
|
+
val params = Arguments.createMap()
|
|
388
|
+
params.putString("error", message)
|
|
389
|
+
|
|
390
|
+
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
391
|
+
.emit("FlirError", params)
|
|
392
|
+
} catch (e: Exception) {
|
|
393
|
+
Log.e(TAG, "Failed to emit error", e)
|
|
394
|
+
}
|
|
205
395
|
}
|
|
206
396
|
|
|
207
397
|
// Compatibility for Java / FlirHelper
|
|
@@ -225,9 +415,10 @@ object FlirManager {
|
|
|
225
415
|
}
|
|
226
416
|
|
|
227
417
|
fun setEmulatorMode(enabled: Boolean) {
|
|
228
|
-
isEmulatorMode = enabled
|
|
229
418
|
if (enabled) {
|
|
230
|
-
|
|
419
|
+
isEmulatorMode = true
|
|
420
|
+
discoveryCallback?.onEmulatorEnabled()
|
|
421
|
+
startEmulator(preferredEmulatorType)
|
|
231
422
|
}
|
|
232
423
|
}
|
|
233
424
|
|
|
@@ -236,19 +427,51 @@ object FlirManager {
|
|
|
236
427
|
}
|
|
237
428
|
|
|
238
429
|
fun startDiscovery(retry: Boolean) {
|
|
239
|
-
if (
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
430
|
+
Log.i(FLOW_TAG, "[FlirManager] startDiscovery($retry) called, sdkManager=${if (sdkManager != null) "present" else "NULL"}, appContext=${if (appContext != null) "present" else "NULL"}")
|
|
431
|
+
|
|
432
|
+
// Auto-init if not initialized
|
|
433
|
+
if (sdkManager == null && appContext != null) {
|
|
434
|
+
Log.i(FLOW_TAG, "[FlirManager] Auto-initializing from startDiscovery()")
|
|
435
|
+
init(appContext!!)
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
val ctx = reactContext
|
|
439
|
+
if (ctx != null) {
|
|
440
|
+
// Reset discovery state if retrying
|
|
441
|
+
if (retry) {
|
|
442
|
+
discoveryStarted = false
|
|
443
|
+
}
|
|
444
|
+
startDiscoveryAndConnect(ctx, isEmuMode = false)
|
|
445
|
+
} else if (appContext != null) {
|
|
446
|
+
// Fallback: try to start discovery without React context
|
|
243
447
|
try {
|
|
244
|
-
|
|
448
|
+
Log.w(TAG, "Starting discovery without React context")
|
|
449
|
+
Log.i(FLOW_TAG, "[FlirManager] Calling sdkManager.startDiscovery(false) without React context")
|
|
450
|
+
sdkManager?.startDiscovery(false)
|
|
245
451
|
} catch (t: Throwable) {
|
|
246
452
|
Log.e(TAG, "startDiscovery failed", t)
|
|
453
|
+
Log.e(FLOW_TAG, "[FlirManager] startDiscovery failed: ${t.message}")
|
|
247
454
|
}
|
|
455
|
+
} else {
|
|
456
|
+
Log.e(FLOW_TAG, "[FlirManager] Cannot startDiscovery - no context available! Call init(context) first.")
|
|
248
457
|
}
|
|
249
458
|
}
|
|
250
459
|
|
|
251
460
|
fun enableEmulatorMode() {
|
|
252
461
|
setEmulatorMode(true)
|
|
253
462
|
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Force start with emulator (useful for testing)
|
|
466
|
+
*/
|
|
467
|
+
fun forceEmulatorMode(type: String = "FLIR_ONE_EDGE") {
|
|
468
|
+
setPreferredEmulatorType(type)
|
|
469
|
+
val ctx = reactContext
|
|
470
|
+
if (ctx != null) {
|
|
471
|
+
discoveryStarted = false
|
|
472
|
+
startDiscoveryAndConnect(ctx, isEmuMode = true)
|
|
473
|
+
} else {
|
|
474
|
+
startEmulator(preferredEmulatorType)
|
|
475
|
+
}
|
|
476
|
+
}
|
|
254
477
|
}
|
|
@@ -71,4 +71,36 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
71
71
|
promise.reject("ERR_FLIR_DEVICE_INFO", e)
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
+
|
|
75
|
+
@ReactMethod
|
|
76
|
+
fun isSDKDownloaded(promise: Promise) {
|
|
77
|
+
try {
|
|
78
|
+
val available = FlirSDKLoader.isSDKAvailable(reactContext)
|
|
79
|
+
promise.resolve(available)
|
|
80
|
+
} catch (e: Exception) {
|
|
81
|
+
promise.reject("ERR_FLIR_SDK_CHECK", e)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@ReactMethod
|
|
86
|
+
fun getSDKStatus(promise: Promise) {
|
|
87
|
+
try {
|
|
88
|
+
val available = FlirSDKLoader.isSDKAvailable(reactContext)
|
|
89
|
+
val arch = FlirSDKLoader.getDeviceArch()
|
|
90
|
+
val dexPath = FlirSDKLoader.getDexPath(reactContext)
|
|
91
|
+
val nativeLibDir = FlirSDKLoader.getNativeLibDir(reactContext)
|
|
92
|
+
|
|
93
|
+
val result = com.facebook.react.bridge.Arguments.createMap()
|
|
94
|
+
result.putBoolean("available", available)
|
|
95
|
+
result.putString("arch", arch)
|
|
96
|
+
result.putString("dexPath", dexPath?.absolutePath ?: "not downloaded")
|
|
97
|
+
result.putString("nativeLibPath", nativeLibDir?.absolutePath ?: "not downloaded")
|
|
98
|
+
result.putBoolean("dexExists", dexPath?.exists() == true)
|
|
99
|
+
result.putBoolean("nativeLibsExist", nativeLibDir?.exists() == true)
|
|
100
|
+
|
|
101
|
+
promise.resolve(result)
|
|
102
|
+
} catch (e: Exception) {
|
|
103
|
+
promise.reject("ERR_FLIR_SDK_STATUS", e)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
74
106
|
}
|