@dynatrace/react-native-plugin 2.307.1 → 2.309.1

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 (130) hide show
  1. package/README.md +7 -3
  2. package/android/build.gradle +3 -1
  3. package/android/src/main/java/com/dynatrace/android/agent/DynatraceAppStartModule.kt +128 -0
  4. package/android/src/main/java/com/dynatrace/android/agent/DynatraceInternalModule.kt +22 -0
  5. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +411 -0
  6. package/android/src/main/java/com/dynatrace/android/agent/DynatraceReactPackage.kt +54 -0
  7. package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.kt +86 -0
  8. package/android/src/main/java/com/dynatrace/android/agent/model/AppStartMeasurement.kt +15 -0
  9. package/android/src/main/java/com/dynatrace/android/agent/model/AppStartMeasurementType.kt +18 -0
  10. package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +228 -0
  11. package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +258 -0
  12. package/files/plugin.gradle +1 -1
  13. package/index.js +10 -10
  14. package/instrumentation/DynatraceInstrumentation.js +1 -0
  15. package/{lib → instrumentation/jsx}/CreateElement.js +6 -5
  16. package/{lib/instrumentor/base → instrumentation/jsx}/ElementHelper.js +14 -12
  17. package/{lib/jsx-dev-runtime.js → instrumentation/jsx/JsxDevRuntime.js} +10 -19
  18. package/instrumentation/jsx/JsxRuntime.js +63 -0
  19. package/instrumentation/jsx/JsxRuntimeUtil.js +31 -0
  20. package/instrumentation/jsx/components/ClassComponent.js +49 -0
  21. package/instrumentation/jsx/components/ComponentUtil.js +33 -0
  22. package/instrumentation/jsx/components/FunctionalComponent.js +20 -0
  23. package/{lib/instrumentor/base → instrumentation/jsx/components}/Picker.js +1 -1
  24. package/{lib/instrumentor/base → instrumentation/jsx/components}/RefreshControl.js +1 -1
  25. package/{lib/instrumentor/base → instrumentation/jsx/components}/Switch.js +1 -1
  26. package/{lib/instrumentor/base → instrumentation/jsx/components}/Touchable.js +5 -5
  27. package/instrumentation/libs/community/Picker.InstrInfo.js +20 -0
  28. package/{lib → instrumentation/libs}/community/Picker.js +1 -1
  29. package/instrumentation/libs/community/gesture-handler/Touchables.InstrInfo.js +23 -0
  30. package/{lib → instrumentation/libs}/community/gesture-handler/Touchables.js +1 -1
  31. package/{lib → instrumentation/libs}/react-native/RefreshControl.InstrInfo.js +2 -2
  32. package/{lib → instrumentation/libs}/react-native/RefreshControl.js +5 -5
  33. package/{lib → instrumentation/libs}/react-native/Switch.InstrInfo.js +2 -2
  34. package/{lib → instrumentation/libs}/react-native/Switch.js +5 -5
  35. package/instrumentation/libs/react-native/Touchables.InstrInfo.js +25 -0
  36. package/{lib → instrumentation/libs}/react-native/Touchables.js +1 -1
  37. package/{lib → instrumentation/libs}/react-navigation/ReactNavigation.js +6 -5
  38. package/{lib/instrumentor → instrumentation}/model/Types.js +1 -14
  39. package/instrumentation/model/TypesUtil.js +17 -0
  40. package/ios/DynatraceRNBridge.h +10 -1
  41. package/ios/DynatraceRNBridge.mm +152 -0
  42. package/jsx-dev-runtime.js +1 -1
  43. package/jsx-runtime.js +1 -1
  44. package/lib/core/Application.js +20 -0
  45. package/lib/{instrumentor/base → core}/Dynatrace.js +57 -48
  46. package/lib/{instrumentor/base → core}/DynatraceAction.js +23 -22
  47. package/lib/core/DynatraceInternal.js +46 -0
  48. package/lib/{instrumentor/base → core}/DynatraceRootAction.js +5 -4
  49. package/lib/{instrumentor/base → core}/DynatraceWebRequestTiming.js +6 -5
  50. package/lib/{instrumentor/base → core}/ErrorHandler.js +6 -5
  51. package/lib/{instrumentor/base → core}/configuration/Configuration.js +1 -1
  52. package/lib/{instrumentor/base → core}/configuration/ConfigurationDefaults.js +1 -2
  53. package/lib/{instrumentor/base → core}/configuration/ConfigurationHandler.js +2 -2
  54. package/lib/{instrumentor/base → core}/configuration/ManualStartupConfiguration.js +1 -1
  55. package/lib/core/logging/ConsoleLogger.js +27 -0
  56. package/lib/core/logging/LogLevel.js +12 -0
  57. package/lib/dynatrace-transformer.js +1 -1
  58. package/lib/next/Dynatrace.js +86 -0
  59. package/lib/next/DynatraceSecondGenForwarder.js +17 -0
  60. package/lib/next/IDynatrace.js +2 -0
  61. package/lib/next/IDynatraceForwarder.js +2 -0
  62. package/lib/next/appstart/AppStartObserver.js +32 -0
  63. package/lib/next/appstart/AppStartType.js +38 -0
  64. package/lib/next/events/EventCreator.js +77 -0
  65. package/lib/next/events/EventPipeline.js +57 -0
  66. package/lib/next/events/EventTimestamp.js +24 -0
  67. package/lib/next/events/ViewInfoCreator.js +27 -0
  68. package/lib/next/events/modifier/BaseDataEventModifier.js +31 -0
  69. package/lib/next/events/modifier/EventLimitation.js +69 -0
  70. package/lib/next/events/modifier/EventModifierUtil.js +88 -0
  71. package/lib/next/events/modifier/IEventModifier.js +2 -0
  72. package/lib/next/events/modifier/ModifyEventValidation.js +187 -0
  73. package/lib/next/events/modifier/NonFiniteNumbersModifier.js +50 -0
  74. package/lib/next/events/modifier/SendEventValidation.js +84 -0
  75. package/lib/next/events/spec/EventFieldKeysEnum.js +2 -0
  76. package/lib/next/events/spec/EventSpecContstants.js +46 -0
  77. package/lib/next/events/spec/IAppStartEvent.js +2 -0
  78. package/lib/next/events/spec/ICrashEvent.js +2 -0
  79. package/lib/next/events/spec/IErrorCodeEvent.js +2 -0
  80. package/lib/next/events/spec/IErrorExceptionEvent.js +2 -0
  81. package/lib/next/events/spec/IReactNativeEvent.js +2 -0
  82. package/lib/next/events/spec/IRumEvent.js +2 -0
  83. package/lib/next/provider/ITimestampProvider.js +2 -0
  84. package/lib/next/provider/TimestampProvider.js +10 -0
  85. package/package.json +41 -33
  86. package/react-native-dynatrace.podspec +1 -1
  87. package/src/lib/{instrumentor/base → core}/interface/NativeDynatraceBridge.ts +8 -0
  88. package/typings/react-native-dynatrace.d.ts +0 -1
  89. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.java +0 -366
  90. package/android/src/main/java/com/dynatrace/android/agent/DynatraceReactPackage.java +0 -67
  91. package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.java +0 -108
  92. package/android/src/main/java/com/dynatrace/android/agent/PrivateDTBridge.java +0 -28
  93. package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.java +0 -192
  94. package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.java +0 -194
  95. package/lib/community/Picker.InstrInfo.js +0 -20
  96. package/lib/community/gesture-handler/Touchables.InstrInfo.js +0 -56
  97. package/lib/instrumentor/DynatraceInstrumentation.js +0 -1
  98. package/lib/instrumentor/base/Application.js +0 -16
  99. package/lib/instrumentor/base/DynatraceInternal.js +0 -34
  100. package/lib/instrumentor/base/Logger.js +0 -16
  101. package/lib/instrumentor/base/model/LogLevel.js +0 -17
  102. package/lib/jsx-runtime.js +0 -69
  103. package/lib/react/Component.js +0 -90
  104. package/lib/react-native/Touchables.InstrInfo.js +0 -60
  105. /package/{lib/instrumentor/base/interface → instrumentation/jsx}/IDynatraceProperties.js +0 -0
  106. /package/{lib → instrumentation/libs}/community/gesture-handler/index.js +0 -0
  107. /package/{lib → instrumentation/libs}/gesture-handler.js +0 -0
  108. /package/{lib → instrumentation/libs}/react-native/index.js +0 -0
  109. /package/{lib → instrumentation/libs}/react-native.js +0 -0
  110. /package/{lib/instrumentor → instrumentation}/model/Reference.js +0 -0
  111. /package/{lib/instrumentor → instrumentation}/parser/Babel.js +0 -0
  112. /package/lib/{instrumentor/base → core}/DynatraceBridge.js +0 -0
  113. /package/lib/{instrumentor/base → core}/NullAction.js +0 -0
  114. /package/lib/{instrumentor/base → core}/NullRootAction.js +0 -0
  115. /package/lib/{instrumentor/base → core}/NullWebRequestTiming.js +0 -0
  116. /package/lib/{instrumentor/base → core}/UserPrivacyOptions.js +0 -0
  117. /package/lib/{instrumentor/base → core}/configuration/ConfigurationBuilder.js +0 -0
  118. /package/lib/{instrumentor/base → core}/configuration/ConfigurationPreset.js +0 -0
  119. /package/lib/{instrumentor/base → core}/configuration/IConfiguration.js +0 -0
  120. /package/lib/{instrumentor/base → core}/interface/IDynatrace.js +0 -0
  121. /package/lib/{instrumentor/base → core}/interface/IDynatraceAction.js +0 -0
  122. /package/lib/{instrumentor/base → core}/interface/IDynatraceInternal.js +0 -0
  123. /package/lib/{instrumentor/base → core}/interface/IDynatraceRootAction.js +0 -0
  124. /package/lib/{instrumentor/base → core}/interface/IWebRequestTiming.js +0 -0
  125. /package/lib/{instrumentor/base → core}/interface/NativeDynatraceBridge.js +0 -0
  126. /package/lib/{instrumentor/base/interface → core/logging}/ILogger.js +0 -0
  127. /package/lib/{instrumentor/base → core}/model/DataCollectionLevel.js +0 -0
  128. /package/lib/{instrumentor/base → core}/model/Json.js +0 -0
  129. /package/lib/{instrumentor/base → core}/model/Platform.js +0 -0
  130. /package/lib/{instrumentor/base → core}/util/StringUtils.js +0 -0
