ilabs-flir 2.4.2 → 2.4.3

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.
@@ -44,6 +44,9 @@ object FlirManager {
44
44
  private var isStreaming = false
45
45
  private var connectedDeviceId: String? = null
46
46
  private var connectedDeviceName: String? = null
47
+
48
+ // Manual gating
49
+ var manualOnly: Boolean = true
47
50
 
48
51
  // Concurrency control
49
52
  private val shouldProcessFrames = java.util.concurrent.atomic.AtomicBoolean(false)
@@ -124,17 +127,33 @@ object FlirManager {
124
127
  */
125
128
  @Synchronized
126
129
  fun startDiscovery(retry: Boolean = false) {
130
+ if (manualOnly && !retry) {
131
+ Log.w(TAG, "🔭 [FLIR] Discovery blocked: manualOnly is enabled. Use startManualDiscovery() or disable the gate.")
132
+ return
133
+ }
134
+
127
135
  if (!isInitialized && reactContext != null) {
128
136
  init(reactContext!!)
129
137
  }
130
138
 
131
139
  if (isScanning && !retry) return
132
140
 
133
- Log.i(TAG, "Starting FlirManager discovery...")
141
+ Log.i(TAG, "🔭 [FLIR] Starting discovery (retry=$retry)...")
134
142
  isScanning = true
135
143
  emitDeviceState("discovering")
136
144
  sdkManager?.scan()
137
145
  }
146
+
147
+ /**
148
+ * Explicitly starts discovery regardless of manualOnly flag.
149
+ * Use this for JS-triggered scans.
150
+ */
151
+ @Synchronized
152
+ fun startManualDiscovery() {
153
+ Log.i(TAG, "🔭 [FLIR] Manual discovery requested - opening gate.")
154
+ manualOnly = false
155
+ startDiscovery(true)
156
+ }
138
157
 
139
158
  /**
140
159
  * Start discovery with React context
@@ -238,7 +238,7 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
238
238
  // Ensure SDK is initialized with context before starting discovery
239
239
  FlirManager.init(reactContext)
240
240
  // With simplified API, just start discovery - emulators are discovered like any device
241
- FlirManager.startDiscovery(true)
241
+ FlirManager.startManualDiscovery()
242
242
  promise?.resolve(true)
243
243
  } catch (e: Exception) {
244
244
  promise?.reject("ERR_FLIR_EMULATOR", e)
@@ -285,7 +285,7 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
285
285
  try {
286
286
  // Ensure SDK is initialized with context before starting discovery
287
287
  FlirManager.init(reactContext)
288
- FlirManager.startDiscovery(true)
288
+ FlirManager.startManualDiscovery()
289
289
  promise?.resolve(true)
290
290
  } catch (e: Exception) {
291
291
  promise?.reject("ERR_FLIR_DISCOVERY", e)
@@ -340,7 +340,7 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
340
340
  @ReactMethod
341
341
  fun resumeFlirAfterPreview(promise: Promise?) {
342
342
  try {
343
- FlirManager.startDiscovery(true)
343
+ FlirManager.startManualDiscovery()
344
344
  promise?.resolve(true)
345
345
  } catch (e: Exception) {
346
346
  promise?.reject("ERR_RESUME_FLIR", e)
@@ -408,6 +408,16 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
408
408
  }
409
409
  }
410
410
 
411
+ @ReactMethod
412
+ fun setManualDiscoveryOnly(enabled: Boolean, promise: Promise?) {
413
+ try {
414
+ FlirManager.manualOnly = enabled
415
+ promise?.resolve(true)
416
+ } catch (e: Exception) {
417
+ promise?.reject("ERR_FLIR_GATE", e)
418
+ }
419
+ }
420
+
411
421
  @ReactMethod
412
422
  fun initializeSDK(promise: Promise?) {
413
423
  try {
@@ -28,10 +28,8 @@ class FlirView(context: ThemedReactContext) : FrameLayout(context) {
28
28
 
29
29
  override fun onAttachedToWindow() {
30
30
  super.onAttachedToWindow()
31
- // Let the centralized manager handle discovery and streaming and emit events
32
- try {
33
- FlirManager.startDiscoveryAndConnect(context as ThemedReactContext)
34
- } catch (ignored: Throwable) {}
31
+ // GATING: Automatic discovery on attach is disabled to enforce manual discovery
32
+ // FlirManager.startDiscoveryAndConnect(context as ThemedReactContext)
35
33
  }
36
34
 
37
35
  override fun onDetachedFromWindow() {
@@ -66,6 +66,9 @@ import ThermalSDK
66
66
  // Internal synchronization
67
67
  private let stateLock = NSObject()
68
68
 
69
+ // Manual gating
70
+ @objc public var manualOnly: Bool = true
71
+
69
72
  // Palette and Snapshot state
70
73
  private var currentPaletteName: String = "WhiteHot"
71
74
  private var pendingSnapshotPath: String?
@@ -113,7 +116,12 @@ import ThermalSDK
113
116
  // MARK: - Discovery
114
117
 
115
118
  @objc public func startDiscovery() {
116
- NSLog("[FlirManager] startDiscovery")
119
+ if manualOnly {
120
+ NSLog("[FlirManager] 🔭 Discovery blocked: manualOnly is enabled. Use startManualDiscovery() or disable the gate.")
121
+ return
122
+ }
123
+
124
+ NSLog("[FlirManager] 🔭 startDiscovery (manualOnly=false)")
117
125
 
118
126
  #if FLIR_ENABLED
119
127
  discoveredDevices.removeAll()
@@ -133,6 +141,14 @@ import ThermalSDK
133
141
  #endif
134
142
  }
135
143
 
144
+ /// Explicitly starts discovery regardless of manualOnly flag.
145
+ /// Use this for JS-triggered scans.
146
+ @objc public func startManualDiscovery() {
147
+ NSLog("[FlirManager] 🔭 Manual discovery requested - opening gate.")
148
+ manualOnly = false
149
+ startDiscovery()
150
+ }
151
+
136
152
  @objc public func stopDiscovery() {
137
153
  objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
138
154
  NSLog("[FlirManager] stopDiscovery")
@@ -151,13 +151,15 @@ RCT_EXPORT_METHOD(startDiscovery : (RCTPromiseResolveBlock)
151
151
  dispatch_async(dispatch_get_main_queue(), ^{
152
152
  id manager = flir_manager_shared();
153
153
  if (manager &&
154
- [manager respondsToSelector:sel_registerName("startDiscovery")]) {
155
- NSLog(@"[FlirModule] [%@] ⏱ Calling FlirManager.startDiscovery",
154
+ [manager respondsToSelector:sel_registerName("startManualDiscovery")]) {
155
+ NSLog(@"[FlirModule] [%@] ⏱ Calling FlirManager.startManualDiscovery",
156
156
  [NSDate date]);
157
+ ((void (*)(id, SEL))objc_msgSend)(manager,
158
+ sel_registerName("startManualDiscovery"));
159
+ } else if (manager && [manager respondsToSelector:sel_registerName("startDiscovery")]) {
160
+ // Fallback for older manager versions
157
161
  ((void (*)(id, SEL))objc_msgSend)(manager,
158
162
  sel_registerName("startDiscovery"));
159
- NSLog(@"[FlirModule] [%@] ⏱ FlirManager.startDiscovery returned",
160
- [NSDate date]);
161
163
  }
162
164
  if (resolve) resolve(@(YES));
163
165
  });
@@ -291,6 +293,11 @@ RCT_EXPORT_METHOD(startEmulator : (NSString *)emulatorType resolver : (
291
293
  ((void (*)(id, SEL, id))objc_msgSend)(
292
294
  manager, sel_registerName("startEmulatorWithType:"), emulatorType ?: @"FLIR_ONE_EDGE");
293
295
 
296
+ // Opening the gate for emulator discovery too
297
+ if ([manager respondsToSelector:sel_registerName("setManualOnly:")]) {
298
+ ((void (*)(id, SEL, BOOL))objc_msgSend)(manager, sel_registerName("setManualOnly:"), NO);
299
+ }
300
+
294
301
  // Resolve immediately - connection status will come via events
295
302
  if (resolve) resolve(@(YES));
296
303
  } else {
@@ -445,7 +452,10 @@ RCT_EXPORT_METHOD(resumeFlirAfterPreview : (RCTPromiseResolveBlock)
445
452
  resolve rejecter : (RCTPromiseRejectBlock)reject) {
446
453
  dispatch_async(dispatch_get_main_queue(), ^{
447
454
  id manager = flir_manager_shared();
448
- if (manager && [manager respondsToSelector:sel_registerName("startDiscovery")]) {
455
+ if (manager && [manager respondsToSelector:sel_registerName("startManualDiscovery")]) {
456
+ atomic_store(&_isCapturing, true);
457
+ ((void (*)(id, SEL))objc_msgSend)(manager, sel_registerName("startManualDiscovery"));
458
+ } else if (manager && [manager respondsToSelector:sel_registerName("startDiscovery")]) {
449
459
  atomic_store(&_isCapturing, true);
450
460
  ((void (*)(id, SEL))objc_msgSend)(manager, sel_registerName("startDiscovery"));
451
461
  }
@@ -455,6 +465,17 @@ RCT_EXPORT_METHOD(resumeFlirAfterPreview : (RCTPromiseResolveBlock)
455
465
 
456
466
 
457
467
 
468
+ RCT_EXPORT_METHOD(setManualDiscoveryOnly : (BOOL)enabled resolver : (
469
+ RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
470
+ dispatch_async(dispatch_get_main_queue(), ^{
471
+ id manager = flir_manager_shared();
472
+ if (manager && [manager respondsToSelector:sel_registerName("setManualOnly:")]) {
473
+ ((void (*)(id, SEL, BOOL))objc_msgSend)(manager, sel_registerName("setManualOnly:"), enabled);
474
+ }
475
+ if (resolve) resolve(@(YES));
476
+ });
477
+ }
478
+
458
479
  RCT_EXPORT_METHOD(getSDKStatus : (RCTPromiseResolveBlock)
459
480
  resolve rejecter : (RCTPromiseRejectBlock)reject) {
460
481
  if (resolve) resolve(@{@"available" : @(YES), @"arch" : @"arm64", @"platform" : @"iOS"});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ilabs-flir",
3
- "version": "2.4.2",
3
+ "version": "2.4.3",
4
4
  "description": "FLIR Thermal SDK for React Native - iOS & Android (bundled at compile time via postinstall)",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",