@sentry/react-native 7.11.0 → 8.0.0-alpha.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.
Files changed (76) hide show
  1. package/RNSentry.podspec +8 -4
  2. package/android/libs/replay-stubs.jar +0 -0
  3. package/android/src/main/java/io/sentry/react/RNSentryCompositeOptionsConfiguration.java +25 -0
  4. package/android/src/main/java/io/sentry/react/RNSentryJsonConverter.java +76 -0
  5. package/android/src/main/java/io/sentry/react/RNSentryJsonUtils.java +41 -0
  6. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +2 -398
  7. package/android/src/main/java/io/sentry/react/RNSentrySDK.java +68 -0
  8. package/android/src/main/java/io/sentry/react/RNSentryStart.java +417 -0
  9. package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
  10. package/dist/js/replay/mobilereplay.d.ts +0 -26
  11. package/dist/js/replay/mobilereplay.d.ts.map +1 -1
  12. package/dist/js/replay/mobilereplay.js.map +1 -1
  13. package/dist/js/sdk.d.ts.map +1 -1
  14. package/dist/js/sdk.js +21 -10
  15. package/dist/js/sdk.js.map +1 -1
  16. package/dist/js/tools/metroconfig.d.ts +9 -1
  17. package/dist/js/tools/metroconfig.d.ts.map +1 -1
  18. package/dist/js/tools/metroconfig.js +9 -2
  19. package/dist/js/tools/metroconfig.js.map +1 -1
  20. package/dist/js/tools/sentryMetroSerializer.d.ts.map +1 -1
  21. package/dist/js/tools/sentryMetroSerializer.js +1 -0
  22. package/dist/js/tools/sentryMetroSerializer.js.map +1 -1
  23. package/dist/js/tools/sentryOptionsSerializer.d.ts +6 -0
  24. package/dist/js/tools/sentryOptionsSerializer.d.ts.map +1 -0
  25. package/dist/js/tools/sentryOptionsSerializer.js +92 -0
  26. package/dist/js/tools/sentryOptionsSerializer.js.map +1 -0
  27. package/dist/js/tools/utils.d.ts +2 -1
  28. package/dist/js/tools/utils.d.ts.map +1 -1
  29. package/dist/js/tools/utils.js.map +1 -1
  30. package/dist/js/utils/worldwide.d.ts +2 -0
  31. package/dist/js/utils/worldwide.d.ts.map +1 -1
  32. package/dist/js/utils/worldwide.js.map +1 -1
  33. package/dist/js/version.d.ts +1 -1
  34. package/dist/js/version.d.ts.map +1 -1
  35. package/dist/js/version.js +1 -1
  36. package/dist/js/version.js.map +1 -1
  37. package/ios/RNSentry.h +3 -0
  38. package/ios/RNSentry.mm +12 -44
  39. package/ios/RNSentryDependencyContainer.h +2 -1
  40. package/ios/RNSentryDependencyContainer.m +1 -0
  41. package/ios/RNSentryEmitNewFrameEvent.h +3 -0
  42. package/ios/RNSentryExperimentalOptions.m +1 -1
  43. package/ios/RNSentryFramesTrackerListener.h +2 -2
  44. package/ios/RNSentryFramesTrackerListener.m +2 -0
  45. package/ios/RNSentryOnDrawReporter.h +2 -1
  46. package/ios/RNSentryOnDrawReporter.m +2 -0
  47. package/ios/RNSentryRNSScreen.m +3 -4
  48. package/ios/RNSentryReplay.mm +0 -5
  49. package/ios/RNSentryReplayBreadcrumbConverter.m +12 -12
  50. package/ios/RNSentrySDK.h +31 -0
  51. package/ios/RNSentrySDK.m +78 -0
  52. package/ios/RNSentryStart.h +25 -0
  53. package/ios/RNSentryStart.m +228 -0
  54. package/ios/RNSentryVersion.m +1 -1
  55. package/ios/SentryScreenFramesWrapper.h +14 -0
  56. package/ios/SentryScreenFramesWrapper.m +39 -0
  57. package/package.json +2 -2
  58. package/plugin/build/logger.d.ts +24 -0
  59. package/plugin/build/logger.js +44 -0
  60. package/plugin/build/utils.d.ts +0 -18
  61. package/plugin/build/utils.js +1 -34
  62. package/plugin/build/version.d.ts +2 -0
  63. package/plugin/build/version.js +6 -0
  64. package/plugin/build/withSentry.d.ts +1 -0
  65. package/plugin/build/withSentry.js +11 -10
  66. package/plugin/build/withSentryAndroid.d.ts +6 -1
  67. package/plugin/build/withSentryAndroid.js +52 -8
  68. package/plugin/build/withSentryAndroidGradlePlugin.d.ts +1 -1
  69. package/plugin/build/withSentryAndroidGradlePlugin.js +8 -8
  70. package/plugin/build/withSentryIOS.d.ts +6 -1
  71. package/plugin/build/withSentryIOS.js +55 -7
  72. package/scripts/sentry-xcode.sh +20 -0
  73. package/sentry.gradle +51 -0
  74. package/ts3.8/dist/js/replay/mobilereplay.d.ts +0 -26
  75. package/ts3.8/dist/js/utils/worldwide.d.ts +2 -0
  76. package/ts3.8/dist/js/version.d.ts +1 -1
