@bits-innovate/react-native-vstarcam 1.0.14 → 1.0.16
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.
|
@@ -13,13 +13,21 @@ import com.facebook.react.bridge.ReactMethod;
|
|
|
13
13
|
import com.facebook.react.bridge.WritableMap;
|
|
14
14
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
15
15
|
|
|
16
|
+
import java.io.BufferedReader;
|
|
17
|
+
import java.io.InputStreamReader;
|
|
16
18
|
import java.lang.reflect.InvocationHandler;
|
|
17
19
|
import java.lang.reflect.Method;
|
|
18
20
|
import java.lang.reflect.Proxy;
|
|
21
|
+
import java.net.HttpURLConnection;
|
|
22
|
+
import java.net.URL;
|
|
19
23
|
import java.util.HashMap;
|
|
20
24
|
import java.util.Map;
|
|
21
25
|
import java.util.concurrent.ExecutorService;
|
|
22
26
|
import java.util.concurrent.Executors;
|
|
27
|
+
import java.util.regex.Pattern;
|
|
28
|
+
|
|
29
|
+
import org.json.JSONObject;
|
|
30
|
+
|
|
23
31
|
|
|
24
32
|
/**
|
|
25
33
|
* VStarCam React Native Module
|
|
@@ -78,6 +86,56 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
78
86
|
return param;
|
|
79
87
|
}
|
|
80
88
|
|
|
89
|
+
// Pattern to detect virtual UIDs (like ACAE0001151GWYQ)
|
|
90
|
+
// Virtual UIDs: start with letters, have 7+ digits, end with letters
|
|
91
|
+
private static final Pattern VIRTUAL_UID_PATTERN = Pattern.compile("^[a-zA-Z]{1,}\\d{7,}.*[a-zA-Z]$");
|
|
92
|
+
|
|
93
|
+
// Check if a device ID is a virtual UID that needs conversion
|
|
94
|
+
private static boolean isVirtualId(String deviceId) {
|
|
95
|
+
if (deviceId == null || deviceId.length() < 10) return false;
|
|
96
|
+
return VIRTUAL_UID_PATTERN.matcher(deviceId).matches();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Convert virtual UID to real client ID using VStarCam API
|
|
100
|
+
// Returns: {uid, supplier, cluster} or null on failure
|
|
101
|
+
private String[] convertVirtualUid(String virtualUid) {
|
|
102
|
+
try {
|
|
103
|
+
URL url = new URL("https://vuid.eye4.cn?vuid=" + virtualUid);
|
|
104
|
+
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
105
|
+
conn.setRequestMethod("GET");
|
|
106
|
+
conn.setConnectTimeout(10000);
|
|
107
|
+
conn.setReadTimeout(10000);
|
|
108
|
+
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
|
109
|
+
|
|
110
|
+
int responseCode = conn.getResponseCode();
|
|
111
|
+
if (responseCode == 200) {
|
|
112
|
+
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
|
113
|
+
StringBuilder response = new StringBuilder();
|
|
114
|
+
String line;
|
|
115
|
+
while ((line = reader.readLine()) != null) {
|
|
116
|
+
response.append(line);
|
|
117
|
+
}
|
|
118
|
+
reader.close();
|
|
119
|
+
|
|
120
|
+
JSONObject json = new JSONObject(response.toString());
|
|
121
|
+
String uid = json.optString("uid", null);
|
|
122
|
+
String supplier = json.optString("supplier", "");
|
|
123
|
+
String cluster = json.optString("cluster", "");
|
|
124
|
+
|
|
125
|
+
if (uid != null && !uid.isEmpty()) {
|
|
126
|
+
Log.d(TAG, "Converted virtual UID " + virtualUid + " -> real UID: " + uid + " (supplier: " + supplier + ", cluster: " + cluster + ")");
|
|
127
|
+
return new String[]{uid, supplier, cluster};
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
Log.e(TAG, "Virtual UID conversion failed, HTTP " + responseCode);
|
|
131
|
+
}
|
|
132
|
+
conn.disconnect();
|
|
133
|
+
} catch (Exception e) {
|
|
134
|
+
Log.e(TAG, "Failed to convert virtual UID: " + e.getMessage(), e);
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
81
139
|
private final ReactApplicationContext reactContext;
|
|
82
140
|
private final ExecutorService executor;
|
|
83
141
|
|
|
@@ -93,12 +151,14 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
93
151
|
private Class<?> releaseListenerClass = null;
|
|
94
152
|
|
|
95
153
|
private static class ClientInfo {
|
|
96
|
-
String deviceId;
|
|
97
|
-
|
|
154
|
+
String deviceId; // Original device ID (can be virtual UID)
|
|
155
|
+
String realClientId; // Converted client ID (for JNI calls)
|
|
156
|
+
long sdkClientPtr = 0; // Actual SDK client pointer (long)
|
|
98
157
|
boolean isConnected = false;
|
|
99
158
|
boolean isLoggedIn = false;
|
|
100
159
|
}
|
|
101
160
|
|
|
161
|
+
|
|
102
162
|
public VStarCamModule(ReactApplicationContext reactContext) {
|
|
103
163
|
super(reactContext);
|
|
104
164
|
this.reactContext = reactContext;
|
|
@@ -297,6 +357,20 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
297
357
|
return MODULE_NAME;
|
|
298
358
|
}
|
|
299
359
|
|
|
360
|
+
// Required by NativeEventEmitter
|
|
361
|
+
@ReactMethod
|
|
362
|
+
public void addListener(String eventName) {
|
|
363
|
+
// Keep: Required for RN built in Event Emitter Calls
|
|
364
|
+
Log.d(TAG, "addListener called for: " + eventName);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Required by NativeEventEmitter
|
|
368
|
+
@ReactMethod
|
|
369
|
+
public void removeListeners(Integer count) {
|
|
370
|
+
// Keep: Required for RN built in Event Emitter Calls
|
|
371
|
+
Log.d(TAG, "removeListeners called with count: " + count);
|
|
372
|
+
}
|
|
373
|
+
|
|
300
374
|
private void sendEvent(String eventName, @Nullable WritableMap params) {
|
|
301
375
|
if (reactContext.hasActiveReactInstance()) {
|
|
302
376
|
reactContext
|
|
@@ -320,10 +394,23 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
320
394
|
return;
|
|
321
395
|
}
|
|
322
396
|
|
|
323
|
-
//
|
|
324
|
-
String
|
|
397
|
+
// Check if this is a virtual UID that needs conversion
|
|
398
|
+
String realClientId = deviceId;
|
|
399
|
+
if (isVirtualId(deviceId)) {
|
|
400
|
+
Log.d(TAG, "Device ID " + deviceId + " looks like a virtual UID, converting...");
|
|
401
|
+
String[] conversionResult = convertVirtualUid(deviceId);
|
|
402
|
+
if (conversionResult != null && conversionResult[0] != null) {
|
|
403
|
+
realClientId = conversionResult[0];
|
|
404
|
+
Log.d(TAG, "Using converted client ID: " + realClientId);
|
|
405
|
+
} else {
|
|
406
|
+
Log.w(TAG, "Virtual UID conversion failed, trying with original ID");
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Call JNIApi.create(did, serverParam) with real client ID
|
|
411
|
+
String serviceParam = getServiceParam(realClientId); // Use real client ID prefix
|
|
325
412
|
Method createMethod = jniApiClass.getMethod("create", String.class, String.class);
|
|
326
|
-
Object result = createMethod.invoke(null,
|
|
413
|
+
Object result = createMethod.invoke(null, realClientId, serviceParam);
|
|
327
414
|
long sdkClientPtr = (Long) result;
|
|
328
415
|
|
|
329
416
|
Log.d(TAG, "JNIApi.create result: " + sdkClientPtr);
|
|
@@ -339,10 +426,11 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
339
426
|
|
|
340
427
|
ClientInfo clientInfo = new ClientInfo();
|
|
341
428
|
clientInfo.deviceId = deviceId;
|
|
429
|
+
clientInfo.realClientId = realClientId; // Store the converted ID
|
|
342
430
|
clientInfo.sdkClientPtr = sdkClientPtr;
|
|
343
431
|
clients.put(ourClientPtr, clientInfo);
|
|
344
432
|
|
|
345
|
-
Log.d(TAG, "Created client: ourPtr=" + ourClientPtr + ", sdkPtr=" + sdkClientPtr);
|
|
433
|
+
Log.d(TAG, "Created client: ourPtr=" + ourClientPtr + ", sdkPtr=" + sdkClientPtr + ", realId=" + realClientId);
|
|
346
434
|
promise.resolve(ourClientPtr);
|
|
347
435
|
} catch (Exception e) {
|
|
348
436
|
Log.e(TAG, "clientCreate failed", e);
|
|
@@ -378,17 +466,33 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
378
466
|
params.putInt("state", 1); // CONNECTING
|
|
379
467
|
sendEvent("onConnectionStateChanged", params);
|
|
380
468
|
|
|
469
|
+
// Use realClientId for service param lookup (it has the correct prefix like VSTN)
|
|
470
|
+
String realId = clientInfo.realClientId != null ? clientInfo.realClientId : clientInfo.deviceId;
|
|
381
471
|
String param = (serverParam != null && !serverParam.isEmpty())
|
|
382
472
|
? serverParam
|
|
383
|
-
: getServiceParam(
|
|
473
|
+
: getServiceParam(realId);
|
|
474
|
+
|
|
475
|
+
// Default connectType to 126 (from V1 app) if not specified
|
|
476
|
+
// connectType 126 = P2P/Relay combination that works reliably
|
|
477
|
+
int actualConnectType = (connectType <= 0) ? 126 : connectType;
|
|
384
478
|
|
|
385
479
|
// Call JNIApi.connect(sdkClientPtr, timeout, serverParam, connectType)
|
|
386
480
|
// Signature: connect([long, int, class java.lang.String, int])
|
|
387
481
|
Method connectMethod = jniApiClass.getMethod("connect",
|
|
388
482
|
long.class, int.class, String.class, int.class);
|
|
389
483
|
|
|
390
|
-
Log.d(TAG, "Calling JNIApi.connect(" + clientInfo.sdkClientPtr + ", 15, " + param + ", " +
|
|
391
|
-
|
|
484
|
+
Log.d(TAG, "Calling JNIApi.connect(" + clientInfo.sdkClientPtr + ", 15, " + param + ", " + actualConnectType + ")");
|
|
485
|
+
|
|
486
|
+
try {
|
|
487
|
+
connectMethod.invoke(null, clientInfo.sdkClientPtr, 15, param, actualConnectType);
|
|
488
|
+
Log.d(TAG, "JNIApi.connect returned normally");
|
|
489
|
+
} catch (java.lang.reflect.InvocationTargetException ite) {
|
|
490
|
+
Log.e(TAG, "JNIApi.connect threw exception: " + ite.getCause(), ite.getCause());
|
|
491
|
+
throw ite;
|
|
492
|
+
} catch (Throwable t) {
|
|
493
|
+
Log.e(TAG, "JNIApi.connect crashed: " + t.getMessage(), t);
|
|
494
|
+
throw t;
|
|
495
|
+
}
|
|
392
496
|
|
|
393
497
|
Log.d(TAG, "JNIApi.connect called - waiting for state callback");
|
|
394
498
|
|
|
@@ -590,25 +694,38 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
590
694
|
*/
|
|
591
695
|
@ReactMethod
|
|
592
696
|
public void clientCheckMode(int clientPtr, Promise promise) {
|
|
697
|
+
Log.d(TAG, "clientCheckMode called for: " + clientPtr);
|
|
593
698
|
try {
|
|
594
699
|
ClientInfo clientInfo = clients.get(clientPtr);
|
|
595
700
|
|
|
596
701
|
int mode = 0;
|
|
597
|
-
|
|
702
|
+
// Note: sdkClientPtr can be negative (unsigned to signed cast) - only check != 0
|
|
703
|
+
if (clientInfo != null && jniApiClass != null && clientInfo.sdkClientPtr != 0) {
|
|
598
704
|
try {
|
|
599
705
|
Method checkModeMethod = jniApiClass.getMethod("checkMode", long.class);
|
|
600
706
|
Object result = checkModeMethod.invoke(null, clientInfo.sdkClientPtr);
|
|
601
707
|
mode = (Integer) result;
|
|
602
|
-
Log.d(TAG, "JNIApi.checkMode result: " + mode);
|
|
708
|
+
Log.d(TAG, "JNIApi.checkMode result: " + mode + " (0=none, 1=P2P, 2=relay, 3=sock)");
|
|
603
709
|
} catch (Exception e) {
|
|
604
|
-
Log.e(TAG, "checkMode failed", e);
|
|
710
|
+
Log.e(TAG, "checkMode JNI call failed", e);
|
|
605
711
|
}
|
|
712
|
+
} else {
|
|
713
|
+
Log.w(TAG, "checkMode skipped: clientInfo=" + clientInfo +
|
|
714
|
+
", jniApiClass=" + (jniApiClass != null) +
|
|
715
|
+
", sdkPtr=" + (clientInfo != null ? clientInfo.sdkClientPtr : "null"));
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// Mode > 0 means connected (1=P2P, 2=Relay, 3=Socket)
|
|
719
|
+
boolean connected = mode > 0;
|
|
720
|
+
if (connected && clientInfo != null) {
|
|
721
|
+
clientInfo.isConnected = true;
|
|
606
722
|
}
|
|
607
723
|
|
|
608
724
|
WritableMap result = Arguments.createMap();
|
|
609
|
-
result.putBoolean("success",
|
|
725
|
+
result.putBoolean("success", connected);
|
|
610
726
|
result.putInt("mode", mode);
|
|
611
727
|
result.putDouble("sessionHandle", clientInfo != null ? clientInfo.sdkClientPtr : -1);
|
|
728
|
+
Log.d(TAG, "clientCheckMode returning: success=" + connected + ", mode=" + mode);
|
|
612
729
|
promise.resolve(result);
|
|
613
730
|
} catch (Exception e) {
|
|
614
731
|
Log.e(TAG, "clientCheckMode failed", e);
|
|
@@ -630,7 +747,7 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
630
747
|
@ReactMethod
|
|
631
748
|
public void getSdkVersion(Promise promise) {
|
|
632
749
|
WritableMap result = Arguments.createMap();
|
|
633
|
-
result.putString("version", "1.0.
|
|
750
|
+
result.putString("version", "1.0.16");
|
|
634
751
|
result.putBoolean("nativeLoaded", isNativeLibraryLoaded);
|
|
635
752
|
result.putString("nativeLib", "OKSMARTPPCS");
|
|
636
753
|
result.putBoolean("p2pInitialized", isP2PInitialized);
|