@luciq/react-native 19.6.0-51917-SNAPSHOT → 19.7.0
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/CHANGELOG.md +12 -0
- package/README.md +174 -111
- package/android/native.gradle +1 -1
- package/android/src/main/java/ai/luciq/reactlibrary/Constants.java +3 -0
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqAPMModule.java +13 -14
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerModule.java +19 -21
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativeModule.java +131 -132
- package/android/src/main/java/ai/luciq/reactlibrary/utils/EventEmitterModule.java +3 -5
- package/android/src/main/java/ai/luciq/reactlibrary/utils/LuciqRNLogger.java +53 -0
- package/dist/utils/LuciqUtils.js +1 -0
- package/ios/RNLuciq/LuciqNetworkLoggerBridge.m +30 -6
- package/ios/RNLuciq/LuciqReactBridge.m +21 -4
- package/ios/RNLuciq/Util/LuciqRNLogger.h +32 -0
- package/ios/RNLuciq/Util/LuciqRNLogger.m +57 -0
- package/ios/native.rb +1 -1
- package/package.json +2 -1
- package/src/utils/LuciqUtils.ts +5 -0
|
@@ -2,6 +2,7 @@ package ai.luciq.reactlibrary;
|
|
|
2
2
|
|
|
3
3
|
import static ai.luciq.apm.configuration.cp.APMFeature.APM_NETWORK_PLUGIN_INSTALLED;
|
|
4
4
|
import static ai.luciq.apm.configuration.cp.APMFeature.CP_NATIVE_INTERCEPTION_ENABLED;
|
|
5
|
+
import static ai.luciq.reactlibrary.Constants.NET_TAG;
|
|
5
6
|
import static ai.luciq.reactlibrary.utils.LuciqUtil.getMethod;
|
|
6
7
|
|
|
7
8
|
import android.app.Application;
|
|
@@ -13,8 +14,6 @@ import android.os.Build;
|
|
|
13
14
|
import android.util.Log;
|
|
14
15
|
import android.view.View;
|
|
15
16
|
|
|
16
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
17
|
-
|
|
18
17
|
import androidx.annotation.NonNull;
|
|
19
18
|
import androidx.annotation.UiThread;
|
|
20
19
|
|
|
@@ -32,22 +31,37 @@ import com.facebook.react.bridge.WritableNativeArray;
|
|
|
32
31
|
import com.facebook.react.bridge.WritableNativeMap;
|
|
33
32
|
import com.facebook.react.uimanager.UIManagerHelper;
|
|
34
33
|
import com.facebook.react.uimanager.UIManagerModule;
|
|
34
|
+
|
|
35
|
+
import org.json.JSONException;
|
|
36
|
+
import org.json.JSONObject;
|
|
37
|
+
import org.json.JSONTokener;
|
|
38
|
+
|
|
39
|
+
import java.io.File;
|
|
40
|
+
import java.lang.reflect.Method;
|
|
41
|
+
import java.util.ArrayList;
|
|
42
|
+
import java.util.Arrays;
|
|
43
|
+
import java.util.HashMap;
|
|
44
|
+
import java.util.Iterator;
|
|
45
|
+
import java.util.List;
|
|
46
|
+
import java.util.Locale;
|
|
47
|
+
import java.util.Map;
|
|
48
|
+
|
|
49
|
+
import javax.annotation.Nullable;
|
|
50
|
+
|
|
35
51
|
import ai.luciq.apm.InternalAPM;
|
|
36
|
-
import ai.luciq.apm.configuration.cp.APMFeature;
|
|
37
52
|
import ai.luciq.library.Feature;
|
|
53
|
+
import ai.luciq.library.IssueType;
|
|
54
|
+
import ai.luciq.library.LogLevel;
|
|
38
55
|
import ai.luciq.library.Luciq;
|
|
39
56
|
import ai.luciq.library.LuciqColorTheme;
|
|
40
57
|
import ai.luciq.library.LuciqCustomTextPlaceHolder;
|
|
41
|
-
import ai.luciq.library.IssueType;
|
|
42
|
-
import ai.luciq.library.LogLevel;
|
|
43
58
|
import ai.luciq.library.ReproConfigurations;
|
|
44
59
|
import ai.luciq.library.core.InstabugCore;
|
|
60
|
+
import ai.luciq.library.featuresflags.model.LuciqFeatureFlag;
|
|
45
61
|
import ai.luciq.library.internal.crossplatform.CoreFeature;
|
|
46
62
|
import ai.luciq.library.internal.crossplatform.CoreFeaturesState;
|
|
47
63
|
import ai.luciq.library.internal.crossplatform.FeaturesStateListener;
|
|
48
64
|
import ai.luciq.library.internal.crossplatform.InternalCore;
|
|
49
|
-
import ai.luciq.library.featuresflags.model.LuciqFeatureFlag;
|
|
50
|
-
import ai.luciq.library.internal.crossplatform.InternalCore;
|
|
51
65
|
import ai.luciq.library.internal.crossplatform.OnFeaturesUpdatedListener;
|
|
52
66
|
import ai.luciq.library.internal.module.LuciqLocale;
|
|
53
67
|
import ai.luciq.library.invocation.LuciqInvocationEvent;
|
|
@@ -56,29 +70,12 @@ import ai.luciq.library.model.LuciqTheme;
|
|
|
56
70
|
import ai.luciq.library.model.NetworkLog;
|
|
57
71
|
import ai.luciq.library.model.Report;
|
|
58
72
|
import ai.luciq.library.ui.onboarding.WelcomeMessage;
|
|
59
|
-
import ai.luciq.library.util.LuciqSDKLogger;
|
|
60
73
|
import ai.luciq.reactlibrary.utils.ArrayUtil;
|
|
61
74
|
import ai.luciq.reactlibrary.utils.EventEmitterModule;
|
|
75
|
+
import ai.luciq.reactlibrary.utils.LuciqRNLogger;
|
|
62
76
|
import ai.luciq.reactlibrary.utils.MainThreadHandler;
|
|
63
|
-
|
|
64
77
|
import ai.luciq.reactlibrary.utils.RNTouchedViewExtractor;
|
|
65
78
|
|
|
66
|
-
import org.json.JSONException;
|
|
67
|
-
import org.json.JSONObject;
|
|
68
|
-
import org.json.JSONTokener;
|
|
69
|
-
|
|
70
|
-
import java.io.File;
|
|
71
|
-
import java.lang.reflect.Method;
|
|
72
|
-
import java.util.ArrayList;
|
|
73
|
-
import java.util.Arrays;
|
|
74
|
-
import java.util.HashMap;
|
|
75
|
-
import java.util.Iterator;
|
|
76
|
-
import java.util.List;
|
|
77
|
-
import java.util.Locale;
|
|
78
|
-
import java.util.Map;
|
|
79
|
-
|
|
80
|
-
import javax.annotation.Nullable;
|
|
81
|
-
|
|
82
79
|
|
|
83
80
|
/**
|
|
84
81
|
* The type Rn luciq reactnative module.
|
|
@@ -86,7 +83,7 @@ import javax.annotation.Nullable;
|
|
|
86
83
|
public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
87
84
|
|
|
88
85
|
private static final String TAG = "Luciq-RN-Core";
|
|
89
|
-
|
|
86
|
+
;
|
|
90
87
|
|
|
91
88
|
private LuciqCustomTextPlaceHolder placeHolders;
|
|
92
89
|
private static Report currentReport;
|
|
@@ -124,6 +121,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
124
121
|
|
|
125
122
|
/**
|
|
126
123
|
* Enables or disables Luciq functionality.
|
|
124
|
+
*
|
|
127
125
|
* @param isEnabled A boolean to enable/disable Luciq.
|
|
128
126
|
*/
|
|
129
127
|
@ReactMethod
|
|
@@ -164,7 +162,9 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
164
162
|
|
|
165
163
|
|
|
166
164
|
) {
|
|
167
|
-
|
|
165
|
+
final int parsedLogLevel = ArgsRegistry.sdkLogLevels.getOrDefault(logLevel, LogLevel.ERROR);
|
|
166
|
+
LuciqRNLogger.setLevel(parsedLogLevel);
|
|
167
|
+
LuciqRNLogger.d(NET_TAG, "[init] Called — logLevel=" + logLevel + ", useNativeNetworkInterception=" + useNativeNetworkInterception + ", codePushVersion=" + codePushVersion + ", appVariant=" + appVariant);
|
|
168
168
|
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
169
169
|
@Override
|
|
170
170
|
public void run() {
|
|
@@ -173,7 +173,6 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
173
173
|
final ArrayList<String> keys = ArrayUtil.parseReadableArrayOfStrings(invocationEventValues);
|
|
174
174
|
final ArrayList<LuciqInvocationEvent> parsedInvocationEvents = ArgsRegistry.invocationEvents.getAll(keys);
|
|
175
175
|
final LuciqInvocationEvent[] invocationEvents = parsedInvocationEvents.toArray(new LuciqInvocationEvent[0]);
|
|
176
|
-
final int parsedLogLevel = ArgsRegistry.sdkLogLevels.getOrDefault(logLevel, LogLevel.ERROR);
|
|
177
176
|
|
|
178
177
|
final Application application = (Application) reactContext.getApplicationContext();
|
|
179
178
|
|
|
@@ -181,7 +180,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
181
180
|
.setInvocationEvents(invocationEvents)
|
|
182
181
|
.setLogLevel(parsedLogLevel);
|
|
183
182
|
|
|
184
|
-
if (map!=null&&map.hasKey("ignoreAndroidSecureFlag")) {
|
|
183
|
+
if (map != null && map.hasKey("ignoreAndroidSecureFlag")) {
|
|
185
184
|
builder.ignoreFlagSecure(map.getBoolean("ignoreAndroidSecureFlag"));
|
|
186
185
|
}
|
|
187
186
|
|
|
@@ -192,12 +191,12 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
192
191
|
builder.setCodePushVersion(codePushVersion);
|
|
193
192
|
}
|
|
194
193
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
if (appVariant != null) {
|
|
195
|
+
builder.setAppVariant(appVariant);
|
|
196
|
+
}
|
|
198
197
|
|
|
199
|
-
if(overAirVersion != null
|
|
200
|
-
if(Luciq.isBuilt()) {
|
|
198
|
+
if (overAirVersion != null) {
|
|
199
|
+
if (Luciq.isBuilt()) {
|
|
201
200
|
Luciq.setOverAirVersion(overAirVersion.getString("version"),
|
|
202
201
|
ArgsRegistry.overAirUpdateService.get(overAirVersion.getString("service")));
|
|
203
202
|
} else {
|
|
@@ -206,7 +205,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
206
205
|
}
|
|
207
206
|
|
|
208
207
|
builder.build();
|
|
209
|
-
|
|
208
|
+
LuciqRNLogger.d(NET_TAG, "[init] SDK build complete");
|
|
210
209
|
}
|
|
211
210
|
});
|
|
212
211
|
}
|
|
@@ -550,7 +549,6 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
550
549
|
}
|
|
551
550
|
|
|
552
551
|
|
|
553
|
-
|
|
554
552
|
/**
|
|
555
553
|
* Removes user attribute if exists.
|
|
556
554
|
*
|
|
@@ -972,7 +970,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
972
970
|
final String requestHeaders,
|
|
973
971
|
final String responseHeaders,
|
|
974
972
|
final double duration) {
|
|
975
|
-
|
|
973
|
+
LuciqRNLogger.d(NET_TAG, "[networkLogAndroid-Core] Received from JS: " + method + " " + url + ", status=" + (int) responseCode + ", duration=" + (long) duration + "ms, reqBodyLen=" + (requestBody != null ? requestBody.length() : 0) + ", resBodyLen=" + (responseBody != null ? responseBody.length() : 0));
|
|
976
974
|
try {
|
|
977
975
|
final String date = String.valueOf(System.currentTimeMillis());
|
|
978
976
|
|
|
@@ -989,14 +987,14 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
989
987
|
networkLog.setRequestHeaders(requestHeaders);
|
|
990
988
|
networkLog.setResponseHeaders(responseHeaders);
|
|
991
989
|
} catch (OutOfMemoryError | Exception exception) {
|
|
992
|
-
|
|
990
|
+
LuciqRNLogger.e(NET_TAG, "[networkLogAndroid-Core] OOM/Error setting log contents: " + exception.getMessage() + " for " + method + " " + url);
|
|
993
991
|
Log.d(TAG, "Error: " + exception.getMessage() + "while trying to set network log contents (request body, response body, request headers, and response headers).");
|
|
994
992
|
}
|
|
995
993
|
|
|
996
994
|
networkLog.insert();
|
|
997
|
-
|
|
995
|
+
LuciqRNLogger.d(NET_TAG, "[networkLogAndroid-Core] Successfully inserted NetworkLog: " + method + " " + url);
|
|
998
996
|
} catch (OutOfMemoryError | Exception exception) {
|
|
999
|
-
|
|
997
|
+
LuciqRNLogger.e(NET_TAG, "[networkLogAndroid-Core] OOM/Error inserting network log: " + exception.getMessage() + " for " + method + " " + url);
|
|
1000
998
|
Log.d(TAG, "Error: " + exception.getMessage() + "while trying to insert a network log");
|
|
1001
999
|
}
|
|
1002
1000
|
}
|
|
@@ -1005,18 +1003,18 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1005
1003
|
@Nullable
|
|
1006
1004
|
private View resolveReactView(final int reactTag) {
|
|
1007
1005
|
try {
|
|
1008
|
-
|
|
1009
|
-
|
|
1006
|
+
final ReactApplicationContext reactContext = getReactApplicationContext();
|
|
1007
|
+
final UIManagerModule uiManagerModule = reactContext.getNativeModule(UIManagerModule.class);
|
|
1010
1008
|
|
|
1011
|
-
|
|
1009
|
+
if (uiManagerModule == null) {
|
|
1012
1010
|
UIManager uiNewManagerModule = UIManagerHelper.getUIManagerForReactTag(reactContext, reactTag);
|
|
1013
1011
|
if (uiNewManagerModule != null) {
|
|
1014
1012
|
return uiNewManagerModule.resolveView(reactTag);
|
|
1015
1013
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1018
1016
|
|
|
1019
|
-
|
|
1017
|
+
return uiManagerModule.resolveView(reactTag);
|
|
1020
1018
|
} catch (Exception e) {
|
|
1021
1019
|
return null;
|
|
1022
1020
|
}
|
|
@@ -1031,8 +1029,8 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1031
1029
|
try {
|
|
1032
1030
|
final View view = resolveReactView(reactTag);
|
|
1033
1031
|
|
|
1034
|
-
if(view !=null){
|
|
1035
|
-
|
|
1032
|
+
if (view != null) {
|
|
1033
|
+
Luciq.addPrivateViews(view);
|
|
1036
1034
|
}
|
|
1037
1035
|
} catch (Exception e) {
|
|
1038
1036
|
e.printStackTrace();
|
|
@@ -1048,9 +1046,9 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1048
1046
|
public void run() {
|
|
1049
1047
|
try {
|
|
1050
1048
|
final View view = resolveReactView(reactTag);
|
|
1051
|
-
if(view !=null){
|
|
1049
|
+
if (view != null) {
|
|
1052
1050
|
|
|
1053
|
-
|
|
1051
|
+
Luciq.removePrivateViews(view);
|
|
1054
1052
|
}
|
|
1055
1053
|
} catch (Exception e) {
|
|
1056
1054
|
e.printStackTrace();
|
|
@@ -1085,7 +1083,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1085
1083
|
* Reports that the screen has been changed (Repro Steps) the screen sent to this method will be the 'current view' on the dashboard
|
|
1086
1084
|
*
|
|
1087
1085
|
* @param screenName string containing the screen name
|
|
1088
|
-
* @param spanId
|
|
1086
|
+
* @param spanId the span ID for screen loading tracking (nullable)
|
|
1089
1087
|
*/
|
|
1090
1088
|
@ReactMethod
|
|
1091
1089
|
public void reportScreenChange(final String screenName, @Nullable final String spanId) {
|
|
@@ -1094,9 +1092,9 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1094
1092
|
public void run() {
|
|
1095
1093
|
try {
|
|
1096
1094
|
Long uiTraceId = spanId != null ? Long.parseLong(spanId) : null;
|
|
1097
|
-
Method method = getMethod(Class.forName("ai.luciq.library.Luciq"), "reportScreenChange", Bitmap.class, String.class
|
|
1095
|
+
Method method = getMethod(Class.forName("ai.luciq.library.Luciq"), "reportScreenChange", Bitmap.class, String.class, Long.class);
|
|
1098
1096
|
if (method != null) {
|
|
1099
|
-
method.invoke(null, null, screenName
|
|
1097
|
+
method.invoke(null, null, screenName, uiTraceId);
|
|
1100
1098
|
}
|
|
1101
1099
|
} catch (Exception e) {
|
|
1102
1100
|
e.printStackTrace();
|
|
@@ -1106,7 +1104,6 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1106
1104
|
}
|
|
1107
1105
|
|
|
1108
1106
|
|
|
1109
|
-
|
|
1110
1107
|
@ReactMethod
|
|
1111
1108
|
public void addFeatureFlags(final ReadableMap featureFlagsMap) {
|
|
1112
1109
|
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
@@ -1179,7 +1176,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1179
1176
|
*/
|
|
1180
1177
|
@ReactMethod
|
|
1181
1178
|
public void registerFeatureFlagsChangeListener() {
|
|
1182
|
-
|
|
1179
|
+
LuciqRNLogger.d(NET_TAG, "[registerFeatureFlagsChangeListener] Registering native feature flags listener");
|
|
1183
1180
|
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
1184
1181
|
@Override
|
|
1185
1182
|
public void run() {
|
|
@@ -1187,19 +1184,19 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1187
1184
|
InternalCore.INSTANCE._setFeaturesStateListener(new FeaturesStateListener() {
|
|
1188
1185
|
@Override
|
|
1189
1186
|
public void invoke(@NonNull CoreFeaturesState featuresState) {
|
|
1190
|
-
|
|
1187
|
+
LuciqRNLogger.d(NET_TAG, "[FeatureFlagsListener] Received update — W3CTraceID=" + featuresState.isW3CExternalTraceIdEnabled() + ", generatedHeader=" + featuresState.isAttachingGeneratedHeaderEnabled() + ", caughtHeader=" + featuresState.isAttachingCapturedHeaderEnabled() + ", networkBodyLimit=" + featuresState.getNetworkLogCharLimit());
|
|
1191
1188
|
WritableMap params = Arguments.createMap();
|
|
1192
1189
|
params.putBoolean("isW3ExternalTraceIDEnabled", featuresState.isW3CExternalTraceIdEnabled());
|
|
1193
1190
|
params.putBoolean("isW3ExternalGeneratedHeaderEnabled", featuresState.isAttachingGeneratedHeaderEnabled());
|
|
1194
1191
|
params.putBoolean("isW3CaughtHeaderEnabled", featuresState.isAttachingCapturedHeaderEnabled());
|
|
1195
|
-
params.putInt("networkBodyLimit",featuresState.getNetworkLogCharLimit());
|
|
1192
|
+
params.putInt("networkBodyLimit", featuresState.getNetworkLogCharLimit());
|
|
1196
1193
|
|
|
1197
1194
|
sendEvent(Constants.LCQ_ON_FEATURE_FLAGS_UPDATE_RECEIVED_CALLBACK, params);
|
|
1198
|
-
|
|
1195
|
+
LuciqRNLogger.d(NET_TAG, "[FeatureFlagsListener] Sent event to JS: " + Constants.LCQ_ON_FEATURE_FLAGS_UPDATE_RECEIVED_CALLBACK);
|
|
1199
1196
|
}
|
|
1200
1197
|
});
|
|
1201
1198
|
} catch (Exception e) {
|
|
1202
|
-
|
|
1199
|
+
LuciqRNLogger.e(NET_TAG, "[registerFeatureFlagsChangeListener] Failed to register listener", e);
|
|
1203
1200
|
e.printStackTrace();
|
|
1204
1201
|
}
|
|
1205
1202
|
|
|
@@ -1214,16 +1211,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1214
1211
|
*/
|
|
1215
1212
|
@ReactMethod
|
|
1216
1213
|
public void isW3ExternalTraceIDEnabled(Promise promise) {
|
|
1217
|
-
|
|
1214
|
+
LuciqRNLogger.d(NET_TAG, "[isW3ExternalTraceIDEnabled] Querying native flag");
|
|
1218
1215
|
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
1219
1216
|
@Override
|
|
1220
1217
|
public void run() {
|
|
1221
1218
|
try {
|
|
1222
1219
|
boolean enabled = InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_EXTERNAL_TRACE_ID);
|
|
1223
|
-
|
|
1220
|
+
LuciqRNLogger.d(NET_TAG, "[isW3ExternalTraceIDEnabled] Result=" + enabled);
|
|
1224
1221
|
promise.resolve(enabled);
|
|
1225
1222
|
} catch (Exception e) {
|
|
1226
|
-
|
|
1223
|
+
LuciqRNLogger.e(NET_TAG, "[isW3ExternalTraceIDEnabled] Error querying flag", e);
|
|
1227
1224
|
e.printStackTrace();
|
|
1228
1225
|
promise.resolve(false);
|
|
1229
1226
|
}
|
|
@@ -1239,16 +1236,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1239
1236
|
*/
|
|
1240
1237
|
@ReactMethod
|
|
1241
1238
|
public void isW3ExternalGeneratedHeaderEnabled(Promise promise) {
|
|
1242
|
-
|
|
1239
|
+
LuciqRNLogger.d(NET_TAG, "[isW3ExternalGeneratedHeaderEnabled] Querying native flag");
|
|
1243
1240
|
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
1244
1241
|
@Override
|
|
1245
1242
|
public void run() {
|
|
1246
1243
|
try {
|
|
1247
1244
|
boolean enabled = InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_GENERATED_HEADER);
|
|
1248
|
-
|
|
1245
|
+
LuciqRNLogger.d(NET_TAG, "[isW3ExternalGeneratedHeaderEnabled] Result=" + enabled);
|
|
1249
1246
|
promise.resolve(enabled);
|
|
1250
1247
|
} catch (Exception e) {
|
|
1251
|
-
|
|
1248
|
+
LuciqRNLogger.e(NET_TAG, "[isW3ExternalGeneratedHeaderEnabled] Error querying flag", e);
|
|
1252
1249
|
e.printStackTrace();
|
|
1253
1250
|
promise.resolve(false);
|
|
1254
1251
|
}
|
|
@@ -1263,16 +1260,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1263
1260
|
*/
|
|
1264
1261
|
@ReactMethod
|
|
1265
1262
|
public void isW3CaughtHeaderEnabled(Promise promise) {
|
|
1266
|
-
|
|
1263
|
+
LuciqRNLogger.d(NET_TAG, "[isW3CaughtHeaderEnabled] Querying native flag");
|
|
1267
1264
|
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
1268
1265
|
@Override
|
|
1269
1266
|
public void run() {
|
|
1270
1267
|
try {
|
|
1271
1268
|
boolean enabled = InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_CAPTURED_HEADER);
|
|
1272
|
-
|
|
1269
|
+
LuciqRNLogger.d(NET_TAG, "[isW3CaughtHeaderEnabled] Result=" + enabled);
|
|
1273
1270
|
promise.resolve(enabled);
|
|
1274
1271
|
} catch (Exception e) {
|
|
1275
|
-
|
|
1272
|
+
LuciqRNLogger.e(NET_TAG, "[isW3CaughtHeaderEnabled] Error querying flag", e);
|
|
1276
1273
|
e.printStackTrace();
|
|
1277
1274
|
promise.resolve(false);
|
|
1278
1275
|
}
|
|
@@ -1287,7 +1284,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1287
1284
|
* Map between the exported JS constant and the arg key in {@link ArgsRegistry}.
|
|
1288
1285
|
* The constant name and the arg key should match to be able to resolve the
|
|
1289
1286
|
* constant with its actual value from the {@link ArgsRegistry} maps.
|
|
1290
|
-
*
|
|
1287
|
+
* <p>
|
|
1291
1288
|
* This is a workaround, because RN cannot resolve enums in the constants map.
|
|
1292
1289
|
*/
|
|
1293
1290
|
@Override
|
|
@@ -1318,23 +1315,25 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1318
1315
|
}
|
|
1319
1316
|
});
|
|
1320
1317
|
}
|
|
1318
|
+
|
|
1321
1319
|
/**
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1320
|
+
* Enables or disables capturing network body.
|
|
1321
|
+
*
|
|
1322
|
+
* @param isEnabled A boolean to enable/disable capturing network body.
|
|
1323
|
+
*/
|
|
1324
|
+
@ReactMethod
|
|
1325
|
+
public void setNetworkLogBodyEnabled(final boolean isEnabled) {
|
|
1326
|
+
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
1327
|
+
@Override
|
|
1328
|
+
public void run() {
|
|
1329
|
+
try {
|
|
1330
|
+
Luciq.setNetworkLogBodyEnabled(isEnabled);
|
|
1331
|
+
} catch (Exception e) {
|
|
1332
|
+
e.printStackTrace();
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1338
1337
|
|
|
1339
1338
|
/**
|
|
1340
1339
|
* Sets the auto mask screenshots types.
|
|
@@ -1366,16 +1365,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1366
1365
|
*/
|
|
1367
1366
|
@ReactMethod
|
|
1368
1367
|
public void getNetworkBodyMaxSize(Promise promise) {
|
|
1369
|
-
|
|
1368
|
+
LuciqRNLogger.d(NET_TAG, "[getNetworkBodyMaxSize] Querying network body size limit");
|
|
1370
1369
|
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
1371
1370
|
@Override
|
|
1372
1371
|
public void run() {
|
|
1373
1372
|
try {
|
|
1374
1373
|
Object limit = InternalCore.INSTANCE.get_networkLogCharLimit();
|
|
1375
|
-
|
|
1374
|
+
LuciqRNLogger.d(NET_TAG, "[getNetworkBodyMaxSize] Result=" + limit);
|
|
1376
1375
|
promise.resolve(limit);
|
|
1377
1376
|
} catch (Exception e) {
|
|
1378
|
-
|
|
1377
|
+
LuciqRNLogger.e(NET_TAG, "[getNetworkBodyMaxSize] Error querying limit", e);
|
|
1379
1378
|
e.printStackTrace();
|
|
1380
1379
|
promise.resolve(false);
|
|
1381
1380
|
}
|
|
@@ -1383,20 +1382,20 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1383
1382
|
});
|
|
1384
1383
|
}
|
|
1385
1384
|
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1385
|
+
/**
|
|
1386
|
+
* Sets current App variant
|
|
1387
|
+
*
|
|
1388
|
+
* @param appVariant The app variant name .
|
|
1389
|
+
*/
|
|
1390
|
+
@ReactMethod
|
|
1391
|
+
public void setAppVariant(@NonNull String appVariant) {
|
|
1392
|
+
try {
|
|
1393
|
+
Luciq.setAppVariant(appVariant);
|
|
1395
1394
|
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
}
|
|
1395
|
+
} catch (Exception e) {
|
|
1396
|
+
e.printStackTrace();
|
|
1399
1397
|
}
|
|
1398
|
+
}
|
|
1400
1399
|
|
|
1401
1400
|
/**
|
|
1402
1401
|
* Enables or disables WebView monitoring.
|
|
@@ -1527,17 +1526,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1527
1526
|
}
|
|
1528
1527
|
|
|
1529
1528
|
|
|
1530
|
-
|
|
1531
1529
|
/**
|
|
1532
1530
|
* Applies a color to the theme builder if present in the configuration.
|
|
1533
1531
|
*
|
|
1534
1532
|
* @param themeConfig The theme configuration map
|
|
1535
|
-
* @param builder
|
|
1536
|
-
* @param key
|
|
1537
|
-
* @param setter
|
|
1533
|
+
* @param builder The theme builder
|
|
1534
|
+
* @param key The configuration key
|
|
1535
|
+
* @param setter The color setter function
|
|
1538
1536
|
*/
|
|
1539
1537
|
private void applyColorIfPresent(ReadableMap themeConfig, ai.luciq.library.model.LuciqTheme.Builder builder,
|
|
1540
|
-
|
|
1538
|
+
String key, java.util.function.BiConsumer<ai.luciq.library.model.LuciqTheme.Builder, Integer> setter) {
|
|
1541
1539
|
if (themeConfig.hasKey(key)) {
|
|
1542
1540
|
int color = getColor(themeConfig, key);
|
|
1543
1541
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
@@ -1550,12 +1548,12 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1550
1548
|
* Applies a text style to the theme builder if present in the configuration.
|
|
1551
1549
|
*
|
|
1552
1550
|
* @param themeConfig The theme configuration map
|
|
1553
|
-
* @param builder
|
|
1554
|
-
* @param key
|
|
1555
|
-
* @param setter
|
|
1551
|
+
* @param builder The theme builder
|
|
1552
|
+
* @param key The configuration key
|
|
1553
|
+
* @param setter The text style setter function
|
|
1556
1554
|
*/
|
|
1557
1555
|
private void applyTextStyleIfPresent(ReadableMap themeConfig, ai.luciq.library.model.LuciqTheme.Builder builder,
|
|
1558
|
-
|
|
1556
|
+
String key, java.util.function.BiConsumer<ai.luciq.library.model.LuciqTheme.Builder, Integer> setter) {
|
|
1559
1557
|
if (themeConfig.hasKey(key)) {
|
|
1560
1558
|
int style = getTextStyle(themeConfig, key);
|
|
1561
1559
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
@@ -1568,13 +1566,13 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1568
1566
|
* Sets a font on the theme builder if the font configuration is present in the theme config.
|
|
1569
1567
|
*
|
|
1570
1568
|
* @param themeConfig The theme configuration map
|
|
1571
|
-
* @param builder
|
|
1572
|
-
* @param fileKey
|
|
1573
|
-
* @param assetKey
|
|
1574
|
-
* @param fontType
|
|
1569
|
+
* @param builder The theme builder
|
|
1570
|
+
* @param fileKey The key for font file path
|
|
1571
|
+
* @param assetKey The key for font asset path
|
|
1572
|
+
* @param fontType The type of font (for logging purposes)
|
|
1575
1573
|
*/
|
|
1576
1574
|
private void setFontIfPresent(ReadableMap themeConfig, ai.luciq.library.model.LuciqTheme.Builder builder,
|
|
1577
|
-
|
|
1575
|
+
String fileKey, String assetKey, String fontType) {
|
|
1578
1576
|
if (themeConfig.hasKey(fileKey) || themeConfig.hasKey(assetKey)) {
|
|
1579
1577
|
Typeface typeface = getTypeface(themeConfig, fileKey, assetKey);
|
|
1580
1578
|
if (typeface != null) {
|
|
@@ -1659,27 +1657,28 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
|
|
|
1659
1657
|
return Typeface.DEFAULT;
|
|
1660
1658
|
}
|
|
1661
1659
|
|
|
1662
|
-
/**
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
private String getFileName(String path) {
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1660
|
+
/**
|
|
1661
|
+
* Extracts the filename from a path, removing any directory prefixes.
|
|
1662
|
+
*
|
|
1663
|
+
* @param path The full path to the file
|
|
1664
|
+
* @return Just the filename with extension
|
|
1665
|
+
*/
|
|
1666
|
+
private String getFileName(String path) {
|
|
1667
|
+
if (path == null || path.isEmpty()) {
|
|
1668
|
+
return path;
|
|
1669
|
+
}
|
|
1672
1670
|
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1671
|
+
int lastSeparator = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
|
|
1672
|
+
if (lastSeparator >= 0 && lastSeparator < path.length() - 1) {
|
|
1673
|
+
return path.substring(lastSeparator + 1);
|
|
1674
|
+
}
|
|
1677
1675
|
|
|
1678
|
-
|
|
1679
|
-
}
|
|
1676
|
+
return path;
|
|
1677
|
+
}
|
|
1680
1678
|
|
|
1681
|
-
|
|
1679
|
+
/**
|
|
1682
1680
|
* Enables or disables displaying in full-screen mode, hiding the status and navigation bars.
|
|
1681
|
+
*
|
|
1683
1682
|
* @param isEnabled A boolean to enable/disable setFullscreen.
|
|
1684
1683
|
*/
|
|
1685
1684
|
@ReactMethod
|
|
@@ -1688,7 +1687,7 @@ private String getFileName(String path) {
|
|
|
1688
1687
|
@Override
|
|
1689
1688
|
public void run() {
|
|
1690
1689
|
try {
|
|
1691
|
-
|
|
1690
|
+
Luciq.setFullscreen(isEnabled);
|
|
1692
1691
|
} catch (Exception e) {
|
|
1693
1692
|
e.printStackTrace();
|
|
1694
1693
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
package ai.luciq.reactlibrary.utils;
|
|
2
2
|
|
|
3
|
-
import android.util.Log;
|
|
4
|
-
|
|
5
3
|
import androidx.annotation.Nullable;
|
|
6
4
|
import androidx.annotation.VisibleForTesting;
|
|
7
5
|
|
|
@@ -26,17 +24,17 @@ public abstract class EventEmitterModule extends ReactContextBaseJavaModule {
|
|
|
26
24
|
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
27
25
|
.emit(event, params);
|
|
28
26
|
} else {
|
|
29
|
-
|
|
27
|
+
LuciqRNLogger.w(NET_TAG, "[EventEmitter] Event DROPPED (no JS listeners): event=" + event + ", module=" + getName() + ", listenerCount=0");
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
protected void addListener(String ignoredEvent) {
|
|
34
32
|
listenerCount++;
|
|
35
|
-
|
|
33
|
+
LuciqRNLogger.d(NET_TAG, "[EventEmitter] addListener — module=" + getName() + ", event=" + ignoredEvent + ", listenerCount=" + listenerCount);
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
protected void removeListeners(Integer count) {
|
|
39
37
|
listenerCount -= count;
|
|
40
|
-
|
|
38
|
+
LuciqRNLogger.d(NET_TAG, "[EventEmitter] removeListeners — module=" + getName() + ", removed=" + count + ", listenerCount=" + listenerCount);
|
|
41
39
|
}
|
|
42
40
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
package ai.luciq.reactlibrary.utils;
|
|
2
|
+
|
|
3
|
+
import android.util.Log;
|
|
4
|
+
|
|
5
|
+
import ai.luciq.library.LogLevel;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Bridge-side logger that gates android.util.Log calls on the same
|
|
9
|
+
* debugLogsLevel the host app passes to Luciq.init(), so the native
|
|
10
|
+
* RN bridge diagnostic logs do not leak in production builds when the
|
|
11
|
+
* JS-side Logger is silent.
|
|
12
|
+
*
|
|
13
|
+
* Mirrors the level hierarchy in src/utils/logger.ts:
|
|
14
|
+
* VERBOSE > DEBUG > ERROR > NONE
|
|
15
|
+
*/
|
|
16
|
+
public final class LuciqRNLogger {
|
|
17
|
+
|
|
18
|
+
private static volatile int currentLevel = LogLevel.ERROR;
|
|
19
|
+
|
|
20
|
+
private LuciqRNLogger() {}
|
|
21
|
+
|
|
22
|
+
public static void setLevel(int level) {
|
|
23
|
+
currentLevel = level;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public static int getLevel() {
|
|
27
|
+
return currentLevel;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public static void d(String tag, String message) {
|
|
31
|
+
if (currentLevel >= LogLevel.DEBUG) {
|
|
32
|
+
Log.d(tag, message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public static void w(String tag, String message) {
|
|
37
|
+
if (currentLevel >= LogLevel.DEBUG) {
|
|
38
|
+
Log.w(tag, message);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public static void e(String tag, String message) {
|
|
43
|
+
if (currentLevel >= LogLevel.ERROR) {
|
|
44
|
+
Log.e(tag, message);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public static void e(String tag, String message, Throwable throwable) {
|
|
49
|
+
if (currentLevel >= LogLevel.ERROR) {
|
|
50
|
+
Log.e(tag, message, throwable);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|