package/RNSentry.podspec CHANGED
@@ -42,11 +42,15 @@ Pod::Spec.new do |s|
42
42
  s.preserve_paths = '*.js'
43
43
 
44
44
  s.source_files = 'ios/**/*.{h,m,mm}'
45
- s.public_header_files = 'ios/RNSentry.h'
45
+ s.public_header_files = 'ios/RNSentry.h', 'ios/RNSentrySDK.h', 'ios/RNSentryStart.h', 'ios/RNSentryVersion.h', 'ios/RNSentryBreadcrumb.h', 'ios/RNSentryReplay.h', 'ios/RNSentryReplayBreadcrumbConverter.h', 'ios/Replay/RNSentryReplayMask.h', 'ios/Replay/RNSentryReplayUnmask.h', 'ios/RNSentryTimeToDisplay.h'
46
46
 
47
47
  s.compiler_flags = other_cflags
48
48
 
49
- s.dependency 'Sentry/HybridSDK', '8.58.0'
49
+ s.pod_target_xcconfig = {
50
+ 'DEFINES_MODULE' => 'YES'
51
+ }
52
+
53
+ s.dependency 'Sentry/HybridSDK', '9.1.0'
50
54
 
51
55
  if defined? install_modules_dependencies
52
56
  # Default React Native dependencies for 0.71 and above (new and legacy architecture)
@@ -56,10 +60,10 @@ Pod::Spec.new do |s|
56
60
 
57
61
  if is_new_arch_enabled then
58
62
  # New Architecture on React Native 0.70 and older
59
- s.pod_target_xcconfig = {
63
+ s.pod_target_xcconfig.merge!({
60
64
  "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
61
65
  "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
62
- }
66
+ })
63
67
 
64
68
  s.dependency "React-RCTFabric" # Required for Fabric Components (like RCTViewComponentView)
65
69
  s.dependency "React-Codegen"
