react-native-acoustic-connect-beta 18.0.22 → 18.0.24
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/AcousticConnectRN.podspec +24 -4
- package/README.md +237 -67
- package/android/build.gradle +47 -2
- package/android/gradle.properties +3 -3
- package/android/src/main/assets/ConnectAdvancedConfig.json +1 -1
- package/android/src/main/assets/ConnectBasicConfig.properties +1 -1
- package/android/src/main/assets/TealeafAdvancedConfig.json +1 -1
- package/android/src/main/java/com/acousticconnectrn/AcousticConnectRNPackage.java +9 -32
- package/android/src/main/java/com/acousticconnectrn/HybridAcousticConnectRN.kt +258 -87
- package/ios/HybridAcousticConnectRN.swift +181 -73
- package/lib/commonjs/TLTRN.js +18 -12
- package/lib/commonjs/TLTRN.js.map +1 -1
- package/lib/commonjs/components/Connect.js +3 -0
- package/lib/commonjs/components/Connect.js.map +1 -1
- package/lib/module/TLTRN.js +18 -12
- package/lib/module/TLTRN.js.map +1 -1
- package/lib/module/components/Connect.js +3 -0
- package/lib/module/components/Connect.js.map +1 -1
- package/lib/typescript/src/TLTRN.d.ts.map +1 -1
- package/lib/typescript/src/components/Connect.d.ts.map +1 -1
- package/lib/typescript/src/specs/react-native-acoustic-connect.nitro.d.ts +62 -0
- package/lib/typescript/src/specs/react-native-acoustic-connect.nitro.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridAcousticConnectRNSpec.cpp +10 -0
- package/nitrogen/generated/android/c++/JHybridAcousticConnectRNSpec.hpp +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/acousticconnectrn/HybridAcousticConnectRNSpec.kt +8 -0
- package/nitrogen/generated/ios/c++/HybridAcousticConnectRNSpecSwift.hpp +16 -0
- package/nitrogen/generated/ios/swift/HybridAcousticConnectRNSpec.swift +2 -0
- package/nitrogen/generated/ios/swift/HybridAcousticConnectRNSpec_cxx.swift +24 -0
- package/nitrogen/generated/shared/c++/HybridAcousticConnectRNSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridAcousticConnectRNSpec.hpp +2 -0
- package/package.json +7 -4
- package/scripts/ConnectConfig.json +1 -1
- package/src/TLTRN.ts +23 -16
- package/src/components/Connect.tsx +3 -0
- package/src/specs/react-native-acoustic-connect.nitro.ts +63 -0
|
@@ -49,8 +49,7 @@ import com.acoustic.connect.android.connectmod.Connect.registerFormField
|
|
|
49
49
|
import com.acoustic.connect.android.connectmod.Connect.resumeConnect
|
|
50
50
|
import com.facebook.react.bridge.LifecycleEventListener
|
|
51
51
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
52
|
-
import com.facebook.react.uimanager.
|
|
53
|
-
import com.facebook.react.uimanager.UIManagerModule
|
|
52
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
54
53
|
import com.ibm.eo.EOCore
|
|
55
54
|
import com.ibm.eo.model.EOMonitoringLevel
|
|
56
55
|
import com.margelo.nitro.NitroModules.Companion.applicationContext
|
|
@@ -65,22 +64,201 @@ import com.tl.uic.util.keyboardview.KeyboardView
|
|
|
65
64
|
import java.util.Objects
|
|
66
65
|
|
|
67
66
|
|
|
68
|
-
class HybridAcousticConnectRN
|
|
67
|
+
class HybridAcousticConnectRN : HybridAcousticConnectRNSpec(),
|
|
69
68
|
LifecycleEventListener {
|
|
70
69
|
|
|
70
|
+
// The Nitro C++ factory (`AcousticConnectRNOnLoad.cpp`) instantiates this
|
|
71
|
+
// class with `getConstructor<()>()` — i.e. it expects a zero-arg
|
|
72
|
+
// constructor. The React context can therefore not be passed in at
|
|
73
|
+
// construction time; we resolve it lazily via `NitroModules.applicationContext`
|
|
74
|
+
// (which is nullable until the React context attaches), guard every
|
|
75
|
+
// access, and retry the lifecycle-listener registration on each
|
|
76
|
+
// `enable()` call until it succeeds.
|
|
77
|
+
|
|
78
|
+
// Touched only on the main looper. All read/write goes through
|
|
79
|
+
// `runOnMain { ... }` (called from `init`, `enable()`, etc.), so the
|
|
80
|
+
// unsynchronised access pattern is safe — the field's mutating thread
|
|
81
|
+
// and reading thread are the same.
|
|
82
|
+
private var lifecycleListenerRegistered = false
|
|
83
|
+
|
|
71
84
|
init {
|
|
72
|
-
|
|
73
|
-
|
|
85
|
+
Log.v(TAG, "[bridge] HybridAcousticConnectRN constructed")
|
|
86
|
+
runOnMain {
|
|
87
|
+
tryRegisterLifecycleListenerOnMain()
|
|
88
|
+
// Cold-start auto-init: mirrors the iOS bridge's behaviour, where
|
|
89
|
+
// `load()` runs inside the constructor's `Task { @MainActor in … }`
|
|
90
|
+
// and initialises the SDK without waiting for an explicit JS
|
|
91
|
+
// call. Without this, an Android cold start where the first
|
|
92
|
+
// activity `onResume` fires before the lifecycle listener was
|
|
93
|
+
// registered (slow JS bundle, RAM-bundle apps, dev hot reload)
|
|
94
|
+
// would leave the SDK uninitialised until the next resume.
|
|
95
|
+
maybeAutoInitOnMain()
|
|
96
|
+
}
|
|
97
|
+
}
|
|
74
98
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Posts to the main looper. Used by every operation that touches
|
|
101
|
+
* `lifecycleListenerRegistered`, registers a `LifecycleEventListener`,
|
|
102
|
+
* or calls into `Connect.init`/`Connect.enable`/`Connect.disable` — so
|
|
103
|
+
* all of those operations execute single-threaded on main, eliminating
|
|
104
|
+
* read-then-write races on the registration flag.
|
|
105
|
+
*/
|
|
106
|
+
private fun runOnMain(block: () -> Unit) {
|
|
107
|
+
Handler(Looper.getMainLooper()).post(block)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Idempotent: registers this hybrid as a React lifecycle listener the
|
|
112
|
+
* first time `NitroModules.applicationContext` is non-null, then no-ops.
|
|
113
|
+
*
|
|
114
|
+
* MUST be called on the main looper. Callers funnel through
|
|
115
|
+
* [runOnMain]; the read-then-write of `lifecycleListenerRegistered` is
|
|
116
|
+
* therefore single-threaded by construction.
|
|
117
|
+
*/
|
|
118
|
+
private fun tryRegisterLifecycleListenerOnMain() {
|
|
119
|
+
if (lifecycleListenerRegistered) return
|
|
120
|
+
val ctx = applicationContext
|
|
121
|
+
if (ctx == null) {
|
|
122
|
+
Log.v(TAG, "[bridge] React context not ready; lifecycle listener registration deferred")
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
ctx.addLifecycleEventListener(this)
|
|
126
|
+
lifecycleListenerRegistered = true
|
|
127
|
+
Log.v(TAG, "[bridge] Lifecycle listener registered")
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Cold-start auto-init helper. Calls `Connect.init` + `Connect.enable`
|
|
132
|
+
* if the SDK isn't already running and the React context is attached.
|
|
133
|
+
* MUST be called on the main looper.
|
|
134
|
+
*
|
|
135
|
+
* Idempotent at every level:
|
|
136
|
+
* - If the SDK is already enabled, returns immediately.
|
|
137
|
+
* - If the context isn't ready, returns without acting (the subsequent
|
|
138
|
+
* `onHostResume` lifecycle callback or an explicit `enable()` from JS
|
|
139
|
+
* will retry).
|
|
140
|
+
* - `Connect.init` and `Connect.enable` are themselves idempotent in
|
|
141
|
+
* the native SDK, so this co-existing with a later JS-driven
|
|
142
|
+
* `enable()` is safe.
|
|
143
|
+
*/
|
|
144
|
+
private fun maybeAutoInitOnMain() {
|
|
145
|
+
if (Connect.isEnabled()) return
|
|
146
|
+
val app = resolveApplication() ?: return
|
|
147
|
+
if (Connect.getApplication() == null) {
|
|
148
|
+
Connect.init(app)
|
|
149
|
+
}
|
|
150
|
+
Connect.enable()
|
|
151
|
+
Log.i(TAG, "[bridge] SDK auto-initialised at bridge construction")
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Resolves the host app's `Application` from
|
|
156
|
+
* `NitroModules.applicationContext`. Returns `null` (with a logged
|
|
157
|
+
* warning) when the React context isn't attached yet — callers must
|
|
158
|
+
* bail rather than NPE. Replaces the previous direct deref through a
|
|
159
|
+
* constructor-injected `ReactApplicationContext` field, which was unsafe
|
|
160
|
+
* because Nitro's factory passes a null JNI handle through Kotlin's
|
|
161
|
+
* non-null platform type.
|
|
162
|
+
*/
|
|
163
|
+
private fun resolveApplication(): Application? {
|
|
164
|
+
val app = applicationContext?.applicationContext as? Application
|
|
165
|
+
if (app == null) {
|
|
166
|
+
Log.w(TAG, "[bridge] Application not yet available (NitroModules.applicationContext is null or its applicationContext is not an Application)")
|
|
167
|
+
}
|
|
168
|
+
return app
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// region Gate-keeper API (CA-137696)
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Re-enables the Connect SDK after a prior `disable()`. All configuration
|
|
175
|
+
* comes from `ConnectConfig.json` at the consumer's project root, which
|
|
176
|
+
* `config.gradle` bakes into `ConnectBasicConfig.properties` /
|
|
177
|
+
* `TealeafBasicConfig.properties` at build time.
|
|
178
|
+
*
|
|
179
|
+
* Idempotency is owned by the native SDK. `Connect.init` is safe to call
|
|
180
|
+
* multiple times, and `Connect.enable` short-circuits once the SDK is
|
|
181
|
+
* running. The bridge does not track its own enable signature — subsequent
|
|
182
|
+
* JS calls just post another runnable that the native side will treat as
|
|
183
|
+
* a no-op.
|
|
184
|
+
*
|
|
185
|
+
* Push wiring on Android is gated at build time by `Connect.PushEnabled`
|
|
186
|
+
* in `ConnectConfig.json`, which `android/build.gradle` consults to
|
|
187
|
+
* include the `connect-push-fcm` artifact. Token forwarding to Connect
|
|
188
|
+
* lives in CA-137698 and runs through the host app's
|
|
189
|
+
* `FirebaseMessagingService`.
|
|
190
|
+
*
|
|
191
|
+
* @return true on accepted dispatch, false if no application context.
|
|
192
|
+
*/
|
|
193
|
+
override fun enable(): Boolean {
|
|
194
|
+
Log.i(TAG, "[bridge] enable() called from JS")
|
|
195
|
+
logResolvedPushAvailability()
|
|
196
|
+
|
|
197
|
+
// All work happens on the main looper so the lifecycle-listener
|
|
198
|
+
// registration flag is touched single-threaded and we don't race
|
|
199
|
+
// with the `init { runOnMain { … } }` registration path. Returning
|
|
200
|
+
// `true` reflects "accepted dispatch", not "succeeded"; the actual
|
|
201
|
+
// work logs its own success or failure on main.
|
|
202
|
+
runOnMain {
|
|
203
|
+
tryRegisterLifecycleListenerOnMain()
|
|
204
|
+
val application = resolveApplication() ?: run {
|
|
205
|
+
Log.w(TAG, "[bridge] enable() bailed — Application still null on main thread")
|
|
206
|
+
return@runOnMain
|
|
80
207
|
}
|
|
208
|
+
Connect.init(application)
|
|
209
|
+
Connect.enable()
|
|
210
|
+
Log.i(TAG, "[bridge] SDK initialised")
|
|
211
|
+
}
|
|
212
|
+
return true
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Disables the Connect SDK. Idempotent — the underlying `Connect.disable()`
|
|
217
|
+
* is safe to call repeatedly on the native side; this override always
|
|
218
|
+
* returns `true` for an accepted dispatch.
|
|
219
|
+
*/
|
|
220
|
+
override fun disable(): Boolean {
|
|
221
|
+
Log.i(TAG, "[bridge] disable() called from JS")
|
|
222
|
+
runOnMain {
|
|
223
|
+
Connect.disable()
|
|
224
|
+
Log.i(TAG, "[bridge] SDK disabled")
|
|
81
225
|
}
|
|
226
|
+
return true
|
|
82
227
|
}
|
|
83
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Checks whether the `connect-push-fcm` artifact is on the classpath and
|
|
231
|
+
* logs the result. The artifact is gated by `Connect.PushEnabled` in
|
|
232
|
+
* `ConnectConfig.json` via `android/build.gradle`'s conditional
|
|
233
|
+
* `implementation` clause. A missing artifact when `PushEnabled` was set
|
|
234
|
+
* to true points at a build-pipeline issue (didn't run `config.gradle`
|
|
235
|
+
* or the conditional didn't fire). Once CA-137698 lands the actual
|
|
236
|
+
* Connect push API on Android, this method also gates the wire-up.
|
|
237
|
+
*/
|
|
238
|
+
private fun logResolvedPushAvailability() {
|
|
239
|
+
val pushAvailable = isConnectPushFcmAvailable()
|
|
240
|
+
Log.i(TAG, "[config] connect-push-fcm on classpath: $pushAvailable")
|
|
241
|
+
if (!pushAvailable) {
|
|
242
|
+
Log.i(TAG, "[config] Push is not active on Android in this build. To enable, set Connect.PushEnabled=true in ConnectConfig.json and re-sync Gradle to include connect-push-fcm. Token forwarding wires in CA-137698.")
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private fun isConnectPushFcmAvailable(): Boolean {
|
|
247
|
+
// Probe a known class shipped by the connect-push-fcm artifact. The
|
|
248
|
+
// exact class lives in the Connect Android SDK's push module and is
|
|
249
|
+
// finalised under CA-137698; this Class.forName probe is robust to
|
|
250
|
+
// package-name changes because it falls through silently when the
|
|
251
|
+
// class is missing (which is the default in a no-push build).
|
|
252
|
+
return try {
|
|
253
|
+
Class.forName(CONNECT_PUSH_FCM_PROBE_CLASS)
|
|
254
|
+
true
|
|
255
|
+
} catch (e: ClassNotFoundException) {
|
|
256
|
+
false
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// endregion
|
|
261
|
+
|
|
84
262
|
/**
|
|
85
263
|
* Sets the module's boolean configuration item from AdvancedConfig.json or BasicConfig.properties that matches the specified key.
|
|
86
264
|
*
|
|
@@ -282,35 +460,28 @@ class HybridAcousticConnectRN(private val reactContext: ReactApplicationContext)
|
|
|
282
460
|
* @return True if the operation was successful, false otherwise.
|
|
283
461
|
*/
|
|
284
462
|
override fun logClickEvent(target: Double, controlId: String): Boolean {
|
|
285
|
-
|
|
286
|
-
try {
|
|
287
|
-
val
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if (!TextUtils.isEmpty(controlId)) {
|
|
301
|
-
logEvent(view, "click", controlId)
|
|
302
|
-
} else {
|
|
303
|
-
logEvent(view, "click")
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
result = true
|
|
307
|
-
}
|
|
463
|
+
val viewTag = target.toInt()
|
|
464
|
+
return try {
|
|
465
|
+
val ctx = applicationContext ?: return false
|
|
466
|
+
val uiManager = UIManagerHelper.getUIManagerForReactTag(ctx, viewTag)
|
|
467
|
+
?: return false
|
|
468
|
+
val view = uiManager.resolveView(viewTag) ?: return false
|
|
469
|
+
|
|
470
|
+
Handler(Looper.getMainLooper()).post {
|
|
471
|
+
val activity = getCurrentActivity() ?: return@post
|
|
472
|
+
if (view is EditText) {
|
|
473
|
+
addFocusAndRegister(view, null, activity)
|
|
474
|
+
} else if (TextUtils.isEmpty(controlId)) {
|
|
475
|
+
logEvent(view, "click")
|
|
476
|
+
} else {
|
|
477
|
+
logEvent(view, "click", controlId)
|
|
308
478
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
479
|
+
}
|
|
480
|
+
true
|
|
481
|
+
} catch (e: Exception) {
|
|
482
|
+
Log.v(TAG, "logClickEvent error: ${e.message}", e)
|
|
483
|
+
false
|
|
312
484
|
}
|
|
313
|
-
return result
|
|
314
485
|
}
|
|
315
486
|
|
|
316
487
|
/**
|
|
@@ -320,31 +491,26 @@ class HybridAcousticConnectRN(private val reactContext: ReactApplicationContext)
|
|
|
320
491
|
* @return True if the operation was successful, false otherwise.
|
|
321
492
|
*/
|
|
322
493
|
fun logClickEvent(target: Double): Boolean {
|
|
323
|
-
|
|
324
|
-
try {
|
|
325
|
-
val
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
addFocusAndRegister(view as EditText, null, getCurrentActivity()!!)
|
|
337
|
-
} else {
|
|
338
|
-
logEvent(view, "click")
|
|
339
|
-
}
|
|
340
|
-
result = true
|
|
341
|
-
}
|
|
494
|
+
val viewTag = target.toInt()
|
|
495
|
+
return try {
|
|
496
|
+
val ctx = applicationContext ?: return false
|
|
497
|
+
val uiManager = UIManagerHelper.getUIManagerForReactTag(ctx, viewTag)
|
|
498
|
+
?: return false
|
|
499
|
+
val view = uiManager.resolveView(viewTag) ?: return false
|
|
500
|
+
|
|
501
|
+
Handler(Looper.getMainLooper()).post {
|
|
502
|
+
val activity = getCurrentActivity() ?: return@post
|
|
503
|
+
if (view is EditText) {
|
|
504
|
+
addFocusAndRegister(view, null, activity)
|
|
505
|
+
} else {
|
|
506
|
+
logEvent(view, "click")
|
|
342
507
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
508
|
+
}
|
|
509
|
+
true
|
|
510
|
+
} catch (e: Exception) {
|
|
511
|
+
Log.v(TAG, "logClickEvent error: ${e.message}")
|
|
512
|
+
false
|
|
346
513
|
}
|
|
347
|
-
return result
|
|
348
514
|
}
|
|
349
515
|
|
|
350
516
|
/**
|
|
@@ -356,31 +522,25 @@ class HybridAcousticConnectRN(private val reactContext: ReactApplicationContext)
|
|
|
356
522
|
* @return True if the operation was successful, false otherwise.
|
|
357
523
|
*/
|
|
358
524
|
override fun logTextChangeEvent(target: Double, controlId: String, text: Variant_NullType_String?): Boolean {
|
|
359
|
-
|
|
360
|
-
try {
|
|
361
|
-
val
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if (view is EditText && (view as EditText).onFocusChangeListener == null) {
|
|
372
|
-
// First time, logEvent and subsequent calls will be handled in change listener
|
|
373
|
-
logEvent(view, TLF_ON_FOCUS_CHANGE_IN, controlId)
|
|
374
|
-
addFocusAndRegister(view as EditText, controlId, getCurrentActivity()!!)
|
|
375
|
-
}
|
|
376
|
-
result = true
|
|
377
|
-
}
|
|
525
|
+
val viewTag = target.toInt()
|
|
526
|
+
return try {
|
|
527
|
+
val ctx = applicationContext ?: return false
|
|
528
|
+
val uiManager = UIManagerHelper.getUIManagerForReactTag(ctx, viewTag)
|
|
529
|
+
?: return false
|
|
530
|
+
val view = uiManager.resolveView(viewTag) ?: return false
|
|
531
|
+
|
|
532
|
+
Handler(Looper.getMainLooper()).post {
|
|
533
|
+
val activity = getCurrentActivity() ?: return@post
|
|
534
|
+
if (view is EditText && view.onFocusChangeListener == null) {
|
|
535
|
+
logEvent(view, TLF_ON_FOCUS_CHANGE_IN, controlId)
|
|
536
|
+
addFocusAndRegister(view, controlId, activity)
|
|
378
537
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
538
|
+
}
|
|
539
|
+
true
|
|
540
|
+
} catch (e: Exception) {
|
|
541
|
+
Log.v(TAG, "logTextChangeEvent error: ${e.message}")
|
|
542
|
+
false
|
|
382
543
|
}
|
|
383
|
-
return result
|
|
384
544
|
}
|
|
385
545
|
|
|
386
546
|
/**
|
|
@@ -832,7 +992,7 @@ class HybridAcousticConnectRN(private val reactContext: ReactApplicationContext)
|
|
|
832
992
|
// }
|
|
833
993
|
|
|
834
994
|
fun onWindowFocusChanged(hasFocus: Boolean) {
|
|
835
|
-
if (
|
|
995
|
+
if (applicationContext == null) {
|
|
836
996
|
// logEvent("WindowFocus", "Context is not ready. Skipping onWindowFocusChanged.")
|
|
837
997
|
return
|
|
838
998
|
}
|
|
@@ -850,7 +1010,7 @@ class HybridAcousticConnectRN(private val reactContext: ReactApplicationContext)
|
|
|
850
1010
|
*/
|
|
851
1011
|
override fun onHostResume() {
|
|
852
1012
|
// Initialize Connect library, and hook into activity lifecycle events to help detect if app is in background
|
|
853
|
-
if (
|
|
1013
|
+
if (applicationContext == null) {
|
|
854
1014
|
// logEvent("Lifecycle", "onHostResume skipped: ReactContext is not ready")
|
|
855
1015
|
return
|
|
856
1016
|
}
|
|
@@ -863,9 +1023,13 @@ class HybridAcousticConnectRN(private val reactContext: ReactApplicationContext)
|
|
|
863
1023
|
|
|
864
1024
|
if (!isEnabled()) {
|
|
865
1025
|
if (getApplication() == null) {
|
|
866
|
-
|
|
1026
|
+
val app = resolveApplication() ?: return
|
|
1027
|
+
init(app)
|
|
867
1028
|
}
|
|
868
|
-
enable()
|
|
1029
|
+
// Qualified to bypass the `enable()` override on this class —
|
|
1030
|
+
// call the native SDK's `Connect.enable()` directly so the
|
|
1031
|
+
// log line "called from JS" doesn't fire on lifecycle wake-ups.
|
|
1032
|
+
Connect.enable()
|
|
869
1033
|
}
|
|
870
1034
|
onResume(activity, null)
|
|
871
1035
|
}
|
|
@@ -901,5 +1065,12 @@ class HybridAcousticConnectRN(private val reactContext: ReactApplicationContext)
|
|
|
901
1065
|
companion object {
|
|
902
1066
|
const val TAG = "AcousticConnectRN"
|
|
903
1067
|
const val DIALOG_CAPTURE_DELAY_MS = 500L // Configurable delay for dialog screenshot capture
|
|
1068
|
+
|
|
1069
|
+
// Class probed at runtime to detect whether the connect-push-fcm
|
|
1070
|
+
// artifact was included in the build. Conservative placeholder — the
|
|
1071
|
+
// actual class name is finalised under CA-137698; if that ticket lands
|
|
1072
|
+
// a different fully-qualified name, update this constant.
|
|
1073
|
+
private const val CONNECT_PUSH_FCM_PROBE_CLASS =
|
|
1074
|
+
"com.acoustic.connect.android.push.fcm.ConnectPushFcm"
|
|
904
1075
|
}
|
|
905
1076
|
}
|