package/README.md CHANGED
@@ -32,8 +32,8 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
32
32
  ## Agent Versions
33
33
  This agent versions are configured in this plugin:
34
34
 
35
- * Android Agent: 8.307.1.1005
36
- * iOS Agent: 8.307.1.1014
35
+ * Android Agent: 8.309.2.1011
36
+ * iOS Agent: 8.309.1.1009
37
37
 
38
38
  ## Quick Setup
39
39
 
@@ -402,7 +402,7 @@ let url = 'https://www.dynatrace.com';
402
402
  // You can also use enterAutoAction if desired
403
403
  let action = Dynatrace.enterManualAction("Manual Web Request");
404
404
  let tag = await action.getRequestTag(url);
405
- let timing = new DynatraceWebRequestTiming(url, tag);
405
+ let timing = new DynatraceWebRequestTiming(tag, url);
406
406
 
407
407
  try {
408
408
  timing.startWebRequestTiming();
@@ -1463,6 +1463,10 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
1463
1463
  <br/><br/>
1464
1464
  ## Changelog
1465
1465
 
1466
+ 2.309.1
1467
+ * Updated Android (8.309.2.1011) & iOS Agent (8.309.1.1009)
1468
+ * Fixed issue with metro when internal require was not resolved correctly
1469
+
1466
1470
  2.307.1
1467
1471
  * Updated Android (8.307.1.1005) & iOS Agent (8.307.1.1014)
1468
1472
  * Now require the use of NodeJS 18+
@@ -16,10 +16,12 @@ buildscript {
16
16
 
17
17
  dependencies {
18
18
  classpath 'com.android.tools.build:gradle:7.3.1'
19
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10"
19
20
  }
20
21
  }
21
22
 
22
23
  apply plugin: 'com.android.library'
24
+ apply plugin: 'org.jetbrains.kotlin.android'
23
25
 
24
26
  if (isNewArchitectureEnabled()) {
25
27
  apply plugin: 'com.facebook.react'
@@ -70,7 +72,7 @@ repositories {
70
72
  }
71
73
 
72
74
  dependencies {
73
- implementation 'com.dynatrace.agent:agent-android:8.307.1.1005'
75
+ implementation 'com.dynatrace.agent:agent-android:8.309.2.1011'
74
76
  implementation "com.facebook.react:react-native:${safeExtGet('reactNative', '+')}"
75
77
  }
76
78
 
@@ -0,0 +1,128 @@
1
+ package com.dynatrace.android.agent
2
+
3
+ import android.os.SystemClock
4
+ import com.dynatrace.android.agent.model.AppStartMeasurement
5
+ import com.dynatrace.android.agent.model.AppStartMeasurementType
6
+ import com.facebook.react.bridge.Arguments
7
+ import com.facebook.react.bridge.ReactApplicationContext
8
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
9
+ import com.facebook.react.bridge.ReactMarker
10
+ import com.facebook.react.bridge.ReactMarkerConstants
11
+ import com.facebook.react.modules.core.DeviceEventManagerModule
12
+ import java.util.Queue
13
+ import java.util.concurrent.ConcurrentLinkedQueue
14
+
15
+ /**
16
+ * Name of the module
17
+ */
18
+ private const val APP_START_MODULE = "DynatraceAppStartModule"
19
+
20
+ /**
21
+ * Emitting app start event with this identifier
22
+ */
23
+ private const val EMIT_APP_START = "dynatraceAppStartMeasurements"
24
+
25
+ /**
26
+ * Queue which contains all our measured app start timestamps
27
+ */
28
+ private val buffer: Queue<AppStartMeasurement> = ConcurrentLinkedQueue()
29
+
30
+ /**
31
+ * Setup to register all time points which we want to use to report correct app startup time.
32
+ */
33
+ fun setupAppStartListener() {
34
+ ReactMarker.addListener { name: ReactMarkerConstants?, _: String?, _: Int ->
35
+ when (name) {
36
+ ReactMarkerConstants.RELOAD -> {
37
+ buffer.clear()
38
+ buffer.add(
39
+ AppStartMeasurement(
40
+ AppStartMeasurementType.RELOAD.value,
41
+ SystemClock.uptimeMillis()
42
+ )
43
+ )
44
+ }
45
+
46
+ ReactMarkerConstants.CONTENT_APPEARED -> buffer.add(
47
+ AppStartMeasurement(
48
+ AppStartMeasurementType.CONTENT_APPEARED.value,
49
+ SystemClock.uptimeMillis()
50
+ )
51
+ )
52
+
53
+ ReactMarkerConstants.DOWNLOAD_END -> buffer.add(
54
+ AppStartMeasurement(
55
+ AppStartMeasurementType.DOWNLOAD_END.value,
56
+ SystemClock.uptimeMillis()
57
+ )
58
+ )
59
+
60
+ ReactMarkerConstants.DOWNLOAD_START -> buffer.add(
61
+ AppStartMeasurement(
62
+ AppStartMeasurementType.DOWNLOAD_START.value,
63
+ SystemClock.uptimeMillis()
64
+ )
65
+ )
66
+
67
+ ReactMarkerConstants.RUN_JS_BUNDLE_END -> buffer.add(
68
+ AppStartMeasurement(
69
+ AppStartMeasurementType.RUN_JS_BUNDLE_END.value,
70
+ SystemClock.uptimeMillis()
71
+ )
72
+ )
73
+
74
+ ReactMarkerConstants.RUN_JS_BUNDLE_START -> buffer.add(
75
+ AppStartMeasurement(
76
+ AppStartMeasurementType.RUN_JS_BUNDLE_START.value,
77
+ SystemClock.uptimeMillis()
78
+ )
79
+ )
80
+
81
+ else -> {
82
+ // Not important
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Module which is handling the app start measurements
90
+ */
91
+ internal class DynatraceAppStartModule(reactContext: ReactApplicationContext?) :
92
+ ReactContextBaseJavaModule(reactContext) {
93
+ init {
94
+ setupInternalListener()
95
+ }
96
+
97
+ /**
98
+ * We setup the listener internally as we
99
+ */
100
+ private fun setupInternalListener() {
101
+ ReactMarker.addListener { name: ReactMarkerConstants, _: String?, _: Int ->
102
+ if (name == ReactMarkerConstants.CONTENT_APPEARED) {
103
+ // When content appeared we will emit the event with all the information
104
+ flushMeasurements()
105
+ }
106
+ }
107
+ }
108
+
109
+ /**
110
+ * We flush all events when content appeared is triggered, as it marks the last event
111
+ */
112
+ private fun flushMeasurements() {
113
+ val params = Arguments.createMap()
114
+ val iterator: Iterator<AppStartMeasurement> = buffer.iterator()
115
+ while (iterator.hasNext()) {
116
+ val entry = iterator.next()
117
+ params.putDouble(entry.name, entry.timestamp.toDouble())
118
+ }
119
+
120
+ reactApplicationContext
121
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
122
+ .emit(EMIT_APP_START, params)
123
+ }
124
+
125
+ override fun getName(): String {
126
+ return APP_START_MODULE
127
+ }
128
+ }
@@ -0,0 +1,22 @@
1
+ package com.dynatrace.android.agent
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
5
+ import com.facebook.react.bridge.ReactMethod
6
+
7
+ class DynatraceInternalModule(reactContext: ReactApplicationContext?) :
8
+ ReactContextBaseJavaModule(reactContext) {
9
+ override fun getName(): String {
10
+ return "DynatraceInternalModule"
11
+ }
12
+
13
+ /**
14
+ * Helper method which should not be called.
15
+ * @param name Action name
16
+ * @return Action
17
+ */
18
+ @ReactMethod
19
+ fun enterAction(name: String?): DTXAction {
20
+ return Dynatrace.integrateNewAction(name)
21
+ }
22
+ }
@@ -0,0 +1,411 @@
1
+ package com.dynatrace.android.agent
2
+
3
+ import android.location.Location
4
+ import com.dynatrace.android.agent.conf.DataCollectionLevel
5
+ import com.dynatrace.android.agent.conf.DynatraceConfigurationBuilder
6
+ import com.dynatrace.android.agent.conf.UserPrivacyOptions
7
+ import com.dynatrace.android.agent.crash.PlatformType
8
+ import com.facebook.react.bridge.Arguments
9
+ import com.facebook.react.bridge.Promise
10
+ import com.facebook.react.bridge.ReactApplicationContext
11
+ import com.facebook.react.bridge.ReadableMap
12
+ import org.json.JSONObject
13
+ import java.net.URI
14
+ import java.net.URISyntaxException
15
+
16
+ private const val PLATFORM_ANDROID = "android"
17
+ private const val PLATFORM_IOS = "ios"
18
+ private const val DATA_COLLECTION_OFF = "OFF"
19
+ private const val DATA_COLLECTION_PERFORMANCE = "PERFORMANCE"
20
+ private const val DATA_COLLECTION_USERBEHAVIOR = "USER_BEHAVIOR"
21
+ const val BRIDGE_NAME = "DynatraceBridge"
22
+
23
+ class DynatraceRNBridgeImpl(
24
+ private val reactApplicationContext: ReactApplicationContext,
25
+ private val _internal: DynatraceInternalModule
26
+ ) {
27
+ private val webTimings: HashMap<String, WebRequestTiming> = HashMap()
28
+ private val actions: HashMap<String, DTXAction?> = HashMap()
29
+
30
+ private val constants = mapOf(
31
+ "PLATFORM_ANDROID" to PLATFORM_ANDROID,
32
+ "PLATFORM_IOS" to PLATFORM_IOS,
33
+ "DATA_COLLECTION_OFF" to DATA_COLLECTION_OFF,
34
+ "DATA_COLLECTION_PERFORMANCE" to DATA_COLLECTION_PERFORMANCE,
35
+ "DATA_COLLECTION_USERBEHAVIOR" to DATA_COLLECTION_USERBEHAVIOR
36
+ )
37
+
38
+ fun getConstants(): Map<String, Any> {
39
+ return constants;
40
+ }
41
+
42
+ fun start(configuration: ReadableMap?, promise: Promise) {
43
+ if (configuration == null) {
44
+ promise.resolve(false)
45
+ return
46
+ } else {
47
+ if (configuration.getString("applicationId") == null || configuration.getString("beaconUrl") == null) {
48
+ promise.resolve(false)
49
+ return
50
+ }
51
+
52
+ val builder = DynatraceConfigurationBuilder(
53
+ configuration.getString("applicationId"),
54
+ configuration.getString("beaconUrl")
55
+ )
56
+
57
+ builder.apply {
58
+ withUserOptIn(configuration.getBoolean("userOptIn"))
59
+ withCrashReporting(configuration.getBoolean("reportCrash"))
60
+ // 0 == Debug / 1 == Info
61
+ withDebugLogging(configuration.getInt("logLevel") == 0)
62
+ }
63
+
64
+ Dynatrace.startup(reactApplicationContext, builder.buildConfiguration())
65
+ promise.resolve(true)
66
+ }
67
+ }
68
+
69
+ //
70
+ // Expects a key which is generated in JS. This is to circumvent the async callback system.
71
+ //
72
+ fun enterAction(name: String, key: String, platform: String?) {
73
+ if (shouldWorkOnAndroid(platform)) {
74
+ newAction(name, key)
75
+ }
76
+ }
77
+
78
+ fun enterManualAction(name: String, key: String, platform: String?) {
79
+ if (shouldWorkOnAndroid(platform)) {
80
+ actions[key] = Dynatrace.enterAction(name)
81
+ }
82
+ }
83
+
84
+ fun enterManualActionWithParent(
85
+ name: String,
86
+ key: String,
87
+ parentKey: String,
88
+ platform: String?
89
+ ) {
90
+ if (shouldWorkOnAndroid(platform)) {
91
+ val parent = actions[parentKey]
92
+ if (parent != null) {
93
+ actions[key] = Dynatrace.enterAction(name, parent)
94
+ } else {
95
+ enterManualAction(name, key, platform)
96
+ }
97
+ }
98
+ }
99
+
100
+ fun leaveAction(key: String, @Suppress("UNUSED_PARAMETER") leave: Boolean, platform: String?) {
101
+ if (shouldWorkOnAndroid(platform)) {
102
+ val action = getAction(key) ?: return
103
+ if (action is DTXAutoAction) {
104
+ action.startTimer()
105
+ } else {
106
+ action.leaveAction()
107
+ }
108
+ actions.remove(key)
109
+ }
110
+ }
111
+
112
+ fun cancelAction(key: String, platform: String?) {
113
+ if (shouldWorkOnAndroid(platform)) {
114
+ val action = getAction(key) ?: return
115
+ action.cancel()
116
+ actions.remove(key)
117
+ }
118
+ }
119
+
120
+ fun endVisit(platform: String?) {
121
+ if (shouldWorkOnAndroid(platform)) {
122
+ Dynatrace.endVisit()
123
+ }
124
+ }
125
+
126
+ fun reportErrorWithoutStacktrace(errorName: String, errorCode: Int, platform: String?) {
127
+ if (shouldWorkOnAndroid(platform)) {
128
+ Dynatrace.internalReportError(errorName, errorCode)
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Reports a stacktrace
134
+ * @param errorName Name of the Error - SyntaxError
135
+ * @param errorValue Value of the Error
136
+ * @param reason Reason for the Error
137
+ * @param stacktrace Whole Stacktrace
138
+ * @param platform Platform wise or both
139
+ */
140
+ fun reportError(
141
+ errorName: String,
142
+ errorValue: String,
143
+ reason: String,
144
+ stacktrace: String,
145
+ platform: String?
146
+ ) {
147
+ if (shouldWorkOnAndroid(platform)) {
148
+ Dynatrace.reportError(PlatformType.CUSTOM, errorName, errorValue, reason, stacktrace)
149
+ }
150
+ }
151
+
152
+ fun reportCrash(
153
+ errorName: String,
154
+ reason: String,
155
+ stacktrace: String,
156
+ isRealError: Boolean,
157
+ platform: String?
158
+ ) {
159
+ if (shouldWorkOnAndroid(platform)) {
160
+ Dynatrace.reportCrash(
161
+ if (isRealError) PlatformType.JAVA_SCRIPT else PlatformType.CUSTOM,
162
+ errorName,
163
+ reason,
164
+ stacktrace
165
+ )
166
+ // Generate new session like iOS to make sure the behavior is the same
167
+ Dynatrace.createNewSession()
168
+ }
169
+ }
170
+
171
+ fun reportErrorInAction(key: String, errorName: String, errorCode: Int, platform: String?) {
172
+ if (shouldWorkOnAndroid(platform)) {
173
+ val action = getAction(key) ?: return
174
+ action.reportError(errorName, errorCode)
175
+ }
176
+ }
177
+
178
+ fun reportValue(key: String, valueName: String, value: String, platform: String?) {
179
+ if (shouldWorkOnAndroid(platform)) {
180
+ val action = getAction(key) ?: return
181
+ action.reportValue(valueName, value)
182
+ }
183
+ }
184
+
185
+ fun getRequestTag(key: String, @Suppress("UNUSED_PARAMETER") url: String, promise: Promise) {
186
+ val action = getAction(key)
187
+ if (action == null) {
188
+ promise.resolve(Dynatrace.getRequestTag())
189
+ return
190
+ }
191
+ promise.resolve(action.requestTag)
192
+ }
193
+
194
+ fun startWebRequestTiming(requestTag: String?, @Suppress("UNUSED_PARAMETER") url: String) {
195
+ if (requestTag != null) {
196
+ val timing = Dynatrace.getWebRequestTiming(requestTag)
197
+ if (timing != null) {
198
+ webTimings[requestTag] = timing
199
+ timing.startWebRequestTiming()
200
+ }
201
+ }
202
+ }
203
+
204
+ fun stopWebRequestTiming(
205
+ requestTag: String?,
206
+ url: String,
207
+ responseCode: Int,
208
+ responseMessage: String
209
+ ) {
210
+ stopWebRequestTimingWithSize(requestTag, url, responseCode, responseMessage, -1, -1)
211
+ }
212
+
213
+ fun stopWebRequestTimingWithSize(
214
+ requestTag: String?,
215
+ url: String,
216
+ responseCode: Int,
217
+ responseMessage: String,
218
+ requestSize: Long,
219
+ responseSize: Long
220
+ ) {
221
+ if (requestTag != null) {
222
+ val timing = webTimings[requestTag]
223
+ if (timing != null) {
224
+ try {
225
+ timing.stopWebRequestTiming(
226
+ URI(url),
227
+ responseCode,
228
+ responseMessage,
229
+ requestSize,
230
+ responseSize
231
+ )
232
+ webTimings.remove(requestTag)
233
+ } catch (ex: URISyntaxException) {
234
+ // do nothing
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ fun identifyUser(user: String, platform: String?) {
241
+ if (shouldWorkOnAndroid(platform)) {
242
+ Dynatrace.identifyUser(user)
243
+ }
244
+ }
245
+
246
+ fun reportEventInAction(actionKey: String, name: String, platform: String?) {
247
+ if (shouldWorkOnAndroid(platform)) {
248
+ val action = getAction(actionKey) ?: return
249
+ action.reportEvent(name)
250
+ }
251
+ }
252
+
253
+ fun reportStringValueInAction(
254
+ actionKey: String,
255
+ name: String,
256
+ value: String,
257
+ platform: String?
258
+ ) {
259
+ if (shouldWorkOnAndroid(platform)) {
260
+ val action = getAction(actionKey) ?: return
261
+ action.reportValue(name, value)
262
+ }
263
+ }
264
+
265
+ fun reportIntValueInAction(actionKey: String, name: String, value: Int, platform: String?) {
266
+ if (shouldWorkOnAndroid(platform)) {
267
+ val action = getAction(actionKey) ?: return
268
+ action.reportValue(name, value)
269
+ }
270
+ }
271
+
272
+ fun reportDoubleValueInAction(
273
+ actionKey: String,
274
+ name: String,
275
+ value: Double,
276
+ platform: String?
277
+ ) {
278
+ if (shouldWorkOnAndroid(platform)) {
279
+ val action = getAction(actionKey) ?: return
280
+ action.reportValue(name, value)
281
+ }
282
+ }
283
+
284
+ fun sendBizEvent(type: String, attributes: ReadableMap, platform: String?) {
285
+ if (shouldWorkOnAndroid(platform)) {
286
+ Dynatrace.sendBizEvent(type, JSONObject(DynatraceUtils.toHashMap(attributes)))
287
+ }
288
+ }
289
+
290
+ fun forwardEvent(attributes: ReadableMap) {
291
+ HybridBridge.forwardEvent(JSONObject(DynatraceUtils.toHashMap(attributes)))
292
+ }
293
+
294
+ fun startView(name: String) {
295
+ Dynatrace.startView(name)
296
+ }
297
+
298
+ fun stopView() {
299
+ Dynatrace.stopView()
300
+ }
301
+
302
+ fun setGPSLocation(lat: Double, lng: Double, platform: String?) {
303
+ if (shouldWorkOnAndroid(platform)) {
304
+ val location = Location("")
305
+
306
+ location.apply {
307
+ latitude = lat
308
+ longitude = lng
309
+ }
310
+
311
+ Dynatrace.setGpsLocation(location)
312
+ }
313
+ }
314
+
315
+ fun flushEvents(platform: String?) {
316
+ if (shouldWorkOnAndroid(platform)) {
317
+ Dynatrace.flushEvents()
318
+ }
319
+ }
320
+
321
+ fun isCrashReportingOptedIn(platform: String?, promise: Promise) {
322
+ if (shouldWorkOnAndroid(platform)) {
323
+ promise.resolve(Dynatrace.isCrashReportingOptedIn())
324
+ }
325
+ }
326
+
327
+ fun setCrashReportingOptedIn(crashReporting: Boolean, platform: String?) {
328
+ if (shouldWorkOnAndroid(platform)) {
329
+ Dynatrace.setCrashReportingOptedIn(crashReporting)
330
+ }
331
+ }
332
+
333
+ fun setDataCollectionLevel(collectionLevel: String, platform: String?) {
334
+ if (shouldWorkOnAndroid(platform)) {
335
+ Dynatrace.setDataCollectionLevel(DataCollectionLevel.valueOf(collectionLevel))
336
+ }
337
+ }
338
+
339
+ fun getDataCollectionLevel(platform: String?, promise: Promise) {
340
+ if (shouldWorkOnAndroid(platform)) {
341
+ val level = Dynatrace.getDataCollectionLevel()
342
+ promise.resolve(level.name)
343
+ }
344
+ }
345
+
346
+ fun setBeaconHeaders(headers: ReadableMap?, platform: String?) {
347
+ if (shouldWorkOnAndroid(platform)) {
348
+ if (headers == null) {
349
+ Dynatrace.setBeaconHeaders(null)
350
+ } else {
351
+ val beaconHeaders = mutableMapOf<String, String?>()
352
+ val iterator = headers.keySetIterator()
353
+ while (iterator.hasNextKey()) {
354
+ val currentKey = iterator.nextKey()
355
+ beaconHeaders[currentKey] = headers.getString(currentKey)
356
+ }
357
+ Dynatrace.setBeaconHeaders(beaconHeaders)
358
+ }
359
+ }
360
+ }
361
+
362
+ fun applyUserPrivacyOptions(userPrivacyOptions: ReadableMap, platform: String?) {
363
+ if (shouldWorkOnAndroid(platform)) {
364
+ val optionsBuilder = UserPrivacyOptions.builder()
365
+ optionsBuilder.withCrashReportingOptedIn(userPrivacyOptions.getBoolean("_crashReportingOptedIn"))
366
+ optionsBuilder.withDataCollectionLevel(
367
+ DataCollectionLevel.valueOf(
368
+ userPrivacyOptions.getString(
369
+ "_dataCollectionLevel"
370
+ )!!
371
+ )
372
+ )
373
+ Dynatrace.applyUserPrivacyOptions(
374
+ optionsBuilder
375
+ .build()
376
+ )
377
+ }
378
+ }
379
+
380
+ fun getUserPrivacyOptions(platform: String?, promise: Promise) {
381
+ if (shouldWorkOnAndroid(platform)) {
382
+ val options = Dynatrace.getUserPrivacyOptions()
383
+ val privacyMap = Arguments.createMap()
384
+ privacyMap.putString("dataCollectionLevel", options.dataCollectionLevel.name)
385
+ privacyMap.putBoolean("crashReportingOptedIn", options.isCrashReportingOptedIn)
386
+ promise.resolve(privacyMap)
387
+ }
388
+ }
389
+
390
+ @Suppress("UNUSED_PARAMETER")
391
+ fun addListener(eventName: String) {
392
+ // Here because of event emitter
393
+ }
394
+
395
+ @Suppress("UNUSED_PARAMETER")
396
+ fun removeListeners(count: Double) {
397
+ // Here because of event emitter
398
+ }
399
+
400
+ private fun newAction(name: String, key: String) {
401
+ actions[key] = _internal.enterAction(name)
402
+ }
403
+
404
+ private fun getAction(key: String): DTXAction? {
405
+ return actions[key]
406
+ }
407
+
408
+ private fun shouldWorkOnAndroid(platform: String?): Boolean {
409
+ return platform == null || platform == PLATFORM_ANDROID || platform == ""
410
+ }
411
+ }
@@ -0,0 +1,54 @@
1
+ package com.dynatrace.android.agent
2
+
3
+ import com.facebook.react.ReactPackage
4
+ import com.facebook.react.TurboReactPackage
5
+ import com.facebook.react.bridge.NativeModule
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.module.model.ReactModuleInfo
8
+ import com.facebook.react.module.model.ReactModuleInfoProvider
9
+ import com.facebook.react.uimanager.ViewManager
10
+ import java.util.Arrays
11
+
12
+ class DynatraceReactPackage : TurboReactPackage() {
13
+ init {
14
+ setupAppStartListener()
15
+ }
16
+
17
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
18
+ return emptyList()
19
+ }
20
+
21
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
22
+ val bridge = DynatraceInternalModule(reactContext)
23
+ val appStart = DynatraceAppStartModule(reactContext)
24
+ return Arrays.asList<NativeModule>(
25
+ DynatraceRNBridge(reactContext, bridge),
26
+ bridge,
27
+ appStart
28
+ )
29
+ }
30
+
31
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
32
+ val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
33
+ val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
34
+ moduleInfos[BRIDGE_NAME] = ReactModuleInfo(
35
+ BRIDGE_NAME,
36
+ BRIDGE_NAME,
37
+ false, // canOverrideExistingModule
38
+ false, // needsEagerInit
39
+ true, // hasConstants
40
+ false, // isCxxModule
41
+ isTurboModule // isTurboModule
42
+ )
43
+ return ReactModuleInfoProvider { moduleInfos }
44
+ }
45
+
46
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
47
+ return if (name == BRIDGE_NAME) {
48
+ DynatraceAppStartModule(reactContext)
49
+ DynatraceRNBridge(reactContext, DynatraceInternalModule(reactContext))
50
+ } else {
51
+ null
52
+ }
53
+ }
54
+ }