Binary file
@@ -0,0 +1,25 @@
1
+ package io.sentry.react;
2
+
3
+ import io.sentry.Sentry.OptionsConfiguration;
4
+ import io.sentry.android.core.SentryAndroidOptions;
5
+ import java.util.List;
6
+ import org.jetbrains.annotations.NotNull;
7
+
8
+ class RNSentryCompositeOptionsConfiguration implements OptionsConfiguration<SentryAndroidOptions> {
9
+ private final @NotNull List<OptionsConfiguration<SentryAndroidOptions>> configurations;
10
+
11
+ @SafeVarargs
12
+ protected RNSentryCompositeOptionsConfiguration(
13
+ @NotNull OptionsConfiguration<SentryAndroidOptions>... configurations) {
14
+ this.configurations = List.of(configurations);
15
+ }
16
+
17
+ @Override
18
+ public void configure(@NotNull SentryAndroidOptions options) {
19
+ for (OptionsConfiguration<SentryAndroidOptions> configuration : configurations) {
20
+ if (configuration != null) {
21
+ configuration.configure(options);
22
+ }
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,76 @@
1
+ package io.sentry.react;
2
+
3
+ import com.facebook.react.bridge.JavaOnlyArray;
4
+ import com.facebook.react.bridge.JavaOnlyMap;
5
+ import com.facebook.react.bridge.WritableArray;
6
+ import com.facebook.react.bridge.WritableMap;
7
+ import io.sentry.ILogger;
8
+ import io.sentry.SentryLevel;
9
+ import io.sentry.android.core.AndroidLogger;
10
+ import java.util.Iterator;
11
+ import org.jetbrains.annotations.NotNull;
12
+ import org.jetbrains.annotations.Nullable;
13
+ import org.json.JSONArray;
14
+ import org.json.JSONException;
15
+ import org.json.JSONObject;
16
+
17
+ final class RNSentryJsonConverter {
18
+ public static final String NAME = "RNSentry.RNSentryJsonConverter";
19
+
20
+ private static final ILogger logger = new AndroidLogger(NAME);
21
+
22
+ private RNSentryJsonConverter() {
23
+ throw new AssertionError("Utility class should not be instantiated");
24
+ }
25
+
26
+ @Nullable
27
+ static WritableMap convertToWritable(@NotNull JSONObject jsonObject) {
28
+ try {
29
+ WritableMap writableMap = new JavaOnlyMap();
30
+ Iterator<String> iterator = jsonObject.keys();
31
+ while (iterator.hasNext()) {
32
+ String key = iterator.next();
33
+ Object value = jsonObject.get(key);
34
+ if (value instanceof Float || value instanceof Double) {
35
+ writableMap.putDouble(key, jsonObject.getDouble(key));
36
+ } else if (value instanceof Number) {
37
+ writableMap.putInt(key, jsonObject.getInt(key));
38
+ } else if (value instanceof String) {
39
+ writableMap.putString(key, jsonObject.getString(key));
40
+ } else if (value instanceof JSONObject) {
41
+ writableMap.putMap(key, convertToWritable(jsonObject.getJSONObject(key)));
42
+ } else if (value instanceof JSONArray) {
43
+ writableMap.putArray(key, convertToWritable(jsonObject.getJSONArray(key)));
44
+ } else if (value == JSONObject.NULL) {
45
+ writableMap.putNull(key);
46
+ }
47
+ }
48
+ return writableMap;
49
+ } catch (JSONException e) {
50
+ logger.log(SentryLevel.ERROR, "Error parsing json object:" + e.getMessage());
51
+ return null;
52
+ }
53
+ }
54
+
55
+ @NotNull
56
+ static WritableArray convertToWritable(@NotNull JSONArray jsonArray) throws JSONException {
57
+ WritableArray writableArray = new JavaOnlyArray();
58
+ for (int i = 0; i < jsonArray.length(); i++) {
59
+ Object value = jsonArray.get(i);
60
+ if (value instanceof Float || value instanceof Double) {
61
+ writableArray.pushDouble(jsonArray.getDouble(i));
62
+ } else if (value instanceof Number) {
63
+ writableArray.pushInt(jsonArray.getInt(i));
64
+ } else if (value instanceof String) {
65
+ writableArray.pushString(jsonArray.getString(i));
66
+ } else if (value instanceof JSONObject) {
67
+ writableArray.pushMap(convertToWritable(jsonArray.getJSONObject(i)));
68
+ } else if (value instanceof JSONArray) {
69
+ writableArray.pushArray(convertToWritable(jsonArray.getJSONArray(i)));
70
+ } else if (value == JSONObject.NULL) {
71
+ writableArray.pushNull();
72
+ }
73
+ }
74
+ return writableArray;
75
+ }
76
+ }
@@ -0,0 +1,41 @@
1
+ package io.sentry.react;
2
+
3
+ import android.content.Context;
4
+ import io.sentry.ILogger;
5
+ import io.sentry.SentryLevel;
6
+ import java.io.BufferedReader;
7
+ import java.io.InputStream;
8
+ import java.io.InputStreamReader;
9
+ import org.jetbrains.annotations.NotNull;
10
+ import org.jetbrains.annotations.Nullable;
11
+ import org.json.JSONObject;
12
+
13
+ final class RNSentryJsonUtils {
14
+ private RNSentryJsonUtils() {
15
+ throw new AssertionError("Utility class should not be instantiated");
16
+ }
17
+
18
+ static @Nullable JSONObject getOptionsFromConfigurationFile(
19
+ @NotNull Context context, @NotNull String fileName, @NotNull ILogger logger) {
20
+ try (InputStream inputStream = context.getAssets().open(fileName);
21
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
22
+
23
+ StringBuilder stringBuilder = new StringBuilder();
24
+ String line;
25
+ while ((line = reader.readLine()) != null) {
26
+ stringBuilder.append(line);
27
+ }
28
+ String configFileContent = stringBuilder.toString();
29
+ return new JSONObject(configFileContent);
30
+
31
+ } catch (Exception e) {
32
+ logger.log(
33
+ SentryLevel.ERROR,
34
+ "Failed to read configuration file. Please make sure "
35
+ + fileName
36
+ + " exists in the root of your project.",
37
+ e);
38
+ return null;
39
+ }
40
+ }
41
+ }
@@ -23,41 +23,27 @@ import com.facebook.react.bridge.ReactApplicationContext;
23
23
  import com.facebook.react.bridge.ReadableArray;
24
24
  import com.facebook.react.bridge.ReadableMap;
25
25
  import com.facebook.react.bridge.ReadableMapKeySetIterator;
26
- import com.facebook.react.bridge.ReadableType;
27
26
  import com.facebook.react.bridge.UiThreadUtil;
28
27
  import com.facebook.react.bridge.WritableArray;
29
28
  import com.facebook.react.bridge.WritableMap;
30
29
  import com.facebook.react.bridge.WritableNativeArray;
31
30
  import com.facebook.react.bridge.WritableNativeMap;
32
- import com.facebook.react.common.JavascriptException;
33
31
  import io.sentry.Breadcrumb;
34
32
  import io.sentry.ILogger;
35
33
  import io.sentry.IScope;
36
34
  import io.sentry.ISentryExecutorService;
37
35
  import io.sentry.ISerializer;
38
- import io.sentry.Integration;
39
- import io.sentry.ProfileLifecycle;
40
36
  import io.sentry.ScopesAdapter;
41
- import io.sentry.ScreenshotStrategyType;
42
37
  import io.sentry.Sentry;
43
38
  import io.sentry.SentryDate;
44
39
  import io.sentry.SentryDateProvider;
45
- import io.sentry.SentryEvent;
46
40
  import io.sentry.SentryExecutorService;
47
41
  import io.sentry.SentryLevel;
48
42
  import io.sentry.SentryOptions;
49
- import io.sentry.SentryReplayOptions;
50
- import io.sentry.SentryReplayOptions.SentryReplayQuality;
51
- import io.sentry.UncaughtExceptionHandlerIntegration;
52
43
  import io.sentry.android.core.AndroidLogger;
53
44
  import io.sentry.android.core.AndroidProfiler;
54
- import io.sentry.android.core.AnrIntegration;
55
- import io.sentry.android.core.BuildConfig;
56
45
  import io.sentry.android.core.BuildInfoProvider;
57
- import io.sentry.android.core.CurrentActivityHolder;
58
46
  import io.sentry.android.core.InternalSentrySdk;
59
- import io.sentry.android.core.NdkIntegration;
60
- import io.sentry.android.core.SentryAndroid;
61
47
  import io.sentry.android.core.SentryAndroidDateProvider;
62
48
  import io.sentry.android.core.SentryAndroidOptions;
63
49
  import io.sentry.android.core.ViewHierarchyEventProcessor;
@@ -67,12 +53,8 @@ import io.sentry.android.core.performance.AppStartMetrics;
67
53
  import io.sentry.protocol.Geo;
68
54
  import io.sentry.protocol.SdkVersion;
69
55
  import io.sentry.protocol.SentryId;
70
- import io.sentry.protocol.SentryPackage;
71
56
  import io.sentry.protocol.User;
72
57
  import io.sentry.protocol.ViewHierarchy;
73
- import io.sentry.react.replay.RNSentryReplayFragmentLifecycleTracer;
74
- import io.sentry.react.replay.RNSentryReplayMask;
75
- import io.sentry.react.replay.RNSentryReplayUnmask;
76
58
  import io.sentry.util.DebugMetaPropertiesApplier;
77
59
  import io.sentry.util.FileUtils;
78
60
  import io.sentry.util.JsonSerializationUtils;
@@ -93,10 +75,8 @@ import java.util.ArrayList;
93
75
  import java.util.HashMap;
94
76
  import java.util.Iterator;
95
77
  import java.util.List;
96
- import java.util.Locale;
97
78
  import java.util.Map;
98
79
  import java.util.Properties;
99
- import java.util.Set;
100
80
  import java.util.concurrent.CountDownLatch;
101
81
  import java.util.regex.Pattern;
102
82
  import org.jetbrains.annotations.NotNull;
@@ -185,30 +165,13 @@ public class RNSentryModuleImpl {
185
165
  }
186
166
  }
187
167
 
188
- private void initFragmentReplayTracking() {
189
- final RNSentryReplayFragmentLifecycleTracer fragmentLifecycleTracer =
190
- new RNSentryReplayFragmentLifecycleTracer(logger);
191
-
192
- final @Nullable Activity currentActivity = getCurrentActivity();
193
- if (!(currentActivity instanceof FragmentActivity)) {
194
- return;
195
- }
196
-
197
- final @NotNull FragmentActivity fragmentActivity = (FragmentActivity) currentActivity;
198
- final @Nullable FragmentManager supportFragmentManager =
199
- fragmentActivity.getSupportFragmentManager();
200
- if (supportFragmentManager != null) {
201
- supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleTracer, true);
202
- }
203
- }
204
-
205
168
  public void initNativeReactNavigationNewFrameTracking(Promise promise) {
206
169
  this.initFragmentInitialFrameTracking();
207
170
  }
208
171
 
209
172
  public void initNativeSdk(final ReadableMap rnOptions, Promise promise) {
210
- SentryAndroid.init(
211
- getApplicationContext(), options -> getSentryAndroidOptions(options, rnOptions, logger));
173
+ RNSentryStart.startWithOptions(
174
+ getApplicationContext(), rnOptions, getCurrentActivity(), logger);
212
175
 
213
176
  promise.resolve(true);
214
177
  }
@@ -224,320 +187,6 @@ public class RNSentryModuleImpl {
224
187
  return context;
225
188
  }
226
189
 
227
- protected void getSentryAndroidOptions(
228
- @NotNull SentryAndroidOptions options, @NotNull ReadableMap rnOptions, ILogger logger) {
229
- @Nullable SdkVersion sdkVersion = options.getSdkVersion();
230
- if (sdkVersion == null) {
231
- sdkVersion = new SdkVersion(RNSentryVersion.ANDROID_SDK_NAME, BuildConfig.VERSION_NAME);
232
- } else {
233
- sdkVersion.setName(RNSentryVersion.ANDROID_SDK_NAME);
234
- }
235
- sdkVersion.addPackage(
236
- RNSentryVersion.REACT_NATIVE_SDK_PACKAGE_NAME,
237
- RNSentryVersion.REACT_NATIVE_SDK_PACKAGE_VERSION);
238
-
239
- options.setSentryClientName(sdkVersion.getName() + "/" + sdkVersion.getVersion());
240
- options.setNativeSdkName(RNSentryVersion.NATIVE_SDK_NAME);
241
- options.setSdkVersion(sdkVersion);
242
-
243
- if (rnOptions.hasKey("debug") && rnOptions.getBoolean("debug")) {
244
- options.setDebug(true);
245
- }
246
- if (rnOptions.hasKey("enabled")) {
247
- options.setEnabled(rnOptions.getBoolean("enabled"));
248
- }
249
- if (rnOptions.hasKey("dsn") && rnOptions.getString("dsn") != null) {
250
- String dsn = rnOptions.getString("dsn");
251
- logger.log(SentryLevel.INFO, String.format("Starting with DSN: '%s'", dsn));
252
- options.setDsn(dsn);
253
- } else {
254
- // SentryAndroid needs an empty string fallback for the dsn.
255
- options.setDsn("");
256
- }
257
- if (rnOptions.hasKey("sampleRate")) {
258
- options.setSampleRate(rnOptions.getDouble("sampleRate"));
259
- }
260
- if (rnOptions.hasKey("sendClientReports")) {
261
- options.setSendClientReports(rnOptions.getBoolean("sendClientReports"));
262
- }
263
- if (rnOptions.hasKey("maxBreadcrumbs")) {
264
- options.setMaxBreadcrumbs(rnOptions.getInt("maxBreadcrumbs"));
265
- }
266
- if (rnOptions.hasKey("maxCacheItems")) {
267
- options.setMaxCacheItems(rnOptions.getInt("maxCacheItems"));
268
- }
269
- if (rnOptions.hasKey("environment") && rnOptions.getString("environment") != null) {
270
- options.setEnvironment(rnOptions.getString("environment"));
271
- }
272
- if (rnOptions.hasKey("release") && rnOptions.getString("release") != null) {
273
- options.setRelease(rnOptions.getString("release"));
274
- }
275
- if (rnOptions.hasKey("dist") && rnOptions.getString("dist") != null) {
276
- options.setDist(rnOptions.getString("dist"));
277
- }
278
- if (rnOptions.hasKey("enableAutoSessionTracking")) {
279
- options.setEnableAutoSessionTracking(rnOptions.getBoolean("enableAutoSessionTracking"));
280
- }
281
- if (rnOptions.hasKey("sessionTrackingIntervalMillis")) {
282
- options.setSessionTrackingIntervalMillis(rnOptions.getInt("sessionTrackingIntervalMillis"));
283
- }
284
- if (rnOptions.hasKey("shutdownTimeout")) {
285
- options.setShutdownTimeoutMillis(rnOptions.getInt("shutdownTimeout"));
286
- }
287
- if (rnOptions.hasKey("enableNdkScopeSync")) {
288
- options.setEnableScopeSync(rnOptions.getBoolean("enableNdkScopeSync"));
289
- }
290
- if (rnOptions.hasKey("attachStacktrace")) {
291
- options.setAttachStacktrace(rnOptions.getBoolean("attachStacktrace"));
292
- }
293
- if (rnOptions.hasKey("attachThreads")) {
294
- // JS use top level stacktrace and android attaches Threads which hides them so
295
- // by default we hide.
296
- options.setAttachThreads(rnOptions.getBoolean("attachThreads"));
297
- }
298
- if (rnOptions.hasKey("attachScreenshot")) {
299
- options.setAttachScreenshot(rnOptions.getBoolean("attachScreenshot"));
300
- }
301
- if (rnOptions.hasKey("attachViewHierarchy")) {
302
- options.setAttachViewHierarchy(rnOptions.getBoolean("attachViewHierarchy"));
303
- }
304
- if (rnOptions.hasKey("sendDefaultPii")) {
305
- options.setSendDefaultPii(rnOptions.getBoolean("sendDefaultPii"));
306
- }
307
- if (rnOptions.hasKey("maxQueueSize")) {
308
- options.setMaxQueueSize(rnOptions.getInt("maxQueueSize"));
309
- }
310
- if (rnOptions.hasKey("enableNdk")) {
311
- options.setEnableNdk(rnOptions.getBoolean("enableNdk"));
312
- }
313
- if (rnOptions.hasKey("enableLogs")) {
314
- options.getLogs().setEnabled(rnOptions.getBoolean("enableLogs"));
315
- }
316
- if (rnOptions.hasKey("spotlight")) {
317
- if (rnOptions.getType("spotlight") == ReadableType.Boolean) {
318
- options.setEnableSpotlight(rnOptions.getBoolean("spotlight"));
319
- options.setSpotlightConnectionUrl(rnOptions.getString("defaultSidecarUrl"));
320
- } else if (rnOptions.getType("spotlight") == ReadableType.String) {
321
- options.setEnableSpotlight(true);
322
- options.setSpotlightConnectionUrl(rnOptions.getString("spotlight"));
323
- }
324
- }
325
-
326
- SentryReplayOptions replayOptions = getReplayOptions(rnOptions);
327
- options.setSessionReplay(replayOptions);
328
- // Check if the replay integration is available on the classpath. It's already
329
- // kept from R8
330
- // shrinking by sentry-android-core
331
- final boolean isReplayAvailable =
332
- loadClass.isClassAvailable("io.sentry.android.replay.ReplayIntegration", logger);
333
- if (isReplayEnabled(replayOptions) && isReplayAvailable) {
334
- options.getReplayController().setBreadcrumbConverter(new RNSentryReplayBreadcrumbConverter());
335
- initFragmentReplayTracking();
336
- }
337
-
338
- // Configure Android UI Profiling
339
- configureAndroidProfiling(options, rnOptions);
340
-
341
- // Exclude Dev Server and Sentry Dsn request from Breadcrumbs
342
- String dsn = getURLFromDSN(rnOptions.getString("dsn"));
343
- String devServerUrl = rnOptions.getString("devServerUrl");
344
- options.setBeforeBreadcrumb(
345
- (breadcrumb, hint) -> {
346
- Object urlObject = breadcrumb.getData("url");
347
- String url = urlObject instanceof String ? (String) urlObject : "";
348
- if ("http".equals(breadcrumb.getType())
349
- && ((dsn != null && url.startsWith(dsn))
350
- || (devServerUrl != null && url.startsWith(devServerUrl)))) {
351
- return null;
352
- }
353
- return breadcrumb;
354
- });
355
-
356
- // React native internally throws a JavascriptException.
357
- // we want to ignore it on the native side to avoid sending it twice.
358
- options.addIgnoredExceptionForType(JavascriptException.class);
359
-
360
- trySetIgnoreErrors(options, rnOptions);
361
-
362
- options.setBeforeSend(
363
- (event, hint) -> {
364
- setEventOriginTag(event);
365
- addPackages(event, options.getSdkVersion());
366
-
367
- return event;
368
- });
369
-
370
- if (rnOptions.hasKey("enableNativeCrashHandling")
371
- && !rnOptions.getBoolean("enableNativeCrashHandling")) {
372
- final List<Integration> integrations = options.getIntegrations();
373
- for (final Integration integration : integrations) {
374
- if (integration instanceof UncaughtExceptionHandlerIntegration
375
- || integration instanceof AnrIntegration
376
- || integration instanceof NdkIntegration) {
377
- integrations.remove(integration);
378
- }
379
- }
380
- }
381
- logger.log(
382
- SentryLevel.INFO, String.format("Native Integrations '%s'", options.getIntegrations()));
383
-
384
- final CurrentActivityHolder currentActivityHolder = CurrentActivityHolder.getInstance();
385
- final Activity currentActivity = getCurrentActivity();
386
- if (currentActivity != null) {
387
- currentActivityHolder.setActivity(currentActivity);
388
- }
389
- }
390
-
391
- private boolean isReplayEnabled(SentryReplayOptions replayOptions) {
392
- return replayOptions.getSessionSampleRate() != null
393
- || replayOptions.getOnErrorSampleRate() != null;
394
- }
395
-
396
- private SentryReplayOptions getReplayOptions(@NotNull ReadableMap rnOptions) {
397
- final SdkVersion replaySdkVersion =
398
- new SdkVersion(
399
- RNSentryVersion.REACT_NATIVE_SDK_NAME,
400
- RNSentryVersion.REACT_NATIVE_SDK_PACKAGE_VERSION);
401
- @NotNull
402
- final SentryReplayOptions androidReplayOptions =
403
- new SentryReplayOptions(false, replaySdkVersion);
404
-
405
- if (!(rnOptions.hasKey("replaysSessionSampleRate")
406
- || rnOptions.hasKey("replaysOnErrorSampleRate"))) {
407
- return androidReplayOptions;
408
- }
409
-
410
- androidReplayOptions.setSessionSampleRate(
411
- rnOptions.hasKey("replaysSessionSampleRate")
412
- ? rnOptions.getDouble("replaysSessionSampleRate")
413
- : null);
414
- androidReplayOptions.setOnErrorSampleRate(
415
- rnOptions.hasKey("replaysOnErrorSampleRate")
416
- ? rnOptions.getDouble("replaysOnErrorSampleRate")
417
- : null);
418
-
419
- if (rnOptions.hasKey("replaysSessionQuality")) {
420
- final String qualityString = rnOptions.getString("replaysSessionQuality");
421
- final SentryReplayQuality quality = parseReplayQuality(qualityString);
422
- androidReplayOptions.setQuality(quality);
423
- }
424
-
425
- if (!rnOptions.hasKey("mobileReplayOptions")) {
426
- return androidReplayOptions;
427
- }
428
- @Nullable final ReadableMap rnMobileReplayOptions = rnOptions.getMap("mobileReplayOptions");
429
- if (rnMobileReplayOptions == null) {
430
- return androidReplayOptions;
431
- }
432
-
433
- androidReplayOptions.setMaskAllText(
434
- !rnMobileReplayOptions.hasKey("maskAllText")
435
- || rnMobileReplayOptions.getBoolean("maskAllText"));
436
- androidReplayOptions.setMaskAllImages(
437
- !rnMobileReplayOptions.hasKey("maskAllImages")
438
- || rnMobileReplayOptions.getBoolean("maskAllImages"));
439
-
440
- final boolean redactVectors =
441
- !rnMobileReplayOptions.hasKey("maskAllVectors")
442
- || rnMobileReplayOptions.getBoolean("maskAllVectors");
443
- if (redactVectors) {
444
- androidReplayOptions.addMaskViewClass("com.horcrux.svg.SvgView"); // react-native-svg
445
- }
446
-
447
- if (rnMobileReplayOptions.hasKey("screenshotStrategy")) {
448
- final String screenshotStrategyString = rnMobileReplayOptions.getString("screenshotStrategy");
449
- final ScreenshotStrategyType screenshotStrategy =
450
- parseScreenshotStrategy(screenshotStrategyString);
451
- androidReplayOptions.setScreenshotStrategy(screenshotStrategy);
452
- }
453
-
454
- androidReplayOptions.setMaskViewContainerClass(RNSentryReplayMask.class.getName());
455
- androidReplayOptions.setUnmaskViewContainerClass(RNSentryReplayUnmask.class.getName());
456
-
457
- return androidReplayOptions;
458
- }
459
-
460
- private ScreenshotStrategyType parseScreenshotStrategy(@Nullable String strategyString) {
461
- if (strategyString == null) {
462
- return ScreenshotStrategyType.PIXEL_COPY;
463
- }
464
-
465
- switch (strategyString.toLowerCase(Locale.ROOT)) {
466
- case "canvas":
467
- return ScreenshotStrategyType.CANVAS;
468
- default:
469
- return ScreenshotStrategyType.PIXEL_COPY;
470
- }
471
- }
472
-
473
- private SentryReplayQuality parseReplayQuality(@Nullable String qualityString) {
474
- if (qualityString == null) {
475
- return SentryReplayQuality.MEDIUM;
476
- }
477
-
478
- switch (qualityString.toLowerCase(Locale.ROOT)) {
479
- case "low":
480
- return SentryReplayQuality.LOW;
481
- case "medium":
482
- return SentryReplayQuality.MEDIUM;
483
- case "high":
484
- return SentryReplayQuality.HIGH;
485
- default:
486
- return SentryReplayQuality.MEDIUM;
487
- }
488
- }
489
-
490
- private void configureAndroidProfiling(
491
- @NotNull SentryAndroidOptions options, @NotNull ReadableMap rnOptions) {
492
- if (!rnOptions.hasKey("_experiments")) {
493
- return;
494
- }
495
-
496
- @Nullable final ReadableMap experiments = rnOptions.getMap("_experiments");
497
- if (experiments == null || !experiments.hasKey("androidProfilingOptions")) {
498
- return;
499
- }
500
-
501
- @Nullable
502
- final ReadableMap androidProfilingOptions = experiments.getMap("androidProfilingOptions");
503
- if (androidProfilingOptions == null) {
504
- return;
505
- }
506
-
507
- // Set profile session sample rate
508
- if (androidProfilingOptions.hasKey("profileSessionSampleRate")) {
509
- final double profileSessionSampleRate =
510
- androidProfilingOptions.getDouble("profileSessionSampleRate");
511
- options.setProfileSessionSampleRate(profileSessionSampleRate);
512
- logger.log(
513
- SentryLevel.INFO,
514
- String.format(
515
- "Android UI Profiling profileSessionSampleRate set to: %.2f",
516
- profileSessionSampleRate));
517
- }
518
-
519
- // Set profiling lifecycle mode
520
- if (androidProfilingOptions.hasKey("lifecycle")) {
521
- final String lifecycle = androidProfilingOptions.getString("lifecycle");
522
- if ("manual".equalsIgnoreCase(lifecycle)) {
523
- options.setProfileLifecycle(ProfileLifecycle.MANUAL);
524
- logger.log(SentryLevel.INFO, "Android UI Profile Lifecycle set to MANUAL");
525
- } else if ("trace".equalsIgnoreCase(lifecycle)) {
526
- options.setProfileLifecycle(ProfileLifecycle.TRACE);
527
- logger.log(SentryLevel.INFO, "Android UI Profile Lifecycle set to TRACE");
528
- }
529
- }
530
-
531
- // Set start on app start
532
- if (androidProfilingOptions.hasKey("startOnAppStart")) {
533
- final boolean startOnAppStart = androidProfilingOptions.getBoolean("startOnAppStart");
534
- options.setStartProfilerOnAppStart(startOnAppStart);
535
- logger.log(
536
- SentryLevel.INFO,
537
- String.format("Android UI Profiling startOnAppStart set to %b", startOnAppStart));
538
- }
539
- }
540
-
541
190
  public void crash() {
542
191
  throw new RuntimeException("TEST - Sentry Client Crash (only works in release mode)");
543
192
  }
@@ -1276,51 +925,6 @@ public class RNSentryModuleImpl {
1276
925
  promise.resolve(Sentry.isCrashedLastRun());
1277
926
  }
1278
927
 
1279
- private void setEventOriginTag(SentryEvent event) {
1280
- // We hardcode native-java as only java events are processed by the Android SDK.
1281
- SdkVersion sdk = event.getSdk();
1282
- if (sdk != null) {
1283
- switch (sdk.getName()) {
1284
- case RNSentryVersion.NATIVE_SDK_NAME:
1285
- setEventEnvironmentTag(event, "native");
1286
- break;
1287
- case RNSentryVersion.ANDROID_SDK_NAME:
1288
- setEventEnvironmentTag(event, "java");
1289
- break;
1290
- default:
1291
- break;
1292
- }
1293
- }
1294
- }
1295
-
1296
- private void setEventEnvironmentTag(SentryEvent event, String environment) {
1297
- event.setTag("event.origin", "android");
1298
- event.setTag("event.environment", environment);
1299
- }
1300
-
1301
- private void addPackages(SentryEvent event, SdkVersion sdk) {
1302
- SdkVersion eventSdk = event.getSdk();
1303
- if (eventSdk != null
1304
- && "sentry.javascript.react-native".equals(eventSdk.getName())
1305
- && sdk != null) {
1306
- Set<SentryPackage> sentryPackages = sdk.getPackageSet();
1307
- if (sentryPackages != null) {
1308
- for (SentryPackage sentryPackage : sentryPackages) {
1309
- eventSdk.addPackage(sentryPackage.getName(), sentryPackage.getVersion());
1310
- }
1311
- }
1312
-
1313
- Set<String> integrations = sdk.getIntegrationSet();
1314
- if (integrations != null) {
1315
- for (String integration : integrations) {
1316
- eventSdk.addIntegration(integration);
1317
- }
1318
- }
1319
-
1320
- event.setSdk(eventSdk);
1321
- }
1322
- }
1323
-
1324
928
  private boolean checkAndroidXAvailability() {
1325
929
  try {
1326
930
  Class.forName("androidx.core.app.FrameMetricsAggregator");