From 2acb7f8a117d8722aee285d63a2b9404428e6636 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Fri, 22 Sep 2023 14:17:09 -0700 Subject: [PATCH] Remove module and depend on upstream. (#640) * remove module and depend on upstream * update upstream to 0.1.0 and fix test breakages * spotless * Update sample-app/build.gradle.kts Co-authored-by: Mateusz Rzeszutek * remove --------- Co-authored-by: Mateusz Rzeszutek --- .../build.gradle.kts | 85 ----- .../src/main/AndroidManifest.xml | 8 - .../rum/internal/AndroidResource.java | 81 ---- .../rum/internal/ApplicationStateWatcher.java | 55 --- .../DefaultingActivityLifecycleCallbacks.java | 55 --- .../GlobalAttributesSpanAppender.java | 96 ----- .../internal/InstrumentedApplicationImpl.java | 53 --- .../rum/internal/NoopOpenTelemetryRum.java | 35 -- .../rum/internal/OpenTelemetryRum.java | 81 ---- .../rum/internal/OpenTelemetryRumBuilder.java | 214 ----------- .../rum/internal/OpenTelemetryRumImpl.java | 41 -- .../rum/internal/RumConstants.java | 49 --- .../rum/internal/RuntimeDetailsExtractor.java | 94 ----- .../internal/SdkPreconfiguredRumBuilder.java | 85 ----- .../opentelemetry/rum/internal/SessionId.java | 103 ----- .../rum/internal/SessionIdChangeListener.java | 23 -- .../rum/internal/SessionIdChangeTracer.java | 36 -- .../internal/SessionIdRatioBasedSampler.java | 63 --- .../rum/internal/SessionIdSpanAppender.java | 49 --- .../rum/internal/SessionIdTimeoutHandler.java | 88 ----- .../AttributeModifyingSpanExporter.java | 92 ----- .../export/FilteringSpanExporter.java | 59 --- .../export/FilteringSpanExporterBuilder.java | 106 ------ .../rum/internal/export/ModifiedSpanData.java | 41 -- .../rum/internal/export/SpanDataModifier.java | 153 -------- .../ApplicationStateListener.java | 35 -- .../InstrumentedApplication.java | 49 --- .../instrumentation/RumScreenName.java | 33 -- .../instrumentation/ScreenNameExtractor.java | 45 --- .../activity/ActivityCallbacks.java | 126 ------ .../activity/ActivityTracer.java | 219 ----------- .../activity/ActivityTracerCache.java | 101 ----- .../activity/Pre29ActivityCallbacks.java | 70 ---- .../Pre29VisibleScreenLifecycleBinding.java | 45 --- .../RumFragmentActivityRegisterer.java | 68 ---- .../VisibleScreenLifecycleBinding.java | 44 --- .../activity/VisibleScreenTracker.java | 98 ----- .../instrumentation/anr/AnrDetector.java | 85 ----- .../anr/AnrDetectorBuilder.java | 59 --- .../anr/AnrDetectorToggler.java | 51 --- .../instrumentation/anr/AnrWatcher.java | 70 ---- .../anr/StackTraceFormatter.java | 43 --- .../instrumentation/crash/CrashDetails.java | 66 ---- .../CrashDetailsAttributesExtractor.java | 41 -- .../instrumentation/crash/CrashReporter.java | 64 ---- .../crash/CrashReporterBuilder.java | 43 --- .../crash/CrashReportingExceptionHandler.java | 60 --- .../fragment/FragmentTracer.java | 124 ------ .../RumFragmentLifecycleCallbacks.java | 174 --------- .../AndroidLifecycleInstrumentation.java | 130 ------- ...ndroidLifecycleInstrumentationBuilder.java | 65 ---- .../instrumentation/network/Carrier.java | 143 ------- .../network/CarrierFinder.java | 56 --- .../network/CurrentNetwork.java | 133 ------- .../CurrentNetworkAttributesExtractor.java | 53 --- .../network/CurrentNetworkProvider.java | 158 -------- .../network/NetworkApplicationListener.java | 73 ---- .../NetworkAttributesSpanAppender.java | 64 ---- .../NetworkChangeAttributesExtractor.java | 59 --- .../network/NetworkChangeListener.java | 22 -- .../network/NetworkChangeMonitor.java | 70 ---- .../network/NetworkChangeMonitorBuilder.java | 48 --- .../network/NetworkDetector.java | 39 -- .../instrumentation/network/NetworkState.java | 38 -- .../network/PostApi28NetworkDetector.java | 130 ------- .../network/SimpleNetworkDetector.java | 56 --- .../slowrendering/SlowRenderListener.java | 217 ----------- .../slowrendering/SlowRenderingDetector.java | 69 ---- .../SlowRenderingDetectorBuilder.java | 57 --- .../startup/AppStartupTimer.java | 162 -------- .../rum/internal/util/ActiveSpan.java | 77 ---- .../rum/internal/util/AnchoredClock.java | 41 -- .../rum/internal/AndroidResourceTest.java | 97 ----- .../internal/ApplicationStateWatcherTest.java | 74 ---- .../GlobalAttributesSpanAppenderTest.java | 56 --- .../internal/OpenTelemetryRumBuilderTest.java | 106 ------ .../internal/RuntimeDetailsExtractorTest.java | 64 ---- .../internal/SessionIdChangeTracerTest.java | 55 --- .../SessionIdRatioBasedSamplerTest.java | 105 ----- .../internal/SessionIdSpanAppenderTest.java | 51 --- .../rum/internal/SessionIdTest.java | 109 ------ .../internal/SessionIdTimeoutHandlerTest.java | 91 ----- .../AttributeModifyingSpanExporterTest.java | 138 ------- .../export/FilteringSpanExporterTest.java | 85 ----- .../internal/export/ModifiedSpanDataTest.java | 90 ----- .../internal/export/SpanDataModifierTest.java | 262 ------------- .../rum/internal/export/TestSpanHelper.java | 42 -- .../activity/ActivityCallbackTestHarness.java | 97 ----- .../activity/ActivityCallbacksTest.java | 360 ------------------ .../activity/ActivityTracerCacheTest.java | 138 ------- .../activity/ActivityTracerTest.java | 233 ------------ .../Pre29ActivityCallbackTestHarness.java | 85 ----- .../Pre29ActivityLifecycleCallbacksTest.java | 322 ---------------- ...re29VisibleScreenLifecycleBindingTest.java | 50 --- .../RumFragmentActivityRegistererTest.java | 84 ---- .../VisibleScreenLifecycleBindingTest.java | 48 --- .../activity/VisibleScreenTrackerTest.java | 143 ------- .../instrumentation/anr/AnrDetectorTest.java | 63 --- .../anr/AnrDetectorTogglerTest.java | 64 ---- .../instrumentation/anr/AnrWatcherTest.java | 115 ------ .../anr/StackTraceFormatterTest.java | 52 --- .../crash/CrashReporterTest.java | 102 ----- .../CrashReportingExceptionHandlerTest.java | 66 ---- .../fragment/FragmentCallbackTestHarness.java | 95 ----- .../fragment/FragmentTracerTest.java | 124 ------ .../RumFragmentLifecycleCallbacksTest.java | 338 ---------------- .../fragment/ScreenNameExtractorTest.java | 62 --- .../network/CarrierFinderTest.java | 65 ---- ...CurrentNetworkAttributesExtractorTest.java | 74 ---- .../network/CurrentNetworkProviderTest.java | 239 ------------ .../NetworkAttributesSpanAppenderTest.java | 61 --- .../network/NetworkChangeMonitorTest.java | 174 --------- .../network/NetworkDetectorTest.java | 49 --- .../network/PostApi28NetworkDetectorTest.java | 151 -------- .../network/SimpleNetworkDetectorTest.java | 146 ------- .../slowrendering/SlowRenderListenerTest.java | 223 ----------- .../startup/AppStartupTimerTest.java | 76 ---- sample-app/build.gradle.kts | 2 +- .../splunk/android/sample/MainActivity.java | 2 +- .../splunk/android/sample/SecondFragment.java | 2 +- settings.gradle.kts | 1 - splunk-otel-android/build.gradle.kts | 3 +- .../splunk/rum/CrashComponentExtractor.java | 2 +- .../com/splunk/rum/DiskToZipkinExporter.java | 2 +- .../com/splunk/rum/InitializationEvents.java | 2 +- .../splunk/rum/MemoryBufferingExporter.java | 2 +- .../java/com/splunk/rum/NoOpSplunkRum.java | 2 +- .../java/com/splunk/rum/RumInitializer.java | 30 +- .../splunk/rum/ScreenAttributesAppender.java | 4 +- .../com/splunk/rum/SpanFilterBuilder.java | 2 +- .../main/java/com/splunk/rum/SplunkRum.java | 8 +- .../java/com/splunk/rum/SplunkRumBuilder.java | 2 +- .../splunk/rum/SplunkScreenNameExtractor.java | 2 +- .../splunk/rum/SplunkSpanDataModifier.java | 2 +- .../com/splunk/rum/StandardAttributes.java | 2 +- .../splunk/rum/DiskToZipkinExporterTest.java | 4 +- .../rum/MemoryBufferingExporterTest.java | 4 +- .../com/splunk/rum/RumInitializerTest.java | 6 +- .../rum/ScreenAttributesAppenderTest.java | 6 +- .../java/com/splunk/rum/SplunkRumTest.java | 6 +- .../rum/SplunkSpanDataModifierTest.java | 2 +- 141 files changed, 50 insertions(+), 10992 deletions(-) delete mode 100644 opentelemetry-android-instrumentation/build.gradle.kts delete mode 100644 opentelemetry-android-instrumentation/src/main/AndroidManifest.xml delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/AndroidResource.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/ApplicationStateWatcher.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/DefaultingActivityLifecycleCallbacks.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/GlobalAttributesSpanAppender.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/InstrumentedApplicationImpl.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/NoopOpenTelemetryRum.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRum.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilder.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRumImpl.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/RumConstants.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/RuntimeDetailsExtractor.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SdkPreconfiguredRumBuilder.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionId.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdChangeListener.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdChangeTracer.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdRatioBasedSampler.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdSpanAppender.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdTimeoutHandler.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/AttributeModifyingSpanExporter.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/FilteringSpanExporter.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/FilteringSpanExporterBuilder.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/ModifiedSpanData.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/SpanDataModifier.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/ApplicationStateListener.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/InstrumentedApplication.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/RumScreenName.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/ScreenNameExtractor.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbacks.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracer.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerCache.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityCallbacks.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29VisibleScreenLifecycleBinding.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/RumFragmentActivityRegisterer.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenLifecycleBinding.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenTracker.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetector.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorBuilder.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorToggler.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrWatcher.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/StackTraceFormatter.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashDetails.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashDetailsAttributesExtractor.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporter.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporterBuilder.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReportingExceptionHandler.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentTracer.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/fragment/RumFragmentLifecycleCallbacks.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/lifecycle/AndroidLifecycleInstrumentation.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/lifecycle/AndroidLifecycleInstrumentationBuilder.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/Carrier.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CarrierFinder.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetwork.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkAttributesExtractor.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkProvider.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkApplicationListener.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkAttributesSpanAppender.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeAttributesExtractor.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeListener.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitor.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitorBuilder.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkDetector.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkState.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/PostApi28NetworkDetector.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/SimpleNetworkDetector.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderListener.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderingDetector.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderingDetectorBuilder.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/startup/AppStartupTimer.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/util/ActiveSpan.java delete mode 100644 opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/util/AnchoredClock.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/AndroidResourceTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/ApplicationStateWatcherTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/GlobalAttributesSpanAppenderTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilderTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/RuntimeDetailsExtractorTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdChangeTracerTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdRatioBasedSamplerTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdSpanAppenderTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdTimeoutHandlerTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/AttributeModifyingSpanExporterTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/FilteringSpanExporterTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/ModifiedSpanDataTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/SpanDataModifierTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/TestSpanHelper.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbackTestHarness.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbacksTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerCacheTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityCallbackTestHarness.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityLifecycleCallbacksTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29VisibleScreenLifecycleBindingTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/RumFragmentActivityRegistererTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenLifecycleBindingTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenTrackerTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorTogglerTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrWatcherTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/StackTraceFormatterTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporterTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReportingExceptionHandlerTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentCallbackTestHarness.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentTracerTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/RumFragmentLifecycleCallbacksTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/ScreenNameExtractorTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CarrierFinderTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkAttributesExtractorTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkProviderTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkAttributesSpanAppenderTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitorTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkDetectorTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/PostApi28NetworkDetectorTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/SimpleNetworkDetectorTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderListenerTest.java delete mode 100644 opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/startup/AppStartupTimerTest.java diff --git a/opentelemetry-android-instrumentation/build.gradle.kts b/opentelemetry-android-instrumentation/build.gradle.kts deleted file mode 100644 index 66366d3b..00000000 --- a/opentelemetry-android-instrumentation/build.gradle.kts +++ /dev/null @@ -1,85 +0,0 @@ -plugins { - id("com.android.library") - id("splunk.android-library-conventions") - id("splunk.errorprone-conventions") -} - -// This submodule is alpha and is not yet intended to be used by itself -version = project.version.toString().replaceFirst("(-SNAPSHOT)?$".toRegex(), "-alpha$1") - -android { - namespace = "opentelemetry.rum.instrumentation" - - compileSdk = 34 - buildToolsVersion = "34.0.0" - - defaultConfig { - minSdk = 21 - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - all { - resValue("string", "rum.version", "${project.version}") - } - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - } - } - - compileOptions { - isCoreLibraryDesugaringEnabled = true - - sourceCompatibility(JavaVersion.VERSION_1_8) - targetCompatibility(JavaVersion.VERSION_1_8) - } - - testOptions { - unitTests.isReturnDefaultValues = true - unitTests.isIncludeAndroidResources = true - } -} - -val otelVersion = "1.30.0-SNAPSHOT" -val otelAlphaVersion = otelVersion.replaceFirst("(-SNAPSHOT)?$".toRegex(), "-alpha$1") - -dependencies { - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("androidx.core:core:1.12.0") - implementation("androidx.navigation:navigation-fragment:2.7.3") - - api(platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:$otelAlphaVersion")) - - implementation("io.opentelemetry:opentelemetry-sdk") - implementation("io.opentelemetry:opentelemetry-exporter-zipkin") - implementation("io.zipkin.reporter2:zipkin-sender-okhttp3") - implementation("io.opentelemetry:opentelemetry-exporter-logging") - implementation("io.opentelemetry.instrumentation:opentelemetry-instrumentation-api") - - implementation("io.opentelemetry:opentelemetry-semconv") - - api("io.opentelemetry:opentelemetry-api") - - testImplementation("org.mockito:mockito-core:5.5.0") - testImplementation("org.mockito:mockito-junit-jupiter:5.5.0") - testImplementation(platform("org.junit:junit-bom:5.10.0")) - testImplementation("org.junit.jupiter:junit-jupiter-api") - testImplementation("org.junit.jupiter:junit-jupiter-engine") - testImplementation("org.junit.vintage:junit-vintage-engine") - testImplementation("io.opentelemetry:opentelemetry-sdk-testing") - testImplementation("org.robolectric:robolectric:4.10.3") - testImplementation("androidx.test:core:1.5.0") - testImplementation("org.assertj:assertj-core:3.24.2") - testImplementation("org.awaitility:awaitility:4.2.0") - - coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3") -} - -tasks.withType { - useJUnitPlatform() -} - -extra["pomName"] = "OpenTelemetry Android Instrumentation" -description = "A library for instrumenting Android applications with OpenTelemetry" diff --git a/opentelemetry-android-instrumentation/src/main/AndroidManifest.xml b/opentelemetry-android-instrumentation/src/main/AndroidManifest.xml deleted file mode 100644 index 298c8b6e..00000000 --- a/opentelemetry-android-instrumentation/src/main/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/AndroidResource.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/AndroidResource.java deleted file mode 100644 index ababe475..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/AndroidResource.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static io.opentelemetry.rum.internal.RumConstants.RUM_SDK_VERSION; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.DEVICE_MODEL_IDENTIFIER; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.DEVICE_MODEL_NAME; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.OS_NAME; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.OS_TYPE; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.OS_VERSION; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.SERVICE_NAME; - -import android.app.Application; -import android.os.Build; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.resources.ResourceBuilder; -import java.util.function.Supplier; -import opentelemetry.rum.instrumentation.R; - -final class AndroidResource { - - static Resource createDefault(Application application) { - String appName = readAppName(application); - ResourceBuilder resourceBuilder = - Resource.getDefault().toBuilder().put(SERVICE_NAME, appName); - - return resourceBuilder - .put(RUM_SDK_VERSION, detectRumVersion(application)) - .put(DEVICE_MODEL_NAME, Build.MODEL) - .put(DEVICE_MODEL_IDENTIFIER, Build.MODEL) - .put(OS_NAME, "Android") - .put(OS_TYPE, "linux") - .put(OS_VERSION, Build.VERSION.RELEASE) - .build(); - } - - private static String readAppName(Application application) { - return trapTo( - () -> { - int stringId = - application.getApplicationContext().getApplicationInfo().labelRes; - return application.getApplicationContext().getString(stringId); - }, - "unknown_service:android"); - } - - private static String detectRumVersion(Application application) { - return trapTo( - () -> { - // TODO: Verify that this will be in the lib/jar at runtime. - // TODO: After donation, package of R file will change - return application - .getApplicationContext() - .getResources() - .getString(R.string.rum_version); - }, - "unknown"); - } - - private static String trapTo(Supplier fn, String defaultValue) { - try { - return fn.get(); - } catch (Exception e) { - return defaultValue; - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/ApplicationStateWatcher.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/ApplicationStateWatcher.java deleted file mode 100644 index 4df387b6..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/ApplicationStateWatcher.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import android.app.Activity; -import androidx.annotation.NonNull; -import io.opentelemetry.rum.internal.instrumentation.ApplicationStateListener; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -final class ApplicationStateWatcher implements DefaultingActivityLifecycleCallbacks { - - private final List applicationStateListeners = - new CopyOnWriteArrayList<>(); - // we count the number of activities that have been "started" and not yet "stopped" here to - // figure out when the app goes into the background. - private int numberOfOpenActivities = 0; - - @Override - public void onActivityStarted(@NonNull Activity activity) { - if (numberOfOpenActivities == 0) { - for (ApplicationStateListener listener : applicationStateListeners) { - listener.onApplicationForegrounded(); - } - } - numberOfOpenActivities++; - } - - @Override - public void onActivityStopped(@NonNull Activity activity) { - if (--numberOfOpenActivities == 0) { - for (ApplicationStateListener listener : applicationStateListeners) { - listener.onApplicationBackgrounded(); - } - } - } - - void registerListener(ApplicationStateListener listener) { - applicationStateListeners.add(listener); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/DefaultingActivityLifecycleCallbacks.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/DefaultingActivityLifecycleCallbacks.java deleted file mode 100644 index 1dad341d..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/DefaultingActivityLifecycleCallbacks.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import android.app.Activity; -import android.app.Application; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Interface helper for implementations that don't need/want all the extra baggage of the full - * Application.ActivityLifecycleCallbacks interface. Implementations can choose which methods to - * implement. - */ -public interface DefaultingActivityLifecycleCallbacks - extends Application.ActivityLifecycleCallbacks { - - @Override - default void onActivityCreated( - @NonNull Activity activity, @Nullable Bundle savedInstanceState) {} - - @Override - default void onActivityStarted(@NonNull Activity activity) {} - - @Override - default void onActivityResumed(@NonNull Activity activity) {} - - @Override - default void onActivityPaused(@NonNull Activity activity) {} - - @Override - default void onActivityStopped(@NonNull Activity activity) {} - - @Override - default void onActivitySaveInstanceState( - @NonNull Activity activity, @NonNull Bundle outState) {} - - @Override - default void onActivityDestroyed(@NonNull Activity activity) {} -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/GlobalAttributesSpanAppender.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/GlobalAttributesSpanAppender.java deleted file mode 100644 index 75f8885e..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/GlobalAttributesSpanAppender.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static java.util.Objects.requireNonNull; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import io.opentelemetry.sdk.trace.ReadableSpan; -import io.opentelemetry.sdk.trace.SpanProcessor; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -/** - * A {@link SpanProcessor} implementation that appends a set of {@linkplain Attributes attributes} - * to every span that is exported. The attributes collection is mutable, and can be updated by - * calling {@link #update(Consumer)}. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public final class GlobalAttributesSpanAppender implements SpanProcessor { - - /** - * Returns a new {@link GlobalAttributesSpanAppender} with a given initial attributes. - * - * @param initialState The initial collection of attributes to append to every span. - */ - public static GlobalAttributesSpanAppender create(Attributes initialState) { - return new GlobalAttributesSpanAppender(initialState); - } - - private final AtomicReference attributes; - - private GlobalAttributesSpanAppender(Attributes initialState) { - this.attributes = new AtomicReference<>(initialState); - } - - @Override - public void onStart(Context parentContext, ReadWriteSpan span) { - span.setAllAttributes(attributes.get()); - } - - @Override - public boolean isStartRequired() { - return true; - } - - @Override - public void onEnd(ReadableSpan span) {} - - @Override - public boolean isEndRequired() { - return false; - } - - /** - * Update the global set of attributes that will be appended to every span. - * - *

Note: this operation performs an atomic update. The passed function should be free from - * side effects, since it may be called multiple times in case of thread contention. - * - * @param attributesUpdater A function which will update the current set of attributes, by - * operating on a {@link AttributesBuilder} from the current set. - */ - public void update(Consumer attributesUpdater) { - while (true) { - // we're absolutely certain this will never be null - Attributes oldAttributes = requireNonNull(attributes.get()); - - AttributesBuilder builder = oldAttributes.toBuilder(); - attributesUpdater.accept(builder); - Attributes newAttributes = builder.build(); - - if (attributes.compareAndSet(oldAttributes, newAttributes)) { - break; - } - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/InstrumentedApplicationImpl.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/InstrumentedApplicationImpl.java deleted file mode 100644 index a8274d4e..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/InstrumentedApplicationImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import android.app.Application; -import io.opentelemetry.rum.internal.instrumentation.ApplicationStateListener; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import io.opentelemetry.sdk.OpenTelemetrySdk; - -final class InstrumentedApplicationImpl implements InstrumentedApplication { - - private final Application application; - private final OpenTelemetrySdk openTelemetrySdk; - private final ApplicationStateWatcher applicationStateWatcher; - - InstrumentedApplicationImpl( - Application application, - OpenTelemetrySdk openTelemetrySdk, - ApplicationStateWatcher applicationStateWatcher) { - this.application = application; - this.openTelemetrySdk = openTelemetrySdk; - this.applicationStateWatcher = applicationStateWatcher; - } - - @Override - public Application getApplication() { - return application; - } - - @Override - public OpenTelemetrySdk getOpenTelemetrySdk() { - return openTelemetrySdk; - } - - @Override - public void registerApplicationStateListener(ApplicationStateListener listener) { - applicationStateWatcher.registerListener(listener); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/NoopOpenTelemetryRum.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/NoopOpenTelemetryRum.java deleted file mode 100644 index 8d2d50ed..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/NoopOpenTelemetryRum.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.trace.TraceId; - -enum NoopOpenTelemetryRum implements OpenTelemetryRum { - INSTANCE; - - @Override - public OpenTelemetry getOpenTelemetry() { - return OpenTelemetry.noop(); - } - - @Override - public String getRumSessionId() { - // RUM sessionId has the same format as traceId - return TraceId.getInvalid(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRum.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRum.java deleted file mode 100644 index 0851e7cf..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRum.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import android.app.Application; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.metrics.SdkMeterProvider; -import io.opentelemetry.sdk.trace.SdkTracerProvider; - -/** - * Entrypoint for the OpenTelemetry Real User Monitoring library for Android. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public interface OpenTelemetryRum { - - /** - * Returns a new {@link OpenTelemetryRumBuilder} for {@link OpenTelemetryRum}. Use this version - * if you would like to configure individual aspects of the OpenTelemetry SDK but would still - * prefer to allow OpenTelemetry RUM to create the SDK for you. If you would like to "bring your - * own" SDK, call the two-argument version. - * - * @param application The {@link Application} that is being instrumented. - */ - static OpenTelemetryRumBuilder builder(Application application) { - return new OpenTelemetryRumBuilder(application); - } - - /** - * Returns a new {@link SdkPreconfiguredRumBuilder} for {@link OpenTelemetryRum}. This version - * requires the user to preconfigure and create their own OpenTelemetrySdk instance. If you - * prefer to use the builder to configure individual aspects of the OpenTelemetry SDK and to - * create and manage it for you, call the one-argument version. - * - *

Specific consideration should be given to the creation of your provided SDK to ensure that - * the {@link SdkTracerProvider}, {@link SdkMeterProvider}, and {@link SdkLoggerProvider} are - * configured correctly for your target RUM provider. - * - * @param application The {@link Application} that is being instrumented. - * @param openTelemetrySdk The {@link OpenTelemetrySdk} that the user has already created. - */ - static SdkPreconfiguredRumBuilder builder( - Application application, OpenTelemetrySdk openTelemetrySdk) { - return new SdkPreconfiguredRumBuilder(application, openTelemetrySdk); - } - - /** Returns a no-op implementation of {@link OpenTelemetryRum}. */ - static OpenTelemetryRum noop() { - return NoopOpenTelemetryRum.INSTANCE; - } - - /** - * Get a handle to the instance of the {@linkplain OpenTelemetry OpenTelemetry API} that this - * instance is using for instrumentation. - */ - OpenTelemetry getOpenTelemetry(); - - /** - * Get the client session ID associated with this instance of the RUM instrumentation library. - * Note: this value will change throughout the lifetime of an application instance, so it is - * recommended that you do not cache this value, but always retrieve it from here when needed. - */ - String getRumSessionId(); -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilder.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilder.java deleted file mode 100644 index 12d8b705..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilder.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import android.app.Application; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; -import io.opentelemetry.sdk.metrics.SdkMeterProvider; -import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Consumer; - -/** - * A builder of {@link OpenTelemetryRum}. It enabled configuring the OpenTelemetry SDK and disabling - * built-in Android instrumentations. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public final class OpenTelemetryRumBuilder { - - private final SessionId sessionId; - private final Application application; - private final List> - tracerProviderCustomizers = new ArrayList<>(); - private final List> - meterProviderCustomizers = new ArrayList<>(); - private final List> - loggerProviderCustomizers = new ArrayList<>(); - private final List> instrumentationInstallers = - new ArrayList<>(); - private Resource resource; - - OpenTelemetryRumBuilder(Application application) { - this.application = application; - SessionIdTimeoutHandler timeoutHandler = new SessionIdTimeoutHandler(); - this.sessionId = new SessionId(timeoutHandler); - this.resource = AndroidResource.createDefault(application); - } - - /** - * Assign a {@link Resource} to be attached to all telemetry emitted by the {@link - * OpenTelemetryRum} created by this builder. This replaces any existing resource. - * - * @return {@code this} - */ - public OpenTelemetryRumBuilder setResource(Resource resource) { - this.resource = resource; - return this; - } - - /** - * Merges a new {@link Resource} with any existing {@link Resource} in this builder. The - * resulting {@link Resource} will be attached to all telemetry emitted by the {@link - * OpenTelemetryRum} created by this builder. - * - * @return {@code this} - */ - public OpenTelemetryRumBuilder mergeResource(Resource resource) { - this.resource = this.resource.merge(resource); - return this; - } - - /** - * Adds a {@link BiFunction} to invoke the with the {@link SdkTracerProviderBuilder} to allow - * customization. The return value of the {@link BiFunction} will replace the passed-in - * argument. - * - *

Multiple calls will execute the customizers in order. - * - *

Note: calling {@link SdkTracerProviderBuilder#setResource(Resource)} inside of your - * configuration function will cause any resource customizers to be ignored that were configured - * via {@link #setResource(Resource)}. - * - * @return {@code this} - */ - public OpenTelemetryRumBuilder addTracerProviderCustomizer( - BiFunction - customizer) { - tracerProviderCustomizers.add(customizer); - return this; - } - - /** - * Adds a {@link BiFunction} to invoke the with the {@link SdkMeterProviderBuilder} to allow - * customization. The return value of the {@link BiFunction} will replace the passed-in - * argument. - * - *

Multiple calls will execute the customizers in order. - * - *

Note: calling {@link SdkMeterProviderBuilder#setResource(Resource)} inside of your - * configuration function will cause any resource customizers to be ignored that were configured - * via {@link #setResource(Resource)}. - * - * @return {@code this} - */ - public OpenTelemetryRumBuilder addMeterProviderCustomizer( - BiFunction customizer) { - meterProviderCustomizers.add(customizer); - return this; - } - - /** - * Adds a {@link BiFunction} to invoke the with the {@link SdkLoggerProviderBuilder} to allow - * customization. The return value of the {@link BiFunction} will replace the passed-in - * argument. - * - *

Multiple calls will execute the customizers in order. - * - *

Note: calling {@link SdkLoggerProviderBuilder#setResource(Resource)} inside of your - * configuration function will cause any resource customizers to be ignored that were configured - * via {@link #setResource(Resource)}. - * - * @return {@code this} - */ - public OpenTelemetryRumBuilder addLoggerProviderCustomizer( - BiFunction - customizer) { - loggerProviderCustomizers.add(customizer); - return this; - } - - /** - * Adds an instrumentation installer function that will be run on an {@link - * InstrumentedApplication} instance as a part of the {@link #build()} method call. - * - * @return {@code this} - */ - public OpenTelemetryRumBuilder addInstrumentation( - Consumer instrumentationInstaller) { - instrumentationInstallers.add(instrumentationInstaller); - return this; - } - - public SessionId getSessionId() { - return sessionId; - } - - /** - * Creates a new instance of {@link OpenTelemetryRum} with the settings of this {@link - * OpenTelemetryRumBuilder}. - * - *

This method will initialize the OpenTelemetry SDK and install built-in system - * instrumentations in the passed Android {@link Application}. - * - * @return A new {@link OpenTelemetryRum} instance. - */ - public OpenTelemetryRum build() { - OpenTelemetrySdk sdk = - OpenTelemetrySdk.builder() - .setTracerProvider(buildTracerProvider(sessionId, application)) - .setMeterProvider(buildMeterProvider(application)) - .setLoggerProvider(buildLoggerProvider(application)) - .build(); - - SdkPreconfiguredRumBuilder delegate = - new SdkPreconfiguredRumBuilder(application, sdk, sessionId); - instrumentationInstallers.forEach(delegate::addInstrumentation); - return delegate.build(); - } - - private SdkTracerProvider buildTracerProvider(SessionId sessionId, Application application) { - SdkTracerProviderBuilder tracerProviderBuilder = - SdkTracerProvider.builder() - .setResource(resource) - .addSpanProcessor(new SessionIdSpanAppender(sessionId)); - for (BiFunction - customizer : tracerProviderCustomizers) { - tracerProviderBuilder = customizer.apply(tracerProviderBuilder, application); - } - return tracerProviderBuilder.build(); - } - - private SdkMeterProvider buildMeterProvider(Application application) { - SdkMeterProviderBuilder meterProviderBuilder = - SdkMeterProvider.builder().setResource(resource); - for (BiFunction customizer : - meterProviderCustomizers) { - meterProviderBuilder = customizer.apply(meterProviderBuilder, application); - } - return meterProviderBuilder.build(); - } - - private SdkLoggerProvider buildLoggerProvider(Application application) { - SdkLoggerProviderBuilder loggerProviderBuilder = - SdkLoggerProvider.builder().setResource(resource); - for (BiFunction - customizer : loggerProviderCustomizers) { - loggerProviderBuilder = customizer.apply(loggerProviderBuilder, application); - } - return loggerProviderBuilder.build(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRumImpl.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRumImpl.java deleted file mode 100644 index 2b749fc4..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/OpenTelemetryRumImpl.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.OpenTelemetrySdk; - -final class OpenTelemetryRumImpl implements OpenTelemetryRum { - - private final OpenTelemetrySdk openTelemetrySdk; - private final SessionId sessionId; - - OpenTelemetryRumImpl(OpenTelemetrySdk openTelemetrySdk, SessionId sessionId) { - this.openTelemetrySdk = openTelemetrySdk; - this.sessionId = sessionId; - } - - @Override - public OpenTelemetry getOpenTelemetry() { - return openTelemetrySdk; - } - - @Override - public String getRumSessionId() { - return sessionId.getSessionId(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/RumConstants.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/RumConstants.java deleted file mode 100644 index 84ca8371..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/RumConstants.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static io.opentelemetry.api.common.AttributeKey.doubleKey; -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; - -import io.opentelemetry.api.common.AttributeKey; - -public class RumConstants { - - public static final String OTEL_RUM_LOG_TAG = "OpenTelemetryRum"; - - public static final AttributeKey SESSION_ID_KEY = stringKey("rum.session.id"); - - public static final AttributeKey LAST_SCREEN_NAME_KEY = - AttributeKey.stringKey("last.screen.name"); - public static final AttributeKey SCREEN_NAME_KEY = - AttributeKey.stringKey("screen.name"); - public static final AttributeKey START_TYPE_KEY = stringKey("start.type"); - - public static final AttributeKey RUM_SDK_VERSION = stringKey("rum.sdk.version"); - - public static final AttributeKey STORAGE_SPACE_FREE_KEY = longKey("storage.free"); - public static final AttributeKey HEAP_FREE_KEY = longKey("heap.free"); - public static final AttributeKey BATTERY_PERCENT_KEY = doubleKey("battery.percent"); - - public static final AttributeKey PREVIOUS_SESSION_ID_KEY = - stringKey("rum.session.previous_id"); - - public static final String APP_START_SPAN_NAME = "AppStart"; - - private RumConstants() {} -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/RuntimeDetailsExtractor.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/RuntimeDetailsExtractor.java deleted file mode 100644 index 36125d09..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/RuntimeDetailsExtractor.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static io.opentelemetry.rum.internal.RumConstants.BATTERY_PERCENT_KEY; -import static io.opentelemetry.rum.internal.RumConstants.HEAP_FREE_KEY; -import static io.opentelemetry.rum.internal.RumConstants.STORAGE_SPACE_FREE_KEY; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.BatteryManager; -import androidx.annotation.Nullable; -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import java.io.File; - -/** Represents details about the runtime environment at a time */ -public final class RuntimeDetailsExtractor extends BroadcastReceiver - implements AttributesExtractor { - - private @Nullable volatile Double batteryPercent = null; - private final File filesDir; - - public static RuntimeDetailsExtractor create(Context context) { - IntentFilter batteryChangedFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); - File filesDir = context.getFilesDir(); - RuntimeDetailsExtractor runtimeDetails = new RuntimeDetailsExtractor<>(filesDir); - context.registerReceiver(runtimeDetails, batteryChangedFilter); - return runtimeDetails; - } - - private RuntimeDetailsExtractor(File filesDir) { - this.filesDir = filesDir; - } - - @Override - public void onReceive(Context context, Intent intent) { - int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); - int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); - batteryPercent = level * 100.0d / (float) scale; - } - - @Override - public void onStart( - AttributesBuilder attributes, - io.opentelemetry.context.Context parentContext, - RQ request) { - attributes.put(STORAGE_SPACE_FREE_KEY, getCurrentStorageFreeSpaceInBytes()); - attributes.put(HEAP_FREE_KEY, getCurrentFreeHeapInBytes()); - - Double currentBatteryPercent = getCurrentBatteryPercent(); - if (currentBatteryPercent != null) { - attributes.put(BATTERY_PERCENT_KEY, currentBatteryPercent); - } - } - - @Override - public void onEnd( - AttributesBuilder attributes, - io.opentelemetry.context.Context context, - RQ request, - RS response, - Throwable error) {} - - private long getCurrentStorageFreeSpaceInBytes() { - return filesDir.getFreeSpace(); - } - - private long getCurrentFreeHeapInBytes() { - Runtime runtime = Runtime.getRuntime(); - return runtime.freeMemory(); - } - - @Nullable - private Double getCurrentBatteryPercent() { - return batteryPercent; - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SdkPreconfiguredRumBuilder.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SdkPreconfiguredRumBuilder.java deleted file mode 100644 index 667bb1a5..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SdkPreconfiguredRumBuilder.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import android.app.Application; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public final class SdkPreconfiguredRumBuilder { - private final Application application; - private final OpenTelemetrySdk sdk; - private final SessionId sessionId; - - private final List> instrumentationInstallers = - new ArrayList<>(); - - SdkPreconfiguredRumBuilder(Application application, OpenTelemetrySdk openTelemetrySdk) { - this(application, openTelemetrySdk, new SessionId(new SessionIdTimeoutHandler())); - } - - SdkPreconfiguredRumBuilder( - Application application, OpenTelemetrySdk openTelemetrySdk, SessionId sessionId) { - this.application = application; - this.sdk = openTelemetrySdk; - this.sessionId = sessionId; - } - - /** - * Adds an instrumentation installer function that will be run on an {@link - * InstrumentedApplication} instance as a part of the {@link #build()} method call. - * - * @return {@code this} - */ - public SdkPreconfiguredRumBuilder addInstrumentation( - Consumer instrumentationInstaller) { - instrumentationInstallers.add(instrumentationInstaller); - return this; - } - - /** - * Creates a new instance of {@link OpenTelemetryRum} with the settings of this {@link - * OpenTelemetryRumBuilder}. - * - *

This method uses a preconfigured OpenTelemetry SDK and install built-in system - * instrumentations in the passed Android {@link Application}. - * - * @return A new {@link OpenTelemetryRum} instance. - */ - public OpenTelemetryRum build() { - // the app state listeners need to be run in the first ActivityLifecycleCallbacks since they - // might turn off/on additional telemetry depending on whether the app is active or not - ApplicationStateWatcher applicationStateWatcher = new ApplicationStateWatcher(); - application.registerActivityLifecycleCallbacks(applicationStateWatcher); - applicationStateWatcher.registerListener(sessionId.getTimeoutHandler()); - - Tracer tracer = sdk.getTracer(OpenTelemetryRum.class.getSimpleName()); - sessionId.setSessionIdChangeListener(new SessionIdChangeTracer(tracer)); - - InstrumentedApplication instrumentedApplication = - new InstrumentedApplicationImpl(application, sdk, applicationStateWatcher); - for (Consumer installer : instrumentationInstallers) { - installer.accept(instrumentedApplication); - } - - return new OpenTelemetryRumImpl(sdk, sessionId); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionId.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionId.java deleted file mode 100644 index e61c15d4..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionId.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static java.util.Objects.requireNonNull; - -import androidx.annotation.Nullable; -import io.opentelemetry.api.trace.TraceId; -import io.opentelemetry.sdk.common.Clock; -import java.util.Random; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - -class SessionId { - - private static final long SESSION_LIFETIME_NANOS = TimeUnit.HOURS.toNanos(4); - - private final Clock clock; - private final AtomicReference value = new AtomicReference<>(); - private final SessionIdTimeoutHandler timeoutHandler; - private volatile long createTimeNanos; - @Nullable private volatile SessionIdChangeListener sessionIdChangeListener; - - SessionId(SessionIdTimeoutHandler timeoutHandler) { - this(Clock.getDefault(), timeoutHandler); - } - - // for testing - SessionId(Clock clock, SessionIdTimeoutHandler timeoutHandler) { - this.clock = clock; - this.timeoutHandler = timeoutHandler; - value.set(createNewId()); - createTimeNanos = clock.now(); - } - - private static String createNewId() { - Random random = new Random(); - // The OTel TraceId has exactly the same format as a RUM SessionId, so let's re-use it here, - // rather than re-inventing the wheel. - return TraceId.fromLongs(random.nextLong(), random.nextLong()); - } - - SessionIdTimeoutHandler getTimeoutHandler() { - return timeoutHandler; - } - - String getSessionId() { - // value will never be null - String oldValue = requireNonNull(value.get()); - String currentValue = oldValue; - boolean sessionIdChanged = false; - - if (sessionExpired() || timeoutHandler.hasTimedOut()) { - String newId = createNewId(); - // if this returns false, then another thread updated the value already. - sessionIdChanged = value.compareAndSet(oldValue, newId); - if (sessionIdChanged) { - createTimeNanos = clock.nanoTime(); - } - // value will never be null - currentValue = requireNonNull(value.get()); - } - - timeoutHandler.bump(); - // sessionId change listener needs to be called after bumping the timer because it may - // create a new span - SessionIdChangeListener sessionIdChangeListener = this.sessionIdChangeListener; - if (sessionIdChanged && sessionIdChangeListener != null) { - sessionIdChangeListener.onChange(oldValue, currentValue); - } - - return currentValue; - } - - private boolean sessionExpired() { - long elapsedTime = clock.nanoTime() - createTimeNanos; - return elapsedTime >= SESSION_LIFETIME_NANOS; - } - - void setSessionIdChangeListener(SessionIdChangeListener sessionIdChangeListener) { - this.sessionIdChangeListener = sessionIdChangeListener; - } - - @Override - public String toString() { - // value will never be null - return requireNonNull(value.get()); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdChangeListener.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdChangeListener.java deleted file mode 100644 index 01966b3b..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdChangeListener.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -interface SessionIdChangeListener { - - /** Gets called every time a new sessionId is generated. */ - void onChange(String oldSessionId, String newSessionId); -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdChangeTracer.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdChangeTracer.java deleted file mode 100644 index b7b3d030..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdChangeTracer.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import io.opentelemetry.api.trace.Tracer; - -final class SessionIdChangeTracer implements SessionIdChangeListener { - - private final Tracer tracer; - - SessionIdChangeTracer(Tracer tracer) { - this.tracer = tracer; - } - - @Override - public void onChange(String oldSessionId, String newSessionId) { - tracer.spanBuilder("sessionId.change") - .setAttribute(RumConstants.PREVIOUS_SESSION_ID_KEY, oldSessionId) - .startSpan() - .end(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdRatioBasedSampler.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdRatioBasedSampler.java deleted file mode 100644 index 0843b819..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdRatioBasedSampler.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.trace.data.LinkData; -import io.opentelemetry.sdk.trace.samplers.Sampler; -import io.opentelemetry.sdk.trace.samplers.SamplingResult; -import java.util.List; - -/** - * Session ID ratio based sampler. Uses {@link Sampler#traceIdRatioBased(double)} sampler - * internally, but passes sessionId instead of traceId to the underlying sampler in order to use the - * same ratio logic but on sessionId instead. This is valid as sessionId uses {@link - * io.opentelemetry.api.trace.TraceId#fromLongs(long, long)} internally to generate random session - * IDs. - */ -public class SessionIdRatioBasedSampler implements Sampler { - private final Sampler ratioBasedSampler; - private final SessionId sessionId; - - public SessionIdRatioBasedSampler(double ratio, SessionId sessionId) { - this.sessionId = sessionId; - // SessionId uses the same format as TraceId, so we can reuse trace ID ratio sampler. - this.ratioBasedSampler = Sampler.traceIdRatioBased(ratio); - } - - @Override - public SamplingResult shouldSample( - Context parentContext, - String traceId, - String name, - SpanKind spanKind, - Attributes attributes, - List parentLinks) { - // Replace traceId with sessionId - return ratioBasedSampler.shouldSample( - parentContext, sessionId.getSessionId(), name, spanKind, attributes, parentLinks); - } - - @Override - public String getDescription() { - return String.format( - "SessionIdRatioBased{traceIdRatioBased:%s}", - this.ratioBasedSampler.getDescription()); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdSpanAppender.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdSpanAppender.java deleted file mode 100644 index 13814bfa..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdSpanAppender.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import io.opentelemetry.sdk.trace.ReadableSpan; -import io.opentelemetry.sdk.trace.SpanProcessor; - -final class SessionIdSpanAppender implements SpanProcessor { - - private final SessionId sessionId; - - public SessionIdSpanAppender(SessionId sessionId) { - this.sessionId = sessionId; - } - - @Override - public void onStart(Context parentContext, ReadWriteSpan span) { - span.setAttribute(RumConstants.SESSION_ID_KEY, sessionId.getSessionId()); - } - - @Override - public boolean isStartRequired() { - return true; - } - - @Override - public void onEnd(ReadableSpan span) {} - - @Override - public boolean isEndRequired() { - return false; - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdTimeoutHandler.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdTimeoutHandler.java deleted file mode 100644 index 791aa43f..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/SessionIdTimeoutHandler.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import io.opentelemetry.rum.internal.instrumentation.ApplicationStateListener; -import io.opentelemetry.sdk.common.Clock; -import java.util.concurrent.TimeUnit; - -/** - * This class encapsulates the following criteria about the sessionId timeout: - * - *

    - *
  • If the app is in the foreground sessionId should never time out. - *
  • If the app is in the background and no activity (spans) happens for >15 minutes, sessionId - * should time out. - *
  • If the app is in the background and some activity (spans) happens in <15 minute intervals, - * sessionId should not time out. - *
- * - *

Consequently, when the app spent >15 minutes without any activity (spans) in the background, - * after moving to the foreground the first span should trigger the sessionId timeout. - */ -final class SessionIdTimeoutHandler implements ApplicationStateListener { - - private static final long SESSION_TIMEOUT_NANOS = TimeUnit.MINUTES.toNanos(15); - - private final Clock clock; - private volatile long timeoutStartNanos; - private volatile State state = State.FOREGROUND; - - SessionIdTimeoutHandler() { - this(Clock.getDefault()); - } - - // for testing - SessionIdTimeoutHandler(Clock clock) { - this.clock = clock; - } - - @Override - public void onApplicationForegrounded() { - state = State.TRANSITIONING_TO_FOREGROUND; - } - - @Override - public void onApplicationBackgrounded() { - state = State.BACKGROUND; - } - - boolean hasTimedOut() { - // don't apply sessionId timeout to apps in the foreground - if (state == State.FOREGROUND) { - return false; - } - long elapsedTime = clock.nanoTime() - timeoutStartNanos; - return elapsedTime >= SESSION_TIMEOUT_NANOS; - } - - void bump() { - timeoutStartNanos = clock.nanoTime(); - - // move from the temporary transition state to foreground after the first span - if (state == State.TRANSITIONING_TO_FOREGROUND) { - state = State.FOREGROUND; - } - } - - private enum State { - FOREGROUND, - BACKGROUND, - /** A temporary state representing the first event after the app has been brought back. */ - TRANSITIONING_TO_FOREGROUND - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/AttributeModifyingSpanExporter.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/AttributeModifyingSpanExporter.java deleted file mode 100644 index 51538e7b..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/AttributeModifyingSpanExporter.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** A SpanExporter that is configured to modify some of its attributes at export time. */ -public class AttributeModifyingSpanExporter implements SpanExporter { - - private final SpanExporter delegate; - private final Map, Function> spanAttributeReplacements; - - public AttributeModifyingSpanExporter( - SpanExporter delegate, Map, Function> spanAttributeReplacements) { - this.delegate = delegate; - this.spanAttributeReplacements = spanAttributeReplacements; - } - - @Override - public CompletableResultCode export(Collection spans) { - if (spanAttributeReplacements.isEmpty()) { - return delegate.export(spans); - } - - List modifiedSpans = - spans.stream().map(this::doModify).collect(Collectors.toList()); - return delegate.export(modifiedSpans); - } - - private SpanData doModify(SpanData span) { - Attributes modifiedAttributes = buildModifiedAttributes(span); - return new ModifiedSpanData(span, modifiedAttributes); - } - - @NonNull - private Attributes buildModifiedAttributes(SpanData span) { - AttributesBuilder modifiedAttributes = Attributes.builder(); - span.getAttributes() - .forEach( - (key, attrValue) -> { - Function remapper = getRemapper(key); - if (remapper != null) { - attrValue = remapper.apply(attrValue); - } - if (attrValue != null) { - modifiedAttributes.put((AttributeKey) key, attrValue); - } - }); - return modifiedAttributes.build(); - } - - @Nullable - private Function getRemapper(AttributeKey key) { - return (Function) spanAttributeReplacements.get(key); - } - - @Override - public CompletableResultCode flush() { - return delegate.flush(); - } - - @Override - public CompletableResultCode shutdown() { - return delegate.shutdown(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/FilteringSpanExporter.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/FilteringSpanExporter.java deleted file mode 100644 index c0744d65..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/FilteringSpanExporter.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.Collection; -import java.util.List; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -/** An exporter that will filter (not export) spans that fail a predicate. */ -public class FilteringSpanExporter implements SpanExporter { - - private final SpanExporter delegate; - - private final Predicate spanRejecter; - - public static FilteringSpanExporterBuilder builder(SpanExporter delegate) { - return new FilteringSpanExporterBuilder(delegate); - } - - FilteringSpanExporter(SpanExporter delegate, Predicate spanRejecter) { - this.delegate = delegate; - this.spanRejecter = spanRejecter; - } - - @Override - public CompletableResultCode export(Collection spans) { - List toExport = - spans.stream().filter(spanRejecter.negate()).collect(Collectors.toList()); - return delegate.export(toExport); - } - - @Override - public CompletableResultCode flush() { - return delegate.flush(); - } - - @Override - public CompletableResultCode shutdown() { - return delegate.shutdown(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/FilteringSpanExporterBuilder.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/FilteringSpanExporterBuilder.java deleted file mode 100644 index f23a4154..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/FilteringSpanExporterBuilder.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.Map; -import java.util.function.Predicate; - -public final class FilteringSpanExporterBuilder { - - private final SpanExporter delegate; - private Predicate predicate = x -> false; - - FilteringSpanExporterBuilder(SpanExporter spanExporter) { - this.delegate = spanExporter; - } - - /** - * Creates a SpanExporter that will not export any spans whose name matches the given name. All - * other spans will be exported by the delegate. - * - * @param name - Entire case sensitive span name to match for exclusion - * @return a SpanExporter - */ - public FilteringSpanExporterBuilder rejectSpansNamed(String name) { - return rejecting(span -> name.equals(span.getName())); - } - - /** - * Creates a SpanExporter that will not export any spans whose name matches the given predicate. - * All other spans will be exported by the delegate. - * - * @param spanNamePredicate - predicate to test the span name atainst - * @return a SpanExporter - */ - public FilteringSpanExporterBuilder rejectSpansNamed(Predicate spanNamePredicate) { - return rejecting(span -> spanNamePredicate.test(span.getName())); - } - - /** - * Creates a SpanExporter that will not export any spans whose name contains the given - * substring. All other spans will be exported by the delegate. - * - * @param substring - Substring go match within the span name - * @return a SpanExporter - */ - public FilteringSpanExporterBuilder rejectSpansWithNameContaining(String substring) { - return rejecting(span -> span.getName().contains(substring)); - } - - /** - * Creates a span exporter that will not export any spans whose SpanData matches the rejecting - * predicate. - * - * @param predicate A predicate that returns true when a span is to be rejected - * @return this - */ - public FilteringSpanExporterBuilder rejecting(Predicate predicate) { - this.predicate = this.predicate.or(predicate); - return this; - } - - public FilteringSpanExporterBuilder rejectSpansWithAttributesMatching( - Map, Predicate> attrRejection) { - if (attrRejection.isEmpty()) { - return this; - } - Predicate spanRejecter = - spanData -> { - Attributes attributes = spanData.getAttributes(); - return attrRejection.entrySet().stream() - .anyMatch( - e -> { - AttributeKey key = e.getKey(); - Predicate valuePredicate = - (Predicate) e.getValue(); - Object attributeValue = attributes.get(key); - return (attributeValue != null - && valuePredicate.test(attributeValue)); - }); - }; - this.predicate = this.predicate.or(spanRejecter); - return this; - } - - public SpanExporter build() { - return new FilteringSpanExporter(delegate, this.predicate); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/ModifiedSpanData.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/ModifiedSpanData.java deleted file mode 100644 index 9340c2ea..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/ModifiedSpanData.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.trace.data.DelegatingSpanData; -import io.opentelemetry.sdk.trace.data.SpanData; - -final class ModifiedSpanData extends DelegatingSpanData { - - private final Attributes modifiedAttributes; - - ModifiedSpanData(SpanData original, Attributes modifiedAttributes) { - super(original); - this.modifiedAttributes = modifiedAttributes; - } - - @Override - public Attributes getAttributes() { - return modifiedAttributes; - } - - @Override - public int getTotalAttributeCount() { - return modifiedAttributes.size(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/SpanDataModifier.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/SpanDataModifier.java deleted file mode 100644 index fa714533..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/export/SpanDataModifier.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * A utility that can be used to create a SpanExporter that allows filtering and modification of - * span data before it is sent to Allows modification of span data before it is sent to a delegate - * exporter. Spans can be rejected entirely based on their name or attribute content, or their - * attributes may be modified. - */ -public final class SpanDataModifier { - - private final SpanExporter delegate; - private Predicate rejectSpanNamesPredicate = spanName -> false; - private final Map, Predicate> rejectSpanAttributesPredicates = - new HashMap<>(); - private final Map, Function> spanAttributeReplacements = new HashMap<>(); - - public static SpanDataModifier builder(SpanExporter delegate) { - return new SpanDataModifier(delegate); - } - - private SpanDataModifier(SpanExporter delegate) { - this.delegate = delegate; - } - - /** - * Remove matching spans from the exporter pipeline. - * - *

Spans with names that match the {@code spanNamePredicate} will not be exported. - * - * @param spanNamePredicate A function that returns true if a span with passed name should be - * rejected. - * @return {@code this}. - */ - public SpanDataModifier rejectSpansByName(Predicate spanNamePredicate) { - rejectSpanNamesPredicate = rejectSpanNamesPredicate.or(spanNamePredicate); - return this; - } - - /** - * Remove matching spans from the exporter pipeline. - * - *

Any span that contains an attribute with key {@code attributeKey} and value matching the - * {@code attributeValuePredicate} will not be exported. - * - * @param attributeKey An attribute key to match. - * @param attributeValuePredicate A function that returns true if a span containing an attribute - * with matching value should be rejected. - * @return {@code this}. - */ - public SpanDataModifier rejectSpansByAttributeValue( - AttributeKey attributeKey, Predicate attributeValuePredicate) { - - rejectSpanAttributesPredicates.compute( - attributeKey, - (k, oldValue) -> - oldValue == null - ? attributeValuePredicate - : ((Predicate) oldValue).or(attributeValuePredicate)); - return this; - } - - /** - * Modify span data before it enters the exporter pipeline. - * - *

Any attribute with key {@code attributeKey} and will be removed from the span before it is - * exported. - * - * @param attributeKey An attribute key to match. - * @return {@code this}. - */ - public SpanDataModifier removeSpanAttribute(AttributeKey attributeKey) { - return removeSpanAttribute(attributeKey, value -> true); - } - - /** - * Modify span data before it enters the exporter pipeline. - * - *

Any attribute with key {@code attributeKey} and value matching the {@code - * attributeValuePredicate} will be removed from the span before it is exported. - * - * @param attributeKey An attribute key to match. - * @param attributeValuePredicate A function that returns true if an attribute with matching - * value should be removed from the span. - * @return {@code this}. - */ - public SpanDataModifier removeSpanAttribute( - AttributeKey attributeKey, Predicate attributeValuePredicate) { - - return replaceSpanAttribute( - attributeKey, old -> attributeValuePredicate.test(old) ? null : old); - } - - /** - * Modify span data before it enters the exporter pipeline. - * - *

The value of any attribute with key {@code attributeKey} will be passed to the {@code - * attributeValueModifier} function. The value returned by the function will replace the - * original value. When the modifier function returns {@code null} the attribute will be removed - * from the span. - * - * @param attributeKey An attribute key to match. - * @param attributeValueModifier A function that receives the old attribute value and returns - * the new one. - * @return {@code this}. - */ - public SpanDataModifier replaceSpanAttribute( - AttributeKey attributeKey, Function attributeValueModifier) { - - spanAttributeReplacements.compute( - attributeKey, - (k, oldValue) -> - oldValue == null - ? attributeValueModifier - : ((Function) oldValue).andThen(attributeValueModifier)); - return this; - } - - public SpanExporter build() { - SpanExporter modifier = delegate; - if (!spanAttributeReplacements.isEmpty()) { - modifier = - new AttributeModifyingSpanExporter( - delegate, new HashMap<>(spanAttributeReplacements)); - } - return FilteringSpanExporter.builder(modifier) - .rejectSpansWithAttributesMatching(new HashMap<>(rejectSpanAttributesPredicates)) - .rejectSpansNamed(rejectSpanNamesPredicate) - .build(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/ApplicationStateListener.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/ApplicationStateListener.java deleted file mode 100644 index cf30b877..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/ApplicationStateListener.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation; - -/** - * Listener interface that is called whenever the instrumented application is brought to foreground - * from the background, or vice versa. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public interface ApplicationStateListener { - - /** - * Called whenever the application is brought to the foreground (i.e. first activity starts). - */ - void onApplicationForegrounded(); - - /** Called whenever the application is brought to the background (i.e. last activity stops). */ - void onApplicationBackgrounded(); -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/InstrumentedApplication.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/InstrumentedApplication.java deleted file mode 100644 index f853bd05..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/InstrumentedApplication.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation; - -import android.app.Application; -import io.opentelemetry.rum.internal.OpenTelemetryRum; -import io.opentelemetry.sdk.OpenTelemetrySdk; - -/** - * Provides access to the {@linkplain OpenTelemetrySdk OpenTelemetry SDK}, the instrumented {@link - * Application}, allows registering {@linkplain ApplicationStateListener listeners}. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public interface InstrumentedApplication { - - /** Returns the instrumented {@link Application}. */ - Application getApplication(); - - /** - * Returns the {@link OpenTelemetrySdk} that is a part of the constructed {@link - * OpenTelemetryRum}. - */ - OpenTelemetrySdk getOpenTelemetrySdk(); - - /** - * Registers the passed {@link ApplicationStateListener} - from now on it will be called - * whenever the application is moved from background to foreground, and vice versa. - * - *

Users of this method should take care to avoid passing the same listener instance multiple - * times; duplicates are not trimmed. - */ - void registerApplicationStateListener(ApplicationStateListener listener); -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/RumScreenName.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/RumScreenName.java deleted file mode 100644 index 97573888..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/RumScreenName.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This annotation can be used to customize the {@code screen.name} attribute for an instrumented - * Fragment or Activity. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface RumScreenName { - /** Return the customized screen name. */ - String value(); -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/ScreenNameExtractor.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/ScreenNameExtractor.java deleted file mode 100644 index 33e90c72..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/ScreenNameExtractor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation; - -import android.app.Activity; -import androidx.fragment.app.Fragment; - -public interface ScreenNameExtractor { - - String extract(Activity activity); - - String extract(Fragment fragment); - - ScreenNameExtractor DEFAULT = - new ScreenNameExtractor() { - @Override - public String extract(Activity activity) { - return useAnnotationOrClassName(activity.getClass()); - } - - @Override - public String extract(Fragment fragment) { - return useAnnotationOrClassName(fragment.getClass()); - } - - private String useAnnotationOrClassName(Class clazz) { - RumScreenName rumScreenName = clazz.getAnnotation(RumScreenName.class); - return rumScreenName == null ? clazz.getSimpleName() : rumScreenName.value(); - } - }; -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbacks.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbacks.java deleted file mode 100644 index 55b1ed25..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbacks.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import android.app.Activity; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import io.opentelemetry.rum.internal.DefaultingActivityLifecycleCallbacks; - -public class ActivityCallbacks implements DefaultingActivityLifecycleCallbacks { - - private final ActivityTracerCache tracers; - - public ActivityCallbacks(ActivityTracerCache tracers) { - this.tracers = tracers; - } - - @Override - public void onActivityPreCreated( - @NonNull Activity activity, @Nullable Bundle savedInstanceState) { - tracers.startActivityCreation(activity).addEvent("activityPreCreated"); - } - - @Override - public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { - tracers.addEvent(activity, "activityCreated"); - } - - @Override - public void onActivityPostCreated( - @NonNull Activity activity, @Nullable Bundle savedInstanceState) { - tracers.addEvent(activity, "activityPostCreated"); - } - - @Override - public void onActivityPreStarted(@NonNull Activity activity) { - tracers.initiateRestartSpanIfNecessary(activity).addEvent("activityPreStarted"); - } - - @Override - public void onActivityStarted(@NonNull Activity activity) { - tracers.addEvent(activity, "activityStarted"); - } - - @Override - public void onActivityPostStarted(@NonNull Activity activity) { - tracers.addEvent(activity, "activityPostStarted"); - } - - @Override - public void onActivityPreResumed(@NonNull Activity activity) { - tracers.startSpanIfNoneInProgress(activity, "Resumed").addEvent("activityPreResumed"); - } - - @Override - public void onActivityResumed(@NonNull Activity activity) { - tracers.addEvent(activity, "activityResumed"); - } - - @Override - public void onActivityPostResumed(@NonNull Activity activity) { - tracers.addEvent(activity, "activityPostResumed") - .addPreviousScreenAttribute() - .endSpanForActivityResumed(); - } - - @Override - public void onActivityPrePaused(@NonNull Activity activity) { - tracers.startSpanIfNoneInProgress(activity, "Paused").addEvent("activityPrePaused"); - } - - @Override - public void onActivityPaused(@NonNull Activity activity) { - tracers.addEvent(activity, "activityPaused"); - } - - @Override - public void onActivityPostPaused(@NonNull Activity activity) { - tracers.addEvent(activity, "activityPostPaused").endActiveSpan(); - } - - @Override - public void onActivityPreStopped(@NonNull Activity activity) { - tracers.startSpanIfNoneInProgress(activity, "Stopped").addEvent("activityPreStopped"); - } - - @Override - public void onActivityStopped(@NonNull Activity activity) { - tracers.addEvent(activity, "activityStopped"); - } - - @Override - public void onActivityPostStopped(@NonNull Activity activity) { - tracers.addEvent(activity, "activityPostStopped").endActiveSpan(); - } - - @Override - public void onActivityPreDestroyed(@NonNull Activity activity) { - tracers.startSpanIfNoneInProgress(activity, "Destroyed").addEvent("activityPreDestroyed"); - } - - @Override - public void onActivityDestroyed(@NonNull Activity activity) { - tracers.addEvent(activity, "activityDestroyed"); - } - - @Override - public void onActivityPostDestroyed(@NonNull Activity activity) { - tracers.addEvent(activity, "activityPostDestroyed").endActiveSpan(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracer.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracer.java deleted file mode 100644 index d77928ca..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracer.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static io.opentelemetry.rum.internal.RumConstants.APP_START_SPAN_NAME; -import static io.opentelemetry.rum.internal.RumConstants.SCREEN_NAME_KEY; -import static io.opentelemetry.rum.internal.RumConstants.START_TYPE_KEY; - -import android.app.Activity; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanBuilder; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.context.Context; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; -import io.opentelemetry.rum.internal.util.ActiveSpan; -import java.util.concurrent.atomic.AtomicReference; - -public class ActivityTracer { - static final AttributeKey ACTIVITY_NAME_KEY = AttributeKey.stringKey("activityName"); - - private final AtomicReference initialAppActivity; - private final Tracer tracer; - private final String activityName; - private final String screenName; - private final AppStartupTimer appStartupTimer; - private final ActiveSpan activeSpan; - - private ActivityTracer(Builder builder) { - this.initialAppActivity = builder.initialAppActivity; - this.tracer = builder.tracer; - this.activityName = builder.getActivityName(); - this.screenName = builder.screenName; - this.appStartupTimer = builder.appStartupTimer; - this.activeSpan = builder.activeSpan; - } - - ActivityTracer startSpanIfNoneInProgress(String spanName) { - if (activeSpan.spanInProgress()) { - return this; - } - activeSpan.startSpan(() -> createSpan(spanName)); - return this; - } - - ActivityTracer startActivityCreation() { - activeSpan.startSpan(this::makeCreationSpan); - return this; - } - - private Span makeCreationSpan() { - // If the application has never loaded an activity, or this is the initial activity getting - // re-created, - // we name this span specially to show that it's the application starting up. Otherwise, use - // the activity class name as the base of the span name. - boolean isColdStart = initialAppActivity.get() == null; - if (isColdStart) { - return createSpanWithParent("Created", appStartupTimer.getStartupSpan()); - } - if (activityName.equals(initialAppActivity.get())) { - return createAppStartSpan("warm"); - } - return createSpan("Created"); - } - - ActivityTracer initiateRestartSpanIfNecessary(boolean multiActivityApp) { - if (activeSpan.spanInProgress()) { - return this; - } - activeSpan.startSpan(() -> makeRestartSpan(multiActivityApp)); - return this; - } - - @NonNull - private Span makeRestartSpan(boolean multiActivityApp) { - // restarting the first activity is a "hot" AppStart - // Note: in a multi-activity application, navigating back to the first activity can trigger - // this, so it would not be ideal to call it an AppStart. - if (!multiActivityApp && activityName.equals(initialAppActivity.get())) { - return createAppStartSpan("hot"); - } - return createSpan("Restarted"); - } - - private Span createAppStartSpan(String startType) { - Span span = createSpan(APP_START_SPAN_NAME); - span.setAttribute(START_TYPE_KEY, startType); - return span; - } - - private Span createSpan(String spanName) { - return createSpanWithParent(spanName, null); - } - - private Span createSpanWithParent(String spanName, @Nullable Span parentSpan) { - final SpanBuilder spanBuilder = - tracer.spanBuilder(spanName).setAttribute(ACTIVITY_NAME_KEY, activityName); - if (parentSpan != null) { - spanBuilder.setParent(parentSpan.storeInContext(Context.current())); - } - Span span = spanBuilder.startSpan(); - // do this after the span is started, so we can override the default screen.name set by the - // RumAttributeAppender. - span.setAttribute(SCREEN_NAME_KEY, screenName); - return span; - } - - public void endSpanForActivityResumed() { - if (initialAppActivity.get() == null) { - initialAppActivity.set(activityName); - } - endActiveSpan(); - } - - public void endActiveSpan() { - // If we happen to be in app startup, make sure this ends it. It's harmless if we're already - // out of the startup phase. - appStartupTimer.end(); - activeSpan.endActiveSpan(); - } - - public ActivityTracer addPreviousScreenAttribute() { - activeSpan.addPreviousScreenAttribute(activityName); - return this; - } - - public ActivityTracer addEvent(String eventName) { - activeSpan.addEvent(eventName); - return this; - } - - public static Builder builder(Activity activity) { - return new Builder(activity); - } - - static class Builder { - private static final ActiveSpan INVALID_ACTIVE_SPAN = new ActiveSpan(() -> null); - private static final Tracer INVALID_TRACER = spanName -> null; - private static final AppStartupTimer INVALID_TIMER = new AppStartupTimer(); - private final Activity activity; - public String screenName = "unknown_screen"; - private AtomicReference initialAppActivity = new AtomicReference<>(); - private Tracer tracer = INVALID_TRACER; - private AppStartupTimer appStartupTimer = INVALID_TIMER; - private ActiveSpan activeSpan = INVALID_ACTIVE_SPAN; - - public Builder(Activity activity) { - this.activity = activity; - } - - public Builder setVisibleScreenTracker(VisibleScreenTracker visibleScreenTracker) { - this.activeSpan = new ActiveSpan(visibleScreenTracker::getPreviouslyVisibleScreen); - return this; - } - - public Builder setInitialAppActivity(String activityName) { - initialAppActivity.set(activityName); - return this; - } - - public Builder setInitialAppActivity(AtomicReference initialAppActivity) { - this.initialAppActivity = initialAppActivity; - return this; - } - - public Builder setTracer(Tracer tracer) { - this.tracer = tracer; - return this; - } - - public Builder setAppStartupTimer(AppStartupTimer appStartupTimer) { - this.appStartupTimer = appStartupTimer; - return this; - } - - public Builder setActiveSpan(ActiveSpan activeSpan) { - this.activeSpan = activeSpan; - return this; - } - - private String getActivityName() { - return activity.getClass().getSimpleName(); - } - - public Builder setScreenName(String screenName) { - this.screenName = screenName; - return this; - } - - public ActivityTracer build() { - if (activeSpan == INVALID_ACTIVE_SPAN) { - throw new IllegalStateException("activeSpan must be configured."); - } - if (tracer == INVALID_TRACER) { - throw new IllegalStateException("tracer must be configured."); - } - if (appStartupTimer == INVALID_TIMER) { - throw new IllegalStateException("appStartupTimer must be configured."); - } - return new ActivityTracer(this); - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerCache.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerCache.java deleted file mode 100644 index 372e4241..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerCache.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import android.app.Activity; -import androidx.annotation.VisibleForTesting; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.ScreenNameExtractor; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; - -/** - * Encapsulates the fact that we have an ActivityTracer instance per Activity class, and provides - * convenience methods for adding events and starting spans. - */ -public class ActivityTracerCache { - - private final Map tracersByActivityClassName = new HashMap<>(); - - private final Function tracerFactory; - - public ActivityTracerCache( - Tracer tracer, - VisibleScreenTracker visibleScreenTracker, - AppStartupTimer startupTimer, - ScreenNameExtractor screenNameExtractor) { - this( - tracer, - visibleScreenTracker, - new AtomicReference<>(), - startupTimer, - screenNameExtractor); - } - - @VisibleForTesting - ActivityTracerCache( - Tracer tracer, - VisibleScreenTracker visibleScreenTracker, - AtomicReference initialAppActivity, - AppStartupTimer startupTimer, - ScreenNameExtractor screenNameExtractor) { - this( - activity -> - ActivityTracer.builder(activity) - .setScreenName(screenNameExtractor.extract(activity)) - .setInitialAppActivity(initialAppActivity) - .setTracer(tracer) - .setAppStartupTimer(startupTimer) - .setVisibleScreenTracker(visibleScreenTracker) - .build()); - } - - @VisibleForTesting - ActivityTracerCache(Function tracerFactory) { - this.tracerFactory = tracerFactory; - } - - public ActivityTracer addEvent(Activity activity, String eventName) { - return getTracer(activity).addEvent(eventName); - } - - public ActivityTracer startSpanIfNoneInProgress(Activity activity, String spanName) { - return getTracer(activity).startSpanIfNoneInProgress(spanName); - } - - public ActivityTracer initiateRestartSpanIfNecessary(Activity activity) { - boolean isMultiActivityApp = tracersByActivityClassName.size() > 1; - return getTracer(activity).initiateRestartSpanIfNecessary(isMultiActivityApp); - } - - public ActivityTracer startActivityCreation(Activity activity) { - return getTracer(activity).startActivityCreation(); - } - - private ActivityTracer getTracer(Activity activity) { - ActivityTracer activityTracer = - tracersByActivityClassName.get(activity.getClass().getName()); - if (activityTracer == null) { - activityTracer = tracerFactory.apply(activity); - tracersByActivityClassName.put(activity.getClass().getName(), activityTracer); - } - return activityTracer; - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityCallbacks.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityCallbacks.java deleted file mode 100644 index 60f033bc..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityCallbacks.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import android.app.Activity; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import io.opentelemetry.rum.internal.DefaultingActivityLifecycleCallbacks; - -public class Pre29ActivityCallbacks implements DefaultingActivityLifecycleCallbacks { - private final ActivityTracerCache tracers; - - public Pre29ActivityCallbacks(ActivityTracerCache tracers) { - this.tracers = tracers; - } - - @Override - public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { - tracers.startActivityCreation(activity).addEvent("activityCreated"); - } - - @Override - public void onActivityStarted(@NonNull Activity activity) { - tracers.initiateRestartSpanIfNecessary(activity).addEvent("activityStarted"); - } - - @Override - public void onActivityResumed(@NonNull Activity activity) { - tracers.startSpanIfNoneInProgress(activity, "Resumed") - .addEvent("activityResumed") - .addPreviousScreenAttribute() - .endSpanForActivityResumed(); - } - - @Override - public void onActivityPaused(@NonNull Activity activity) { - tracers.startSpanIfNoneInProgress(activity, "Paused") - .addEvent("activityPaused") - .endActiveSpan(); - } - - @Override - public void onActivityStopped(@NonNull Activity activity) { - tracers.startSpanIfNoneInProgress(activity, "Stopped") - .addEvent("activityStopped") - .endActiveSpan(); - } - - @Override - public void onActivityDestroyed(@NonNull Activity activity) { - tracers.startSpanIfNoneInProgress(activity, "Destroyed") - .addEvent("activityDestroyed") - .endActiveSpan(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29VisibleScreenLifecycleBinding.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29VisibleScreenLifecycleBinding.java deleted file mode 100644 index 4b8c0c4c..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29VisibleScreenLifecycleBinding.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import android.app.Activity; -import androidx.annotation.NonNull; -import io.opentelemetry.rum.internal.DefaultingActivityLifecycleCallbacks; - -/** - * An ActivityLifecycleCallbacks that is responsible for telling the VisibleScreenTracker when an - * activity has been resumed and when an activity has been paused. It's just a glue class designed - * for API level before 29. - */ -public class Pre29VisibleScreenLifecycleBinding implements DefaultingActivityLifecycleCallbacks { - - private final VisibleScreenTracker visibleScreenTracker; - - public Pre29VisibleScreenLifecycleBinding(VisibleScreenTracker visibleScreenTracker) { - this.visibleScreenTracker = visibleScreenTracker; - } - - @Override - public void onActivityResumed(@NonNull Activity activity) { - visibleScreenTracker.activityResumed(activity); - } - - @Override - public void onActivityPaused(@NonNull Activity activity) { - visibleScreenTracker.activityPaused(activity); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/RumFragmentActivityRegisterer.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/RumFragmentActivityRegisterer.java deleted file mode 100644 index b4f10450..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/RumFragmentActivityRegisterer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import android.app.Activity; -import android.app.Application; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; -import io.opentelemetry.rum.internal.DefaultingActivityLifecycleCallbacks; - -/** - * Registers the RumFragmentLifecycleCallbacks when an activity is created. There are just 2 factory - * methods here, one for API level before 29, and one for the rest. - */ -public class RumFragmentActivityRegisterer { - - private RumFragmentActivityRegisterer() {} - - public static Application.ActivityLifecycleCallbacks create( - FragmentManager.FragmentLifecycleCallbacks fragmentCallbacks) { - return new DefaultingActivityLifecycleCallbacks() { - @Override - public void onActivityPreCreated( - @NonNull Activity activity, @Nullable Bundle savedInstanceState) { - if (activity instanceof FragmentActivity) { - register((FragmentActivity) activity, fragmentCallbacks); - } - } - }; - } - - public static Application.ActivityLifecycleCallbacks createPre29( - FragmentManager.FragmentLifecycleCallbacks fragmentCallbacks) { - return new DefaultingActivityLifecycleCallbacks() { - @Override - public void onActivityCreated( - @NonNull Activity activity, @Nullable Bundle savedInstanceState) { - if (activity instanceof FragmentActivity) { - register((FragmentActivity) activity, fragmentCallbacks); - } - } - }; - } - - private static void register( - FragmentActivity activity, - FragmentManager.FragmentLifecycleCallbacks fragmentCallbacks) { - FragmentManager fragmentManager = activity.getSupportFragmentManager(); - fragmentManager.registerFragmentLifecycleCallbacks(fragmentCallbacks, true); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenLifecycleBinding.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenLifecycleBinding.java deleted file mode 100644 index bbfa8930..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenLifecycleBinding.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import android.app.Activity; -import androidx.annotation.NonNull; -import io.opentelemetry.rum.internal.DefaultingActivityLifecycleCallbacks; - -/** - * An ActivityLifecycleCallbacks that is responsible for telling the VisibleScreenTracker when an - * activity has been resumed and when an activity has been paused. It's just a glue class. - */ -public class VisibleScreenLifecycleBinding implements DefaultingActivityLifecycleCallbacks { - - private final VisibleScreenTracker visibleScreenTracker; - - public VisibleScreenLifecycleBinding(VisibleScreenTracker visibleScreenTracker) { - this.visibleScreenTracker = visibleScreenTracker; - } - - @Override - public void onActivityPostResumed(@NonNull Activity activity) { - visibleScreenTracker.activityResumed(activity); - } - - @Override - public void onActivityPrePaused(@NonNull Activity activity) { - visibleScreenTracker.activityPaused(activity); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenTracker.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenTracker.java deleted file mode 100644 index 87fa24d3..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenTracker.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import android.app.Activity; -import androidx.annotation.Nullable; -import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; -import androidx.navigation.fragment.NavHostFragment; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Wherein we do our best to figure out what "screen" is visible and what was the previously visible - * "screen". - * - *

In general, we favor using the last fragment that was resumed, but fall back to the last - * resumed activity in case we don't have a fragment. - * - *

We always ignore NavHostFragment instances since they aren't ever visible to the user. - * - *

We have to treat DialogFragments slightly differently since they don't replace the launching - * screen, and the launching screen never leaves visibility. - */ -public class VisibleScreenTracker { - private final AtomicReference lastResumedActivity = new AtomicReference<>(); - private final AtomicReference previouslyLastResumedActivity = new AtomicReference<>(); - private final AtomicReference lastResumedFragment = new AtomicReference<>(); - private final AtomicReference previouslyLastResumedFragment = new AtomicReference<>(); - - @Nullable - public String getPreviouslyVisibleScreen() { - String previouslyLastFragment = previouslyLastResumedFragment.get(); - if (previouslyLastFragment != null) { - return previouslyLastFragment; - } - return previouslyLastResumedActivity.get(); - } - - public String getCurrentlyVisibleScreen() { - String lastFragment = lastResumedFragment.get(); - if (lastFragment != null) { - return lastFragment; - } - String lastActivity = lastResumedActivity.get(); - if (lastActivity != null) { - return lastActivity; - } - return "unknown"; - } - - public void activityResumed(Activity activity) { - lastResumedActivity.set(activity.getClass().getSimpleName()); - } - - public void activityPaused(Activity activity) { - previouslyLastResumedActivity.set(activity.getClass().getSimpleName()); - lastResumedActivity.compareAndSet(activity.getClass().getSimpleName(), null); - } - - public void fragmentResumed(Fragment fragment) { - // skip the NavHostFragment since it's never really "visible" by itself. - if (fragment instanceof NavHostFragment) { - return; - } - - if (fragment instanceof DialogFragment) { - previouslyLastResumedFragment.set(lastResumedFragment.get()); - } - lastResumedFragment.set(fragment.getClass().getSimpleName()); - } - - public void fragmentPaused(Fragment fragment) { - // skip the NavHostFragment since it's never really "visible" by itself. - if (fragment instanceof NavHostFragment) { - return; - } - if (fragment instanceof DialogFragment) { - lastResumedFragment.set(previouslyLastResumedFragment.get()); - } else { - lastResumedFragment.compareAndSet(fragment.getClass().getSimpleName(), null); - } - previouslyLastResumedFragment.set(fragment.getClass().getSimpleName()); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetector.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetector.java deleted file mode 100644 index 469e48f3..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetector.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.anr; - -import android.os.Handler; -import android.os.Looper; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.trace.StatusCode; -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import java.util.List; -import java.util.concurrent.ScheduledExecutorService; - -/** Entrypoint for installing the ANR (application not responding) detection instrumentation. */ -public final class AnrDetector { - - /** Returns a new {@link AnrDetector} with the default settings. */ - public static AnrDetector create() { - return builder().build(); - } - - /** Returns a new {@link AnrDetectorBuilder}. */ - public static AnrDetectorBuilder builder() { - return new AnrDetectorBuilder(); - } - - private final List> additionalExtractors; - private final Looper mainLooper; - private final ScheduledExecutorService scheduler; - - AnrDetector(AnrDetectorBuilder builder) { - this.additionalExtractors = builder.additionalExtractors; - this.mainLooper = builder.mainLooper; - this.scheduler = builder.scheduler; - } - - /** - * Installs the ANR detection instrumentation on the given {@link InstrumentedApplication}. - * - *

When the main thread is unresponsive for 5 seconds or more, an event including the main - * thread's stack trace will be reported to the RUM system. - */ - public void installOn(InstrumentedApplication instrumentedApplication) { - Handler uiHandler = new Handler(mainLooper); - AnrWatcher anrWatcher = - new AnrWatcher( - uiHandler, - mainLooper.getThread(), - buildAnrInstrumenter(instrumentedApplication.getOpenTelemetrySdk())); - - AnrDetectorToggler listener = new AnrDetectorToggler(anrWatcher, scheduler); - // call it manually the first time to enable the ANR detection - listener.onApplicationForegrounded(); - - instrumentedApplication.registerApplicationStateListener(listener); - } - - private Instrumenter buildAnrInstrumenter( - OpenTelemetry openTelemetry) { - return Instrumenter.builder( - openTelemetry, "io.opentelemetry.anr", stackTrace -> "ANR") - // it's always an error - .setSpanStatusExtractor( - (spanStatusBuilder, stackTrace, unused, error) -> - spanStatusBuilder.setStatus(StatusCode.ERROR)) - .addAttributesExtractor(new StackTraceFormatter()) - .addAttributesExtractors(additionalExtractors) - .buildInstrumenter(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorBuilder.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorBuilder.java deleted file mode 100644 index 7cd00e95..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorBuilder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.anr; - -import android.os.Looper; -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - -/** A builder of {@link AnrDetector}. */ -public final class AnrDetectorBuilder { - - AnrDetectorBuilder() {} - - final List> additionalExtractors = - new ArrayList<>(); - Looper mainLooper = Looper.getMainLooper(); - ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - - /** Adds an {@link AttributesExtractor} that will extract additional attributes. */ - public AnrDetectorBuilder addAttributesExtractor( - AttributesExtractor extractor) { - additionalExtractors.add(extractor); - return this; - } - - /** Sets a custom {@link Looper} to run on. Useful for testing. */ - public AnrDetectorBuilder setMainLooper(Looper looper) { - mainLooper = looper; - return this; - } - - // visible for tests - AnrDetectorBuilder setScheduler(ScheduledExecutorService scheduler) { - this.scheduler = scheduler; - return this; - } - - /** Returns a new {@link AnrDetector} with the settings of this {@link AnrDetectorBuilder}. */ - public AnrDetector build() { - return new AnrDetector(this); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorToggler.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorToggler.java deleted file mode 100644 index f28d012c..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorToggler.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.anr; - -import androidx.annotation.Nullable; -import io.opentelemetry.rum.internal.instrumentation.ApplicationStateListener; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -final class AnrDetectorToggler implements ApplicationStateListener { - - private final Runnable anrWatcher; - private final ScheduledExecutorService anrScheduler; - - @Nullable private ScheduledFuture future; - - AnrDetectorToggler(Runnable anrWatcher, ScheduledExecutorService anrScheduler) { - this.anrWatcher = anrWatcher; - this.anrScheduler = anrScheduler; - } - - @Override - public void onApplicationForegrounded() { - if (future == null) { - future = anrScheduler.scheduleAtFixedRate(anrWatcher, 1, 1, TimeUnit.SECONDS); - } - } - - @Override - public void onApplicationBackgrounded() { - if (future != null) { - future.cancel(true); - future = null; - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrWatcher.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrWatcher.java deleted file mode 100644 index d4abf0ca..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrWatcher.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.anr; - -import android.os.Handler; -import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -final class AnrWatcher implements Runnable { - private final AtomicInteger anrCounter = new AtomicInteger(); - private final Handler uiHandler; - private final Thread mainThread; - private final Instrumenter instrumenter; - - AnrWatcher( - Handler uiHandler, - Thread mainThread, - Instrumenter instrumenter) { - this.uiHandler = uiHandler; - this.mainThread = mainThread; - this.instrumenter = instrumenter; - } - - @Override - public void run() { - CountDownLatch response = new CountDownLatch(1); - if (!uiHandler.post(response::countDown)) { - // the main thread is probably shutting down. ignore and return. - return; - } - boolean success; - try { - success = response.await(1, TimeUnit.SECONDS); - } catch (InterruptedException e) { - return; - } - if (success) { - anrCounter.set(0); - return; - } - if (anrCounter.incrementAndGet() >= 5) { - StackTraceElement[] stackTrace = mainThread.getStackTrace(); - recordAnr(stackTrace); - // only report once per 5s. - anrCounter.set(0); - } - } - - private void recordAnr(StackTraceElement[] stackTrace) { - Context context = instrumenter.start(Context.current(), stackTrace); - instrumenter.end(context, stackTrace, null, null); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/StackTraceFormatter.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/StackTraceFormatter.java deleted file mode 100644 index dfd7d945..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/StackTraceFormatter.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.anr; - -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; - -final class StackTraceFormatter implements AttributesExtractor { - - @Override - public void onStart( - AttributesBuilder attributes, Context parentContext, StackTraceElement[] stackTrace) { - StringBuilder stackTraceString = new StringBuilder(); - for (StackTraceElement stackTraceElement : stackTrace) { - stackTraceString.append(stackTraceElement).append("\n"); - } - attributes.put(SemanticAttributes.EXCEPTION_STACKTRACE, stackTraceString.toString()); - } - - @Override - public void onEnd( - AttributesBuilder attributes, - Context context, - StackTraceElement[] stackTraceElements, - Void unused, - Throwable error) {} -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashDetails.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashDetails.java deleted file mode 100644 index 98d7446e..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashDetails.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.crash; - -/** A class representing all the details of an application crash. */ -public final class CrashDetails { - - /** Creates a new {@link CrashDetails} instance. */ - public static CrashDetails create(Thread thread, Throwable cause) { - return new CrashDetails(thread, cause); - } - - private final Thread thread; - private final Throwable cause; - - CrashDetails(Thread thread, Throwable cause) { - this.thread = thread; - this.cause = cause; - } - - /** Returns the thread that crashed. */ - public Thread getThread() { - return thread; - } - - /** Returns the cause of the crash. */ - public Throwable getCause() { - return cause; - } - - String spanName() { - return getCause().getClass().getSimpleName(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CrashDetails that = (CrashDetails) o; - - if (!thread.equals(that.thread)) return false; - return cause.equals(that.cause); - } - - @Override - public int hashCode() { - int result = thread.hashCode(); - result = 31 * result + cause.hashCode(); - return result; - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashDetailsAttributesExtractor.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashDetailsAttributesExtractor.java deleted file mode 100644 index d2eb97af..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashDetailsAttributesExtractor.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.crash; - -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; - -final class CrashDetailsAttributesExtractor implements AttributesExtractor { - - @Override - public void onStart( - AttributesBuilder attributes, Context parentContext, CrashDetails crashDetails) { - attributes.put(SemanticAttributes.THREAD_ID, crashDetails.getThread().getId()); - attributes.put(SemanticAttributes.THREAD_NAME, crashDetails.getThread().getName()); - attributes.put(SemanticAttributes.EXCEPTION_ESCAPED, true); - } - - @Override - public void onEnd( - AttributesBuilder attributes, - Context context, - CrashDetails crashDetails, - Void unused, - Throwable error) {} -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporter.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporter.java deleted file mode 100644 index 4c23724f..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporter.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.crash; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import java.util.List; - -/** Entrypoint for installing the crash reporting instrumentation. */ -public final class CrashReporter { - - /** Returns a new {@link CrashReporter} with the default settings. */ - public static CrashReporter create() { - return builder().build(); - } - - /** Returns a new {@link CrashReporterBuilder}. */ - public static CrashReporterBuilder builder() { - return new CrashReporterBuilder(); - } - - private final List> additionalExtractors; - - CrashReporter(CrashReporterBuilder builder) { - this.additionalExtractors = builder.additionalExtractors; - } - - /** - * Installs the crash reporting instrumentation on the given {@link InstrumentedApplication}. - */ - public void installOn(InstrumentedApplication instrumentedApplication) { - Thread.UncaughtExceptionHandler existingHandler = - Thread.getDefaultUncaughtExceptionHandler(); - Thread.setDefaultUncaughtExceptionHandler( - new CrashReportingExceptionHandler( - buildInstrumenter(instrumentedApplication.getOpenTelemetrySdk()), - instrumentedApplication.getOpenTelemetrySdk().getSdkTracerProvider(), - existingHandler)); - } - - private Instrumenter buildInstrumenter(OpenTelemetry openTelemetry) { - return Instrumenter.builder( - openTelemetry, "io.opentelemetry.crash", CrashDetails::spanName) - .addAttributesExtractor(new CrashDetailsAttributesExtractor()) - .addAttributesExtractors(additionalExtractors) - .buildInstrumenter(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporterBuilder.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporterBuilder.java deleted file mode 100644 index 49e11921..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporterBuilder.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.crash; - -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import java.util.ArrayList; -import java.util.List; - -/** A builder of {@link CrashReporter}. */ -public final class CrashReporterBuilder { - - CrashReporterBuilder() {} - - final List> additionalExtractors = new ArrayList<>(); - - /** Adds an {@link AttributesExtractor} that will extract additional attributes. */ - public CrashReporterBuilder addAttributesExtractor( - AttributesExtractor extractor) { - additionalExtractors.add(extractor); - return this; - } - - /** - * Returns a new {@link CrashReporter} with the settings of this {@link CrashReporterBuilder}. - */ - public CrashReporter build() { - return new CrashReporter(this); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReportingExceptionHandler.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReportingExceptionHandler.java deleted file mode 100644 index 709af643..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReportingExceptionHandler.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.crash; - -import androidx.annotation.NonNull; -import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import java.util.concurrent.TimeUnit; - -final class CrashReportingExceptionHandler implements Thread.UncaughtExceptionHandler { - - private final Instrumenter instrumenter; - private final SdkTracerProvider sdkTracerProvider; - private final Thread.UncaughtExceptionHandler existingHandler; - - CrashReportingExceptionHandler( - Instrumenter instrumenter, - SdkTracerProvider sdkTracerProvider, - Thread.UncaughtExceptionHandler existingHandler) { - this.instrumenter = instrumenter; - this.sdkTracerProvider = sdkTracerProvider; - this.existingHandler = existingHandler; - } - - @Override - public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) { - reportCrash(t, e); - - // do our best to make sure the crash makes it out of the VM - CompletableResultCode flushResult = sdkTracerProvider.forceFlush(); - flushResult.join(10, TimeUnit.SECONDS); - - // preserve any existing behavior - if (existingHandler != null) { - existingHandler.uncaughtException(t, e); - } - } - - private void reportCrash(Thread t, Throwable e) { - CrashDetails crashDetails = CrashDetails.create(t, e); - Context context = instrumenter.start(Context.current(), crashDetails); - instrumenter.end(context, crashDetails, null, e); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentTracer.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentTracer.java deleted file mode 100644 index 2ccd8dbb..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentTracer.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.fragment; - -import androidx.fragment.app.Fragment; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.RumConstants; -import io.opentelemetry.rum.internal.util.ActiveSpan; - -class FragmentTracer { - static final AttributeKey FRAGMENT_NAME_KEY = AttributeKey.stringKey("fragmentName"); - - private final String fragmentName; - private final String screenName; - private final Tracer tracer; - private final ActiveSpan activeSpan; - - private FragmentTracer(Builder builder) { - this.tracer = builder.tracer; - this.fragmentName = builder.getFragmentName(); - this.screenName = builder.screenName; - this.activeSpan = builder.activeSpan; - } - - FragmentTracer startSpanIfNoneInProgress(String action) { - if (activeSpan.spanInProgress()) { - return this; - } - activeSpan.startSpan(() -> createSpan(action)); - return this; - } - - FragmentTracer startFragmentCreation() { - activeSpan.startSpan(() -> createSpan("Created")); - return this; - } - - private Span createSpan(String spanName) { - Span span = - tracer.spanBuilder(spanName) - .setAttribute(FRAGMENT_NAME_KEY, fragmentName) - .startSpan(); - // do this after the span is started, so we can override the default screen.name set by the - // RumAttributeAppender. - span.setAttribute(RumConstants.SCREEN_NAME_KEY, screenName); - return span; - } - - void endActiveSpan() { - activeSpan.endActiveSpan(); - } - - FragmentTracer addPreviousScreenAttribute() { - activeSpan.addPreviousScreenAttribute(fragmentName); - return this; - } - - FragmentTracer addEvent(String eventName) { - activeSpan.addEvent(eventName); - return this; - } - - static Builder builder(Fragment fragment) { - return new Builder(fragment); - } - - static class Builder { - private static final ActiveSpan INVALID_ACTIVE_SPAN = new ActiveSpan(() -> null); - private static final Tracer INVALID_TRACER = spanName -> null; - private final Fragment fragment; - public String screenName = ""; - private Tracer tracer = INVALID_TRACER; - private ActiveSpan activeSpan = INVALID_ACTIVE_SPAN; - - public Builder(Fragment fragment) { - this.fragment = fragment; - } - - Builder setTracer(Tracer tracer) { - this.tracer = tracer; - return this; - } - - public Builder setScreenName(String screenName) { - this.screenName = screenName; - return this; - } - - Builder setActiveSpan(ActiveSpan activeSpan) { - this.activeSpan = activeSpan; - return this; - } - - public String getFragmentName() { - return fragment.getClass().getSimpleName(); - } - - FragmentTracer build() { - if (activeSpan == INVALID_ACTIVE_SPAN) { - throw new IllegalStateException("activeSpan must be configured."); - } - if (tracer == INVALID_TRACER) { - throw new IllegalStateException("tracer must be configured."); - } - return new FragmentTracer(this); - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/fragment/RumFragmentLifecycleCallbacks.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/fragment/RumFragmentLifecycleCallbacks.java deleted file mode 100644 index a8c4184f..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/fragment/RumFragmentLifecycleCallbacks.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.fragment; - -import android.content.Context; -import android.os.Bundle; -import android.view.View; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.ScreenNameExtractor; -import io.opentelemetry.rum.internal.instrumentation.activity.VisibleScreenTracker; -import io.opentelemetry.rum.internal.util.ActiveSpan; -import java.util.HashMap; -import java.util.Map; - -public class RumFragmentLifecycleCallbacks extends FragmentManager.FragmentLifecycleCallbacks { - private final Map tracersByFragmentClassName = new HashMap<>(); - - private final Tracer tracer; - private final VisibleScreenTracker visibleScreenTracker; - private final ScreenNameExtractor screenNameExtractor; - - public RumFragmentLifecycleCallbacks( - Tracer tracer, - VisibleScreenTracker visibleScreenTracker, - ScreenNameExtractor screenNameExtractor) { - this.tracer = tracer; - this.visibleScreenTracker = visibleScreenTracker; - this.screenNameExtractor = screenNameExtractor; - } - - @Override - public void onFragmentPreAttached( - @NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) { - super.onFragmentPreAttached(fm, f, context); - getTracer(f).startFragmentCreation().addEvent("fragmentPreAttached"); - } - - @Override - public void onFragmentAttached( - @NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) { - super.onFragmentAttached(fm, f, context); - addEvent(f, "fragmentAttached"); - } - - @Override - public void onFragmentPreCreated( - @NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) { - super.onFragmentPreCreated(fm, f, savedInstanceState); - addEvent(f, "fragmentPreCreated"); - } - - @Override - public void onFragmentCreated( - @NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) { - super.onFragmentCreated(fm, f, savedInstanceState); - addEvent(f, "fragmentCreated"); - } - - @Override - public void onFragmentViewCreated( - @NonNull FragmentManager fm, - @NonNull Fragment f, - @NonNull View v, - @Nullable Bundle savedInstanceState) { - super.onFragmentViewCreated(fm, f, v, savedInstanceState); - getTracer(f).startSpanIfNoneInProgress("Restored").addEvent("fragmentViewCreated"); - } - - @Override - public void onFragmentStarted(@NonNull FragmentManager fm, @NonNull Fragment f) { - super.onFragmentStarted(fm, f); - addEvent(f, "fragmentStarted"); - } - - @Override - public void onFragmentResumed(@NonNull FragmentManager fm, @NonNull Fragment f) { - super.onFragmentResumed(fm, f); - getTracer(f) - .startSpanIfNoneInProgress("Resumed") - .addEvent("fragmentResumed") - .addPreviousScreenAttribute() - .endActiveSpan(); - visibleScreenTracker.fragmentResumed(f); - } - - @Override - public void onFragmentPaused(@NonNull FragmentManager fm, @NonNull Fragment f) { - super.onFragmentPaused(fm, f); - visibleScreenTracker.fragmentPaused(f); - getTracer(f).startSpanIfNoneInProgress("Paused").addEvent("fragmentPaused"); - } - - @Override - public void onFragmentStopped(@NonNull FragmentManager fm, @NonNull Fragment f) { - super.onFragmentStopped(fm, f); - getTracer(f).addEvent("fragmentStopped").endActiveSpan(); - } - - @Override - public void onFragmentSaveInstanceState( - @NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Bundle outState) { - super.onFragmentSaveInstanceState(fm, f, outState); - } - - @Override - public void onFragmentViewDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) { - super.onFragmentViewDestroyed(fm, f); - getTracer(f) - .startSpanIfNoneInProgress("ViewDestroyed") - .addEvent("fragmentViewDestroyed") - .endActiveSpan(); - } - - @Override - public void onFragmentDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) { - super.onFragmentDestroyed(fm, f); - // note: this might not get called if the dev has checked "retainInstance" on the fragment - getTracer(f).startSpanIfNoneInProgress("Destroyed").addEvent("fragmentDestroyed"); - } - - @Override - public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) { - super.onFragmentDetached(fm, f); - // this is a terminal operation, but might also be the only thing we see on app getting - // killed, so - getTracer(f) - .startSpanIfNoneInProgress("Detached") - .addEvent("fragmentDetached") - .endActiveSpan(); - } - - private void addEvent(@NonNull Fragment fragment, String eventName) { - FragmentTracer fragmentTracer = - tracersByFragmentClassName.get(fragment.getClass().getName()); - if (fragmentTracer != null) { - fragmentTracer.addEvent(eventName); - } - } - - private FragmentTracer getTracer(Fragment fragment) { - FragmentTracer activityTracer = - tracersByFragmentClassName.get(fragment.getClass().getName()); - if (activityTracer == null) { - activityTracer = - FragmentTracer.builder(fragment) - .setTracer(tracer) - .setScreenName(screenNameExtractor.extract(fragment)) - .setActiveSpan( - new ActiveSpan( - visibleScreenTracker::getPreviouslyVisibleScreen)) - .build(); - tracersByFragmentClassName.put(fragment.getClass().getName(), activityTracer); - } - return activityTracer; - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/lifecycle/AndroidLifecycleInstrumentation.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/lifecycle/AndroidLifecycleInstrumentation.java deleted file mode 100644 index 2440f252..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/lifecycle/AndroidLifecycleInstrumentation.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.lifecycle; - -import android.app.Application; -import android.os.Build; -import androidx.annotation.NonNull; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import io.opentelemetry.rum.internal.instrumentation.ScreenNameExtractor; -import io.opentelemetry.rum.internal.instrumentation.activity.ActivityCallbacks; -import io.opentelemetry.rum.internal.instrumentation.activity.ActivityTracerCache; -import io.opentelemetry.rum.internal.instrumentation.activity.Pre29ActivityCallbacks; -import io.opentelemetry.rum.internal.instrumentation.activity.Pre29VisibleScreenLifecycleBinding; -import io.opentelemetry.rum.internal.instrumentation.activity.RumFragmentActivityRegisterer; -import io.opentelemetry.rum.internal.instrumentation.activity.VisibleScreenLifecycleBinding; -import io.opentelemetry.rum.internal.instrumentation.activity.VisibleScreenTracker; -import io.opentelemetry.rum.internal.instrumentation.fragment.RumFragmentLifecycleCallbacks; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; -import java.util.function.Function; - -/** - * This is an umbrella instrumentation that covers several things: * startup timer callback is - * registered so that UI startup time can be measured - activity lifecycle callbacks are registered - * so that lifecycle events can be generated - activity lifecycle callback listener is registered to - * that will register a FragmentLifecycleCallbacks when appropriate - activity lifecycle callback - * listener is registered to dispatch events to the VisibleScreenTracker - */ -public class AndroidLifecycleInstrumentation { - - private static final String INSTRUMENTATION_SCOPE = "io.opentelemetry.lifecycle"; - private final AppStartupTimer startupTimer; - private final VisibleScreenTracker visibleScreenTracker; - - private final Function tracerCustomizer; - private final ScreenNameExtractor screenNameExtractor; - - AndroidLifecycleInstrumentation(AndroidLifecycleInstrumentationBuilder builder) { - this.startupTimer = builder.startupTimer; - this.visibleScreenTracker = builder.visibleScreenTracker; - this.tracerCustomizer = builder.tracerCustomizer; - this.screenNameExtractor = builder.screenNameExtractor; - } - - public static AndroidLifecycleInstrumentationBuilder builder() { - return new AndroidLifecycleInstrumentationBuilder(); - } - - public void installOn(InstrumentedApplication app) { - installStartupTimerInstrumentation(app); - installActivityLifecycleEventsInstrumentation(app); - installFragmentLifecycleInstrumentation(app); - installScreenTrackingInstrumentation(app); - } - - private void installStartupTimerInstrumentation(InstrumentedApplication app) { - app.getApplication() - .registerActivityLifecycleCallbacks(startupTimer.createLifecycleCallback()); - } - - private void installActivityLifecycleEventsInstrumentation(InstrumentedApplication app) { - Application.ActivityLifecycleCallbacks activityCallbacks = buildActivityEventsCallback(app); - app.getApplication().registerActivityLifecycleCallbacks(activityCallbacks); - } - - @NonNull - private Application.ActivityLifecycleCallbacks buildActivityEventsCallback( - InstrumentedApplication instrumentedApp) { - Tracer delegateTracer = - instrumentedApp.getOpenTelemetrySdk().getTracer(INSTRUMENTATION_SCOPE); - Tracer tracer = tracerCustomizer.apply(delegateTracer); - - ActivityTracerCache tracers = - new ActivityTracerCache( - tracer, visibleScreenTracker, startupTimer, screenNameExtractor); - if (Build.VERSION.SDK_INT < 29) { - return new Pre29ActivityCallbacks(tracers); - } - return new ActivityCallbacks(tracers); - } - - private void installFragmentLifecycleInstrumentation(InstrumentedApplication app) { - Application.ActivityLifecycleCallbacks fragmentRegisterer = buildFragmentRegisterer(app); - app.getApplication().registerActivityLifecycleCallbacks(fragmentRegisterer); - } - - @NonNull - private Application.ActivityLifecycleCallbacks buildFragmentRegisterer( - InstrumentedApplication app) { - - Tracer delegateTracer = app.getOpenTelemetrySdk().getTracer(INSTRUMENTATION_SCOPE); - Tracer tracer = tracerCustomizer.apply(delegateTracer); - RumFragmentLifecycleCallbacks fragmentLifecycle = - new RumFragmentLifecycleCallbacks( - tracer, visibleScreenTracker, screenNameExtractor); - if (Build.VERSION.SDK_INT < 29) { - return RumFragmentActivityRegisterer.createPre29(fragmentLifecycle); - } - return RumFragmentActivityRegisterer.create(fragmentLifecycle); - } - - private void installScreenTrackingInstrumentation(InstrumentedApplication app) { - Application.ActivityLifecycleCallbacks screenTrackingBinding = - buildScreenTrackingBinding(visibleScreenTracker); - app.getApplication().registerActivityLifecycleCallbacks(screenTrackingBinding); - } - - @NonNull - private Application.ActivityLifecycleCallbacks buildScreenTrackingBinding( - VisibleScreenTracker visibleScreenTracker) { - if (Build.VERSION.SDK_INT < 29) { - return new Pre29VisibleScreenLifecycleBinding(visibleScreenTracker); - } - return new VisibleScreenLifecycleBinding(visibleScreenTracker); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/lifecycle/AndroidLifecycleInstrumentationBuilder.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/lifecycle/AndroidLifecycleInstrumentationBuilder.java deleted file mode 100644 index 03733d63..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/lifecycle/AndroidLifecycleInstrumentationBuilder.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.lifecycle; - -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.ScreenNameExtractor; -import io.opentelemetry.rum.internal.instrumentation.activity.VisibleScreenTracker; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; -import java.util.function.Function; - -public class AndroidLifecycleInstrumentationBuilder { - private static final VisibleScreenTracker INVALID_SCREEN_TRACKER = new VisibleScreenTracker(); - private static final AppStartupTimer INVALID_TIMER = new AppStartupTimer(); - ScreenNameExtractor screenNameExtractor = ScreenNameExtractor.DEFAULT; - AppStartupTimer startupTimer = INVALID_TIMER; - VisibleScreenTracker visibleScreenTracker = INVALID_SCREEN_TRACKER; - Function tracerCustomizer = Function.identity(); - - public AndroidLifecycleInstrumentationBuilder setStartupTimer(AppStartupTimer timer) { - this.startupTimer = timer; - return this; - } - - public AndroidLifecycleInstrumentationBuilder setVisibleScreenTracker( - VisibleScreenTracker tracker) { - this.visibleScreenTracker = tracker; - return this; - } - - public AndroidLifecycleInstrumentationBuilder setTracerCustomizer( - Function customizer) { - this.tracerCustomizer = customizer; - return this; - } - - public AndroidLifecycleInstrumentationBuilder setScreenNameExtractor( - ScreenNameExtractor screenNameExtractor) { - this.screenNameExtractor = screenNameExtractor; - return this; - } - - public AndroidLifecycleInstrumentation build() { - if (visibleScreenTracker == INVALID_SCREEN_TRACKER) { - throw new IllegalStateException("visibleScreenTracker must be configured."); - } - if (startupTimer == INVALID_TIMER) { - throw new IllegalStateException("startupTimer must be configured."); - } - return new AndroidLifecycleInstrumentation(this); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/Carrier.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/Carrier.java deleted file mode 100644 index a6f61d29..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/Carrier.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import android.os.Build; -import android.telephony.TelephonyManager; -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import java.util.Objects; - -@RequiresApi(api = Build.VERSION_CODES.P) -final class Carrier { - - private final int id; - private final @Nullable String name; - private final @Nullable String mobileCountryCode; // 3 digits - private final @Nullable String mobileNetworkCode; // 2 or 3 digits - private final @Nullable String isoCountryCode; - - static Builder builder() { - return new Builder(); - } - - Carrier(Builder builder) { - this.id = builder.id; - this.name = builder.name; - this.mobileCountryCode = builder.mobileCountryCode; - this.mobileNetworkCode = builder.mobileNetworkCode; - this.isoCountryCode = builder.isoCountryCode; - } - - int getId() { - return id; - } - - @Nullable - String getName() { - return name; - } - - @Nullable - String getMobileCountryCode() { - return mobileCountryCode; - } - - @Nullable - String getMobileNetworkCode() { - return mobileNetworkCode; - } - - @Nullable - String getIsoCountryCode() { - return isoCountryCode; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Carrier carrier = (Carrier) o; - return id == carrier.id - && Objects.equals(name, carrier.name) - && Objects.equals(mobileCountryCode, carrier.mobileCountryCode) - && Objects.equals(mobileNetworkCode, carrier.mobileNetworkCode) - && Objects.equals(isoCountryCode, carrier.isoCountryCode); - } - - @Override - public int hashCode() { - return Objects.hash(id, name, mobileCountryCode, mobileNetworkCode, isoCountryCode); - } - - @Override - public String toString() { - return "Carrier{" - + "id=" - + id - + ", name='" - + name - + '\'' - + ", mobileCountryCode='" - + mobileCountryCode - + '\'' - + ", mobileNetworkCode='" - + mobileNetworkCode - + '\'' - + ", isoCountryCode='" - + isoCountryCode - + '\'' - + '}'; - } - - static class Builder { - private int id = TelephonyManager.UNKNOWN_CARRIER_ID; - private @Nullable String name = null; - private @Nullable String mobileCountryCode = null; - private @Nullable String mobileNetworkCode = null; - private @Nullable String isoCountryCode = null; - - Carrier build() { - return new Carrier(this); - } - - Builder id(int id) { - this.id = id; - return this; - } - - Builder name(String name) { - this.name = name; - return this; - } - - Builder mobileCountryCode(String countryCode) { - this.mobileCountryCode = countryCode; - return this; - } - - Builder mobileNetworkCode(String networkCode) { - this.mobileNetworkCode = networkCode; - return this; - } - - Builder isoCountryCode(String isoCountryCode) { - this.isoCountryCode = isoCountryCode; - return this; - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CarrierFinder.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CarrierFinder.java deleted file mode 100644 index 23ca02a8..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CarrierFinder.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import android.os.Build; -import android.telephony.TelephonyManager; -import androidx.annotation.RequiresApi; - -@RequiresApi(api = Build.VERSION_CODES.P) -class CarrierFinder { - - private final TelephonyManager telephonyManager; - - CarrierFinder(TelephonyManager telephonyManager) { - this.telephonyManager = telephonyManager; - } - - Carrier get() { - Carrier.Builder builder = Carrier.builder(); - int id = telephonyManager.getSimCarrierId(); - builder.id(id); - CharSequence name = telephonyManager.getSimCarrierIdName(); - if (validString(name)) { - builder.name(name.toString()); - } - String simOperator = telephonyManager.getSimOperator(); - if (validString(simOperator) && simOperator.length() >= 5) { - String countryCode = simOperator.substring(0, 3); - String networkCode = simOperator.substring(3); - builder.mobileCountryCode(countryCode).mobileNetworkCode(networkCode); - } - String isoCountryCode = telephonyManager.getSimCountryIso(); - if (validString(isoCountryCode)) { - builder.isoCountryCode(isoCountryCode); - } - return builder.build(); - } - - private boolean validString(CharSequence str) { - return !(str == null || str.length() == 0); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetwork.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetwork.java deleted file mode 100644 index 4a7ab9d5..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetwork.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import android.os.Build; -import androidx.annotation.Nullable; -import java.util.Objects; - -/** A value class representing the current network that the device is connected to. */ -public final class CurrentNetwork { - - @Nullable private final Carrier carrier; - private final NetworkState state; - @Nullable private final String subType; - - private CurrentNetwork(Builder builder) { - this.carrier = builder.carrier; - this.state = builder.state; - this.subType = builder.subType; - } - - /** Returns {@code true} if the device has internet connection; {@code false} otherwise. */ - public boolean isOnline() { - return getState() != NetworkState.NO_NETWORK_AVAILABLE; - } - - NetworkState getState() { - return state; - } - - @Nullable - String getSubType() { - return subType; - } - - @SuppressWarnings("NullAway") - @Nullable - String getCarrierCountryCode() { - return haveCarrier() ? carrier.getMobileCountryCode() : null; - } - - @SuppressWarnings("NullAway") - @Nullable - String getCarrierIsoCountryCode() { - return haveCarrier() ? carrier.getIsoCountryCode() : null; - } - - @SuppressWarnings("NullAway") - @Nullable - String getCarrierNetworkCode() { - return haveCarrier() ? carrier.getMobileNetworkCode() : null; - } - - @SuppressWarnings("NullAway") - @Nullable - String getCarrierName() { - return haveCarrier() ? carrier.getName() : null; - } - - private boolean haveCarrier() { - return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) && (carrier != null); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - CurrentNetwork that = (CurrentNetwork) o; - return Objects.equals(carrier, that.carrier) - && state == that.state - && Objects.equals(subType, that.subType); - } - - @Override - public int hashCode() { - return Objects.hash(carrier, state, subType); - } - - @Override - public String toString() { - return "CurrentNetwork{" - + "carrier=" - + carrier - + ", state=" - + state - + ", subType='" - + subType - + '\'' - + '}'; - } - - static Builder builder(NetworkState state) { - return new Builder(state); - } - - static class Builder { - @Nullable private Carrier carrier; - private final NetworkState state; - @Nullable private String subType; - - private Builder(NetworkState state) { - this.state = state; - } - - Builder carrier(@Nullable Carrier carrier) { - this.carrier = carrier; - return this; - } - - Builder subType(@Nullable String subType) { - this.subType = subType; - return this; - } - - CurrentNetwork build() { - return new CurrentNetwork(this); - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkAttributesExtractor.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkAttributesExtractor.java deleted file mode 100644 index 3662cb1a..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkAttributesExtractor.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_HOST_CARRIER_ICC; -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_HOST_CARRIER_MCC; -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_HOST_CARRIER_MNC; -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_HOST_CARRIER_NAME; -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_HOST_CONNECTION_SUBTYPE; -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_HOST_CONNECTION_TYPE; - -import androidx.annotation.Nullable; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; - -final class CurrentNetworkAttributesExtractor { - - Attributes extract(CurrentNetwork network) { - AttributesBuilder builder = - Attributes.builder() - .put(NET_HOST_CONNECTION_TYPE, network.getState().getHumanName()); - - setIfNotNull(builder, NET_HOST_CONNECTION_SUBTYPE, network.getSubType()); - setIfNotNull(builder, NET_HOST_CARRIER_NAME, network.getCarrierName()); - setIfNotNull(builder, NET_HOST_CARRIER_MCC, network.getCarrierCountryCode()); - setIfNotNull(builder, NET_HOST_CARRIER_MNC, network.getCarrierNetworkCode()); - setIfNotNull(builder, NET_HOST_CARRIER_ICC, network.getCarrierIsoCountryCode()); - - return builder.build(); - } - - private static void setIfNotNull( - AttributesBuilder builder, AttributeKey key, @Nullable String value) { - if (value != null) { - builder.put(key, value); - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkProvider.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkProvider.java deleted file mode 100644 index 33e633b2..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkProvider.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import android.app.Application; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkRequest; -import android.os.Build; -import android.util.Log; -import androidx.annotation.NonNull; -import io.opentelemetry.rum.internal.RumConstants; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.function.Supplier; - -// note: based on ideas from stack overflow: -// https://stackoverflow.com/questions/32547006/connectivitymanager-getnetworkinfoint-deprecated - -/** - * A provider of {@link CurrentNetwork} information. Registers itself in the Android {@link - * ConnectivityManager} and listens for network changes. - */ -public final class CurrentNetworkProvider { - - static final CurrentNetwork NO_NETWORK = - CurrentNetwork.builder(NetworkState.NO_NETWORK_AVAILABLE).build(); - static final CurrentNetwork UNKNOWN_NETWORK = - CurrentNetwork.builder(NetworkState.TRANSPORT_UNKNOWN).build(); - - /** - * Creates a new {@link CurrentNetworkProvider} instance and registers network callbacks in the - * Android {@link ConnectivityManager}. - */ - public static CurrentNetworkProvider createAndStart(Application application) { - Context context = application.getApplicationContext(); - CurrentNetworkProvider currentNetworkProvider = - new CurrentNetworkProvider(NetworkDetector.create(context)); - currentNetworkProvider.startMonitoring( - CurrentNetworkProvider::createNetworkMonitoringRequest, - (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)); - return currentNetworkProvider; - } - - private final NetworkDetector networkDetector; - - private volatile CurrentNetwork currentNetwork = UNKNOWN_NETWORK; - private final List listeners = new CopyOnWriteArrayList<>(); - - // visible for tests - CurrentNetworkProvider(NetworkDetector networkDetector) { - this.networkDetector = networkDetector; - } - - // visible for tests - void startMonitoring( - Supplier createNetworkMonitoringRequest, - ConnectivityManager connectivityManager) { - refreshNetworkStatus(); - try { - registerNetworkCallbacks(createNetworkMonitoringRequest, connectivityManager); - } catch (Exception e) { - // if this fails, we'll go without network change events. - Log.w( - RumConstants.OTEL_RUM_LOG_TAG, - "Failed to register network callbacks. Automatic network monitoring is disabled.", - e); - } - } - - private void registerNetworkCallbacks( - Supplier createNetworkMonitoringRequest, - ConnectivityManager connectivityManager) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - connectivityManager.registerDefaultNetworkCallback(new ConnectionMonitor()); - } else { - NetworkRequest networkRequest = createNetworkMonitoringRequest.get(); - connectivityManager.registerNetworkCallback(networkRequest, new ConnectionMonitor()); - } - } - - /** Returns up-to-date {@linkplain CurrentNetwork current network information}. */ - public CurrentNetwork refreshNetworkStatus() { - try { - currentNetwork = networkDetector.detectCurrentNetwork(); - } catch (Exception e) { - // guard against security issues/bugs when accessing the Android connectivityManager. - // see: https://issuetracker.google.com/issues/175055271 - currentNetwork = UNKNOWN_NETWORK; - } - return currentNetwork; - } - - private static NetworkRequest createNetworkMonitoringRequest() { - // note: this throws an NPE when running in junit without robolectric, due to Android - return new NetworkRequest.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH) - .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) - .addTransportType(NetworkCapabilities.TRANSPORT_VPN) - .build(); - } - - CurrentNetwork getCurrentNetwork() { - return currentNetwork; - } - - void addNetworkChangeListener(NetworkChangeListener listener) { - listeners.add(listener); - } - - private void notifyListeners(CurrentNetwork activeNetwork) { - for (NetworkChangeListener listener : listeners) { - listener.onNetworkChange(activeNetwork); - } - } - - private final class ConnectionMonitor extends ConnectivityManager.NetworkCallback { - - @Override - public void onAvailable(@NonNull Network network) { - CurrentNetwork activeNetwork = refreshNetworkStatus(); - Log.d(RumConstants.OTEL_RUM_LOG_TAG, " onAvailable: currentNetwork=" + activeNetwork); - - notifyListeners(activeNetwork); - } - - @Override - public void onLost(@NonNull Network network) { - // it seems that the "currentNetwork" is still the one that is being lost, so for - // this method, we'll force it to be NO_NETWORK, rather than relying on the - // ConnectivityManager to have the right - // state at the right time during this event. - CurrentNetwork currentNetwork = NO_NETWORK; - CurrentNetworkProvider.this.currentNetwork = currentNetwork; - Log.d(RumConstants.OTEL_RUM_LOG_TAG, " onLost: currentNetwork=" + currentNetwork); - - notifyListeners(currentNetwork); - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkApplicationListener.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkApplicationListener.java deleted file mode 100644 index 6cdd1991..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkApplicationListener.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.rum.internal.instrumentation.ApplicationStateListener; -import java.util.concurrent.atomic.AtomicBoolean; - -class NetworkApplicationListener implements ApplicationStateListener { - static final AttributeKey NETWORK_STATUS_KEY = stringKey("network.status"); - - private final CurrentNetworkProvider currentNetworkProvider; - private final AtomicBoolean shouldEmitChangeEvents = new AtomicBoolean(true); - - NetworkApplicationListener(CurrentNetworkProvider currentNetworkProvider) { - this.currentNetworkProvider = currentNetworkProvider; - } - - void startMonitoring(Instrumenter instrumenter) { - currentNetworkProvider.addNetworkChangeListener( - new TracingNetworkChangeListener(instrumenter, shouldEmitChangeEvents)); - } - - @Override - public void onApplicationForegrounded() { - shouldEmitChangeEvents.set(true); - } - - @Override - public void onApplicationBackgrounded() { - shouldEmitChangeEvents.set(false); - } - - private static final class TracingNetworkChangeListener implements NetworkChangeListener { - - private final Instrumenter instrumenter; - private final AtomicBoolean shouldEmitChangeEvents; - - TracingNetworkChangeListener( - Instrumenter instrumenter, - AtomicBoolean shouldEmitChangeEvents) { - this.instrumenter = instrumenter; - this.shouldEmitChangeEvents = shouldEmitChangeEvents; - } - - @Override - public void onNetworkChange(CurrentNetwork currentNetwork) { - if (!shouldEmitChangeEvents.get()) { - return; - } - Context context = instrumenter.start(Context.current(), currentNetwork); - instrumenter.end(context, currentNetwork, null, null); - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkAttributesSpanAppender.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkAttributesSpanAppender.java deleted file mode 100644 index 948286c5..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkAttributesSpanAppender.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import io.opentelemetry.sdk.trace.ReadableSpan; -import io.opentelemetry.sdk.trace.SpanProcessor; - -/** - * A {@link SpanProcessor} implementation that appends a set of {@linkplain Attributes attributes} - * describing the {@linkplain CurrentNetwork current network} to every span that is exported. - * - *

This class is internal and not for public use. Its APIs are unstable and can change at any - * time. - */ -public final class NetworkAttributesSpanAppender implements SpanProcessor { - - public static SpanProcessor create(CurrentNetworkProvider currentNetworkProvider) { - return new NetworkAttributesSpanAppender(currentNetworkProvider); - } - - private final CurrentNetworkProvider currentNetworkProvider; - private final CurrentNetworkAttributesExtractor networkAttributesExtractor = - new CurrentNetworkAttributesExtractor(); - - NetworkAttributesSpanAppender(CurrentNetworkProvider currentNetworkProvider) { - this.currentNetworkProvider = currentNetworkProvider; - } - - @Override - public void onStart(Context parentContext, ReadWriteSpan span) { - CurrentNetwork currentNetwork = currentNetworkProvider.getCurrentNetwork(); - span.setAllAttributes(networkAttributesExtractor.extract(currentNetwork)); - } - - @Override - public boolean isStartRequired() { - return true; - } - - @Override - public void onEnd(ReadableSpan span) {} - - @Override - public boolean isEndRequired() { - return false; - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeAttributesExtractor.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeAttributesExtractor.java deleted file mode 100644 index e2eed40b..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeAttributesExtractor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_HOST_CONNECTION_TYPE; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; - -final class NetworkChangeAttributesExtractor implements AttributesExtractor { - - static final AttributeKey NETWORK_STATUS_KEY = stringKey("network.status"); - - private final CurrentNetworkAttributesExtractor networkAttributesExtractor = - new CurrentNetworkAttributesExtractor(); - - @Override - public void onStart( - AttributesBuilder attributes, Context parentContext, CurrentNetwork currentNetwork) { - String status = - currentNetwork.getState() == NetworkState.NO_NETWORK_AVAILABLE - ? "lost" - : "available"; - attributes.put(NETWORK_STATUS_KEY, status); - } - - @Override - public void onEnd( - AttributesBuilder attributes, - Context context, - CurrentNetwork currentNetwork, - Void unused, - Throwable error) { - // put these after span start to override what might be set in the - // NetworkAttributesSpanAppender. - if (currentNetwork.getState() == NetworkState.NO_NETWORK_AVAILABLE) { - attributes.put(NET_HOST_CONNECTION_TYPE, currentNetwork.getState().getHumanName()); - } else { - attributes.putAll(networkAttributesExtractor.extract(currentNetwork)); - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeListener.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeListener.java deleted file mode 100644 index 8121b3cc..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeListener.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -interface NetworkChangeListener { - - void onNetworkChange(CurrentNetwork currentNetwork); -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitor.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitor.java deleted file mode 100644 index 7cd12e03..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitor.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import java.util.ArrayList; -import java.util.List; - -/** - * Entrypoint for installing the network change monitoring instrumentation. - * - *

This class is internal and not for public use. Its APIs are unstable and can change at any - * time. - */ -public final class NetworkChangeMonitor { - - public static NetworkChangeMonitor create(CurrentNetworkProvider currentNetworkProvider) { - return builder(currentNetworkProvider).build(); - } - - public static NetworkChangeMonitorBuilder builder( - CurrentNetworkProvider currentNetworkProvider) { - return new NetworkChangeMonitorBuilder(currentNetworkProvider); - } - - private final CurrentNetworkProvider currentNetworkProvider; - private final List> additionalExtractors; - - NetworkChangeMonitor(NetworkChangeMonitorBuilder builder) { - this.currentNetworkProvider = builder.currentNetworkProvider; - this.additionalExtractors = new ArrayList<>(builder.additionalExtractors); - } - - /** - * Installs the network change monitoring instrumentation on the given {@link - * InstrumentedApplication}. - */ - public void installOn(InstrumentedApplication instrumentedApplication) { - NetworkApplicationListener networkApplicationListener = - new NetworkApplicationListener(currentNetworkProvider); - networkApplicationListener.startMonitoring( - buildInstrumenter(instrumentedApplication.getOpenTelemetrySdk())); - instrumentedApplication.registerApplicationStateListener(networkApplicationListener); - } - - private Instrumenter buildInstrumenter(OpenTelemetry openTelemetry) { - return Instrumenter.builder( - openTelemetry, "io.opentelemetry.network", network -> "network.change") - .addAttributesExtractor(new NetworkChangeAttributesExtractor()) - .addAttributesExtractors(additionalExtractors) - .buildInstrumenter(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitorBuilder.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitorBuilder.java deleted file mode 100644 index 99256228..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitorBuilder.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import java.util.ArrayList; -import java.util.List; - -/** - * A builder of {@link NetworkChangeMonitor}. - * - *

This class is internal and not for public use. Its APIs are unstable and can change at any - * time. - */ -public final class NetworkChangeMonitorBuilder { - - final CurrentNetworkProvider currentNetworkProvider; - final List> additionalExtractors = new ArrayList<>(); - - NetworkChangeMonitorBuilder(CurrentNetworkProvider currentNetworkProvider) { - this.currentNetworkProvider = currentNetworkProvider; - } - - /** Adds an {@link AttributesExtractor} that will extract additional attributes. */ - public NetworkChangeMonitorBuilder addAttributesExtractor( - AttributesExtractor extractor) { - additionalExtractors.add(extractor); - return this; - } - - public NetworkChangeMonitor build() { - return new NetworkChangeMonitor(this); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkDetector.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkDetector.java deleted file mode 100644 index 151c2538..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkDetector.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.os.Build; -import android.telephony.TelephonyManager; - -interface NetworkDetector { - CurrentNetwork detectCurrentNetwork(); - - static NetworkDetector create(Context context) { - ConnectivityManager connectivityManager = - (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - CarrierFinder carrierFinder = new CarrierFinder(telephonyManager); - return new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context); - } - return new SimpleNetworkDetector(connectivityManager); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkState.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkState.java deleted file mode 100644 index 45c34802..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkState.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; - -enum NetworkState { - NO_NETWORK_AVAILABLE(SemanticAttributes.NetHostConnectionTypeValues.UNAVAILABLE), - TRANSPORT_CELLULAR(SemanticAttributes.NetHostConnectionTypeValues.CELL), - TRANSPORT_WIFI(SemanticAttributes.NetHostConnectionTypeValues.WIFI), - TRANSPORT_UNKNOWN(SemanticAttributes.NetHostConnectionTypeValues.UNKNOWN), - // this one doesn't seem to have an otel value at this point. - TRANSPORT_VPN("vpn"); - - private final String humanName; - - NetworkState(String humanName) { - this.humanName = humanName; - } - - String getHumanName() { - return humanName; - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/PostApi28NetworkDetector.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/PostApi28NetworkDetector.java deleted file mode 100644 index 1bd9589a..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/PostApi28NetworkDetector.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider.NO_NETWORK; -import static io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider.UNKNOWN_NETWORK; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.NetworkCapabilities; -import android.os.Build; -import android.telephony.TelephonyManager; -import androidx.annotation.RequiresApi; -import androidx.core.app.ActivityCompat; - -@RequiresApi(api = Build.VERSION_CODES.P) -class PostApi28NetworkDetector implements NetworkDetector { - private final ConnectivityManager connectivityManager; - private final TelephonyManager telephonyManager; - private final CarrierFinder carrierFinder; - private final Context context; - - PostApi28NetworkDetector( - ConnectivityManager connectivityManager, - TelephonyManager telephonyManager, - CarrierFinder carrierFinder, - Context context) { - this.connectivityManager = connectivityManager; - this.telephonyManager = telephonyManager; - this.carrierFinder = carrierFinder; - this.context = context; - } - - @SuppressLint("MissingPermission") - @Override - public CurrentNetwork detectCurrentNetwork() { - NetworkCapabilities capabilities = - connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork()); - if (capabilities == null) { - return NO_NETWORK; - } - String subType = null; - Carrier carrier = carrierFinder.get(); - if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { - // If the app has the permission, use it to get a subtype. - if (hasPermission(Manifest.permission.READ_PHONE_STATE)) { - subType = getDataNetworkTypeName(telephonyManager.getDataNetworkType()); - } - return CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .carrier(carrier) - .subType(subType) - .build(); - } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { - return CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).carrier(carrier).build(); - } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) { - return CurrentNetwork.builder(NetworkState.TRANSPORT_VPN).carrier(carrier).build(); - } - // there is an active network, but it doesn't fall into the neat buckets above - return UNKNOWN_NETWORK; - } - - // visible for testing - boolean hasPermission(String permission) { - return ActivityCompat.checkSelfPermission(context, permission) - == PackageManager.PERMISSION_GRANTED; - } - - private String getDataNetworkTypeName(int dataNetworkType) { - switch (dataNetworkType) { - case TelephonyManager.NETWORK_TYPE_1xRTT: - return "1xRTT"; - case TelephonyManager.NETWORK_TYPE_CDMA: - return "CDMA"; - case TelephonyManager.NETWORK_TYPE_EDGE: - return "EDGE"; - case TelephonyManager.NETWORK_TYPE_EHRPD: - return "EHRPD"; - case TelephonyManager.NETWORK_TYPE_EVDO_0: - return "EVDO_0"; - case TelephonyManager.NETWORK_TYPE_EVDO_A: - return "EVDO_A"; - case TelephonyManager.NETWORK_TYPE_EVDO_B: - return "EVDO_B"; - case TelephonyManager.NETWORK_TYPE_GPRS: - return "GPRS"; - case TelephonyManager.NETWORK_TYPE_GSM: - return "GSM"; - case TelephonyManager.NETWORK_TYPE_HSDPA: - return "HSDPA"; - case TelephonyManager.NETWORK_TYPE_HSPA: - return "HSPA"; - case TelephonyManager.NETWORK_TYPE_HSPAP: - return "HSPAP"; - case TelephonyManager.NETWORK_TYPE_HSUPA: - return "HSUPA"; - case TelephonyManager.NETWORK_TYPE_IDEN: - return "IDEN"; - case TelephonyManager.NETWORK_TYPE_IWLAN: - return "IWLAN"; - case TelephonyManager.NETWORK_TYPE_LTE: - return "LTE"; - case TelephonyManager.NETWORK_TYPE_NR: - return "NR"; - case TelephonyManager.NETWORK_TYPE_TD_SCDMA: - return "SCDMA"; - case TelephonyManager.NETWORK_TYPE_UMTS: - return "UMTS"; - case TelephonyManager.NETWORK_TYPE_UNKNOWN: - return "UNKNOWN"; - } - return "UNKNOWN"; - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/SimpleNetworkDetector.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/SimpleNetworkDetector.java deleted file mode 100644 index d24666c1..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/network/SimpleNetworkDetector.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider.NO_NETWORK; -import static io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider.UNKNOWN_NETWORK; - -import android.net.ConnectivityManager; -import android.net.NetworkInfo; - -class SimpleNetworkDetector implements NetworkDetector { - private final ConnectivityManager connectivityManager; - - SimpleNetworkDetector(ConnectivityManager connectivityManager) { - this.connectivityManager = connectivityManager; - } - - @Override - public CurrentNetwork detectCurrentNetwork() { - NetworkInfo activeNetwork = - connectivityManager.getActiveNetworkInfo(); // Deprecated in API 29 - if (activeNetwork == null) { - return NO_NETWORK; - } - switch (activeNetwork.getType()) { - case ConnectivityManager.TYPE_MOBILE: // Deprecated in API 28 - return CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .subType(activeNetwork.getSubtypeName()) - .build(); - case ConnectivityManager.TYPE_WIFI: // Deprecated in API 28 - return CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI) - .subType(activeNetwork.getSubtypeName()) - .build(); - case ConnectivityManager.TYPE_VPN: - return CurrentNetwork.builder(NetworkState.TRANSPORT_VPN) - .subType(activeNetwork.getSubtypeName()) - .build(); - } - // there is an active network, but it doesn't fall into the neat buckets above - return UNKNOWN_NETWORK; - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderListener.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderListener.java deleted file mode 100644 index 3f717a19..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderListener.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.slowrendering; - -import static android.view.FrameMetrics.DRAW_DURATION; -import static android.view.FrameMetrics.FIRST_DRAW_FRAME; - -import android.app.Activity; -import android.os.Build; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.util.Log; -import android.util.SparseIntArray; -import android.view.FrameMetrics; -import android.view.Window; -import androidx.annotation.GuardedBy; -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.DefaultingActivityLifecycleCallbacks; -import io.opentelemetry.rum.internal.RumConstants; -import java.time.Duration; -import java.time.Instant; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -@RequiresApi(api = Build.VERSION_CODES.N) -class SlowRenderListener implements DefaultingActivityLifecycleCallbacks { - - static final int SLOW_THRESHOLD_MS = 16; - static final int FROZEN_THRESHOLD_MS = 700; - - private static final int NANOS_PER_MS = (int) TimeUnit.MILLISECONDS.toNanos(1); - // rounding value adds half a millisecond, for rounding to nearest ms - private static final int NANOS_ROUNDING_VALUE = NANOS_PER_MS / 2; - - private static final HandlerThread frameMetricsThread = - new HandlerThread("FrameMetricsCollector"); - - private final Tracer tracer; - private final ScheduledExecutorService executorService; - private final Handler frameMetricsHandler; - private final Duration pollInterval; - - private final ConcurrentMap activities = - new ConcurrentHashMap<>(); - - SlowRenderListener(Tracer tracer, Duration pollInterval) { - this( - tracer, - Executors.newScheduledThreadPool(1), - new Handler(startFrameMetricsLoop()), - pollInterval); - } - - // Exists for testing - SlowRenderListener( - Tracer tracer, - ScheduledExecutorService executorService, - Handler frameMetricsHandler, - Duration pollInterval) { - this.tracer = tracer; - this.executorService = executorService; - this.frameMetricsHandler = frameMetricsHandler; - this.pollInterval = pollInterval; - } - - private static Looper startFrameMetricsLoop() { - // just a precaution: this is supposed to be called only once, and the thread should always - // be not started here - if (!frameMetricsThread.isAlive()) { - frameMetricsThread.start(); - } - return frameMetricsThread.getLooper(); - } - - // the returned future is very unlikely to fail - @SuppressWarnings("FutureReturnValueIgnored") - void start() { - executorService.scheduleAtFixedRate( - this::reportSlowRenders, - pollInterval.toMillis(), - pollInterval.toMillis(), - TimeUnit.MILLISECONDS); - } - - @Override - public void onActivityResumed(@NonNull Activity activity) { - PerActivityListener listener = new PerActivityListener(activity); - PerActivityListener existing = activities.putIfAbsent(activity, listener); - if (existing == null) { - activity.getWindow().addOnFrameMetricsAvailableListener(listener, frameMetricsHandler); - } - } - - @Override - public void onActivityPaused(@NonNull Activity activity) { - PerActivityListener listener = activities.remove(activity); - if (listener != null) { - activity.getWindow().removeOnFrameMetricsAvailableListener(listener); - reportSlow(listener); - } - } - - static class PerActivityListener implements Window.OnFrameMetricsAvailableListener { - - private final Activity activity; - private final Object lock = new Object(); - - @GuardedBy("lock") - private SparseIntArray drawDurationHistogram = new SparseIntArray(); - - PerActivityListener(Activity activity) { - this.activity = activity; - } - - @Override - public void onFrameMetricsAvailable( - Window window, FrameMetrics frameMetrics, int dropCountSinceLastInvocation) { - - long firstDrawFrame = frameMetrics.getMetric(FIRST_DRAW_FRAME); - if (firstDrawFrame == 1) { - return; - } - - long drawDurationsNs = frameMetrics.getMetric(DRAW_DURATION); - // ignore values < 0; something must have gone wrong - if (drawDurationsNs >= 0) { - synchronized (lock) { - // calculation copied from FrameMetricsAggregator - int durationMs = - (int) ((drawDurationsNs + NANOS_ROUNDING_VALUE) / NANOS_PER_MS); - int oldValue = drawDurationHistogram.get(durationMs); - drawDurationHistogram.put(durationMs, (oldValue + 1)); - } - } - } - - SparseIntArray resetMetrics() { - synchronized (lock) { - SparseIntArray metrics = drawDurationHistogram; - drawDurationHistogram = new SparseIntArray(); - return metrics; - } - } - - public String getActivityName() { - return activity.getComponentName().flattenToShortString(); - } - } - - private void reportSlowRenders() { - try { - activities.forEach((activity, listener) -> reportSlow(listener)); - } catch (Exception e) { - Log.w(RumConstants.OTEL_RUM_LOG_TAG, "Exception while processing frame metrics", e); - } - } - - private void reportSlow(PerActivityListener listener) { - int slowCount = 0; - int frozenCount = 0; - SparseIntArray durationToCountHistogram = listener.resetMetrics(); - for (int i = 0; i < durationToCountHistogram.size(); i++) { - int duration = durationToCountHistogram.keyAt(i); - int count = durationToCountHistogram.get(duration); - if (duration > FROZEN_THRESHOLD_MS) { - Log.d( - RumConstants.OTEL_RUM_LOG_TAG, - "* FROZEN RENDER DETECTED: " + duration + " ms." + count + " times"); - frozenCount += count; - } else if (duration > SLOW_THRESHOLD_MS) { - Log.d( - RumConstants.OTEL_RUM_LOG_TAG, - "* Slow render detected: " + duration + " ms. " + count + " times"); - slowCount += count; - } - } - - Instant now = Instant.now(); - if (slowCount > 0) { - makeSpan("slowRenders", listener.getActivityName(), slowCount, now); - } - if (frozenCount > 0) { - makeSpan("frozenRenders", listener.getActivityName(), frozenCount, now); - } - } - - private void makeSpan(String spanName, String activityName, int slowCount, Instant now) { - Span span = - tracer.spanBuilder(spanName) - .setAttribute("count", slowCount) - .setAttribute("activity.name", activityName) - .setStartTimestamp(now) - .startSpan(); - span.end(now); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderingDetector.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderingDetector.java deleted file mode 100644 index 152cfe3f..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderingDetector.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.slowrendering; - -import android.os.Build; -import android.util.Log; -import io.opentelemetry.rum.internal.RumConstants; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import java.time.Duration; - -/** - * Entrypoint for installing the slow rendering detection instrumentation. - * - *

This class is internal and not for public use. Its APIs are unstable and can change at any - * time. - */ -public final class SlowRenderingDetector { - - public static SlowRenderingDetector create() { - return builder().build(); - } - - public static SlowRenderingDetectorBuilder builder() { - return new SlowRenderingDetectorBuilder(); - } - - private final Duration slowRenderingDetectionPollInterval; - - SlowRenderingDetector(SlowRenderingDetectorBuilder builder) { - this.slowRenderingDetectionPollInterval = builder.slowRenderingDetectionPollInterval; - } - - /** - * Installs the slow rendering detection instrumentation on the given {@link - * InstrumentedApplication}. - */ - public void installOn(InstrumentedApplication instrumentedApplication) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - Log.w( - RumConstants.OTEL_RUM_LOG_TAG, - "Slow/frozen rendering detection is not supported on platforms older than Android N (SDK version 24)."); - return; - } - - SlowRenderListener detector = - new SlowRenderListener( - instrumentedApplication - .getOpenTelemetrySdk() - .getTracer("io.opentelemetry.slow-rendering"), - slowRenderingDetectionPollInterval); - - instrumentedApplication.getApplication().registerActivityLifecycleCallbacks(detector); - detector.start(); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderingDetectorBuilder.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderingDetectorBuilder.java deleted file mode 100644 index 4ec87c72..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderingDetectorBuilder.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.slowrendering; - -import android.util.Log; -import io.opentelemetry.rum.internal.RumConstants; -import java.time.Duration; - -/** - * A builder of {@link SlowRenderingDetector}. - * - *

This class is internal and not for public use. Its APIs are unstable and can change at any - * time. - */ -public final class SlowRenderingDetectorBuilder { - - SlowRenderingDetectorBuilder() {} - - Duration slowRenderingDetectionPollInterval = Duration.ofSeconds(1); - - /** - * Configures the rate at which frame render durations are polled. - * - * @param interval The period that should be used for polling. - * @return {@code this} - */ - public SlowRenderingDetectorBuilder setSlowRenderingDetectionPollInterval(Duration interval) { - if (interval.toMillis() <= 0) { - Log.e( - RumConstants.OTEL_RUM_LOG_TAG, - "Invalid slowRenderingDetectionPollInterval: " - + interval - + "; must be positive"); - return this; - } - this.slowRenderingDetectionPollInterval = interval; - return this; - } - - public SlowRenderingDetector build() { - return new SlowRenderingDetector(this); - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/startup/AppStartupTimer.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/startup/AppStartupTimer.java deleted file mode 100644 index 016ede02..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/instrumentation/startup/AppStartupTimer.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.startup; - -import android.app.Activity; -import android.app.Application; -import android.os.Bundle; -import android.os.Handler; -import android.util.Log; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.DefaultingActivityLifecycleCallbacks; -import io.opentelemetry.rum.internal.RumConstants; -import io.opentelemetry.rum.internal.util.AnchoredClock; -import io.opentelemetry.sdk.common.Clock; -import java.util.concurrent.TimeUnit; - -public class AppStartupTimer { - // Maximum time from app start to creation of the UI. If this time is exceeded we will not - // create the app start span. Long app startup could indicate that the app was really started in - // background, in which case the measured startup time is misleading. - private static final long MAX_TIME_TO_UI_INIT = TimeUnit.MINUTES.toNanos(1); - - // exposed so it can be used for the rest of the startup sequence timing. - private final AnchoredClock startupClock = AnchoredClock.create(Clock.getDefault()); - private final long firstPossibleTimestamp = startupClock.now(); - @Nullable private volatile Span overallAppStartSpan = null; - @Nullable private volatile Runnable completionCallback = null; - // whether activity has been created - // accessed only from UI thread - private boolean uiInitStarted = false; - // whether MAX_TIME_TO_UI_INIT has been exceeded - // accessed only from UI thread - private boolean uiInitTooLate = false; - // accessed only from UI thread - private boolean isStartedFromBackground = false; - - public Span start(Tracer tracer) { - // guard against a double-start and just return what's already in flight. - if (overallAppStartSpan != null) { - return overallAppStartSpan; - } - final Span appStart = - tracer.spanBuilder("AppStart") - .setStartTimestamp(firstPossibleTimestamp, TimeUnit.NANOSECONDS) - .setAttribute(RumConstants.START_TYPE_KEY, "cold") - .startSpan(); - overallAppStartSpan = appStart; - return appStart; - } - - /** Returns the epoch timestamp in nanos calculated by the startupClock. */ - public long clockNow() { - return startupClock.now(); - } - - /** - * Creates a lifecycle listener that starts the UI init when an activity is created. - * - * @return a new Application.ActivityLifecycleCallbacks instance - */ - public Application.ActivityLifecycleCallbacks createLifecycleCallback() { - return new DefaultingActivityLifecycleCallbacks() { - @Override - public void onActivityCreated( - @NonNull Activity activity, @Nullable Bundle savedInstanceState) { - startUiInit(); - } - }; - } - - /** Called when Activity is created. */ - private void startUiInit() { - if (uiInitStarted || isStartedFromBackground) { - return; - } - uiInitStarted = true; - if (firstPossibleTimestamp + MAX_TIME_TO_UI_INIT < startupClock.now()) { - Log.d(RumConstants.OTEL_RUM_LOG_TAG, "Max time to UI init exceeded"); - uiInitTooLate = true; - clear(); - } - } - - public void setCompletionCallback(Runnable completionCallback) { - this.completionCallback = completionCallback; - } - - public void end() { - Span overallAppStartSpan = this.overallAppStartSpan; - if (overallAppStartSpan != null && !uiInitTooLate && !isStartedFromBackground) { - runCompletionCallback(); - overallAppStartSpan.end(startupClock.now(), TimeUnit.NANOSECONDS); - } - clear(); - } - - @Nullable - public Span getStartupSpan() { - return overallAppStartSpan; - } - - // visibleForTesting - public void runCompletionCallback() { - Runnable completionCallback = this.completionCallback; - if (completionCallback != null) { - completionCallback.run(); - } - } - - private void clear() { - overallAppStartSpan = null; - completionCallback = null; - } - - public void detectBackgroundStart(Handler handler) { - handler.post(new StartFromBackgroundRunnable(this)); - } - - /** - * See - * https://github.com/firebase/firebase-android-sdk/blob/939f90edd74373d42772518d04826657c2ef2e21/firebase-perf/src/main/java/com/google/firebase/perf/metrics/AppStartTrace.java#L283 - * When a runnable posted to main UI thread is executed before any activity's onCreate() method - * then the app is started in background. If app is started from foreground, activity's - * onCreate() method is executed before this runnable. Firebase does this check from a - * ContentProvider, we do it from whatever used OpenTelemetryRum first. If the first use of - * OpenTelemetryRum happens when the app is already started for us it will look the same as a - * background start, which is fine as it wouldn't report correct time anyway. - */ - private static class StartFromBackgroundRunnable implements Runnable { - private final AppStartupTimer startupTimer; - - public StartFromBackgroundRunnable(AppStartupTimer startupTimer) { - this.startupTimer = startupTimer; - } - - @Override - public void run() { - // check whether an activity has been created - if (!startupTimer.uiInitStarted) { - Log.d(RumConstants.OTEL_RUM_LOG_TAG, "Detected background app start"); - startupTimer.isStartedFromBackground = true; - } - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/util/ActiveSpan.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/util/ActiveSpan.java deleted file mode 100644 index 2e4430bf..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/util/ActiveSpan.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.util; - -import static io.opentelemetry.rum.internal.RumConstants.LAST_SCREEN_NAME_KEY; - -import androidx.annotation.Nullable; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.context.Scope; -import java.util.function.Supplier; - -public class ActiveSpan { - private final Supplier lastVisibleScreen; - - @Nullable private Span span; - @Nullable private Scope scope; - - public ActiveSpan(Supplier lastVisibleScreen) { - this.lastVisibleScreen = lastVisibleScreen; - } - - public boolean spanInProgress() { - return span != null; - } - - // it's fine to not close the scope here, will be closed in endActiveSpan() - @SuppressWarnings("MustBeClosedChecker") - public void startSpan(Supplier spanCreator) { - // don't start one if there's already one in progress - if (span != null) { - return; - } - this.span = spanCreator.get(); - scope = span.makeCurrent(); - } - - public void endActiveSpan() { - if (scope != null) { - scope.close(); - scope = null; - } - if (this.span != null) { - this.span.end(); - this.span = null; - } - } - - public void addEvent(String eventName) { - if (span != null) { - span.addEvent(eventName); - } - } - - public void addPreviousScreenAttribute(String screenName) { - if (span == null) { - return; - } - String previouslyVisibleScreen = lastVisibleScreen.get(); - if (previouslyVisibleScreen != null && !screenName.equals(previouslyVisibleScreen)) { - span.setAttribute(LAST_SCREEN_NAME_KEY, previouslyVisibleScreen); - } - } -} diff --git a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/util/AnchoredClock.java b/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/util/AnchoredClock.java deleted file mode 100644 index ce3c2260..00000000 --- a/opentelemetry-android-instrumentation/src/main/java/io/opentelemetry/rum/internal/util/AnchoredClock.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.util; - -import io.opentelemetry.sdk.common.Clock; - -// copied from otel-java -public final class AnchoredClock { - private final Clock clock; - private final long epochNanos; - private final long nanoTime; - - private AnchoredClock(Clock clock, long epochNanos, long nanoTime) { - this.clock = clock; - this.epochNanos = epochNanos; - this.nanoTime = nanoTime; - } - - public static AnchoredClock create(Clock clock) { - return new AnchoredClock(clock, clock.now(), clock.nanoTime()); - } - - public long now() { - long deltaNanos = this.clock.nanoTime() - this.nanoTime; - return this.epochNanos + deltaNanos; - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/AndroidResourceTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/AndroidResourceTest.java deleted file mode 100644 index 0b65acda..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/AndroidResourceTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static io.opentelemetry.rum.internal.RumConstants.RUM_SDK_VERSION; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.DEVICE_MODEL_IDENTIFIER; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.DEVICE_MODEL_NAME; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.OS_NAME; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.OS_TYPE; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.OS_VERSION; -import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.SERVICE_NAME; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; - -import android.app.Application; -import android.content.pm.ApplicationInfo; -import android.os.Build; -import io.opentelemetry.sdk.resources.Resource; -import opentelemetry.rum.instrumentation.R; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class AndroidResourceTest { - - String appName = "robotron"; - String rumSdkVersion = "1.2.3"; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - Application app; - - @Test - void testFullResource() { - ApplicationInfo appInfo = new ApplicationInfo(); - appInfo.labelRes = 12345; - when(app.getApplicationContext().getApplicationInfo()).thenReturn(appInfo); - when(app.getApplicationContext().getString(appInfo.labelRes)).thenReturn(appName); - when(app.getApplicationContext().getResources().getString(R.string.rum_version)) - .thenReturn(rumSdkVersion); - - Resource expected = - Resource.getDefault() - .merge( - Resource.builder() - .put(SERVICE_NAME, appName) - .put(RUM_SDK_VERSION, rumSdkVersion) - .put(DEVICE_MODEL_NAME, Build.MODEL) - .put(DEVICE_MODEL_IDENTIFIER, Build.MODEL) - .put(OS_NAME, "Android") - .put(OS_TYPE, "linux") - .put(OS_VERSION, Build.VERSION.RELEASE) - .build()); - - Resource result = AndroidResource.createDefault(app); - assertEquals(expected, result); - } - - @Test - void testProblematicContext() { - when(app.getApplicationContext().getApplicationInfo()) - .thenThrow(new SecurityException("cannot do that")); - when(app.getApplicationContext().getResources()).thenThrow(new SecurityException("boom")); - - Resource expected = - Resource.getDefault() - .merge( - Resource.builder() - .put(SERVICE_NAME, "unknown_service:android") - .put(RUM_SDK_VERSION, "unknown") - .put(DEVICE_MODEL_NAME, Build.MODEL) - .put(DEVICE_MODEL_IDENTIFIER, Build.MODEL) - .put(OS_NAME, "Android") - .put(OS_TYPE, "linux") - .put(OS_VERSION, Build.VERSION.RELEASE) - .build()); - - Resource result = AndroidResource.createDefault(app); - assertEquals(expected, result); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/ApplicationStateWatcherTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/ApplicationStateWatcherTest.java deleted file mode 100644 index 618278a0..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/ApplicationStateWatcherTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static org.mockito.Mockito.inOrder; - -import android.app.Activity; -import io.opentelemetry.rum.internal.instrumentation.ApplicationStateListener; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class ApplicationStateWatcherTest { - - @Mock Activity activity; - @Mock ApplicationStateListener listener1; - @Mock ApplicationStateListener listener2; - - ApplicationStateWatcher underTest; - - @BeforeEach - void setUp() { - underTest = new ApplicationStateWatcher(); - underTest.registerListener(listener1); - underTest.registerListener(listener2); - } - - @Test - void appForegrounded() { - underTest.onActivityStarted(activity); - underTest.onActivityStarted(activity); - underTest.onActivityStopped(activity); - underTest.onActivityStarted(activity); - underTest.onActivityStopped(activity); - - InOrder io = inOrder(listener1, listener2); - io.verify(listener1).onApplicationForegrounded(); - io.verify(listener2).onApplicationForegrounded(); - io.verifyNoMoreInteractions(); - } - - @Test - void appBackgrounded() { - underTest.onActivityStarted(activity); - underTest.onActivityStarted(activity); - underTest.onActivityStopped(activity); - underTest.onActivityStopped(activity); - - InOrder io = inOrder(listener1, listener2); - io.verify(listener1).onApplicationForegrounded(); - io.verify(listener2).onApplicationForegrounded(); - io.verify(listener1).onApplicationBackgrounded(); - io.verify(listener2).onApplicationBackgrounded(); - io.verifyNoMoreInteractions(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/GlobalAttributesSpanAppenderTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/GlobalAttributesSpanAppenderTest.java deleted file mode 100644 index 6660cc79..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/GlobalAttributesSpanAppenderTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.verify; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class GlobalAttributesSpanAppenderTest { - - @Mock private ReadWriteSpan span; - - private final GlobalAttributesSpanAppender globalAttributes = - GlobalAttributesSpanAppender.create(Attributes.of(stringKey("key"), "value")); - - @Test - void shouldAppendGlobalAttributes() { - globalAttributes.update(attributesBuilder -> attributesBuilder.put("key", "value2")); - globalAttributes.update( - attributesBuilder -> attributesBuilder.put(longKey("otherKey"), 1234L)); - - assertTrue(globalAttributes.isStartRequired()); - globalAttributes.onStart(Context.root(), span); - - verify(span) - .setAllAttributes( - Attributes.of(stringKey("key"), "value2", longKey("otherKey"), 1234L)); - - assertFalse(globalAttributes.isEndRequired()); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilderTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilderTest.java deleted file mode 100644 index 97cdac65..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilderTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static io.opentelemetry.rum.internal.RumConstants.SESSION_ID_KEY; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.verify; - -import android.app.Activity; -import android.app.Application; -import io.opentelemetry.rum.internal.instrumentation.ApplicationStateListener; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class OpenTelemetryRumBuilderTest { - - final Resource resource = - Resource.getDefault().toBuilder().put("test.attribute", "abcdef").build(); - final InMemorySpanExporter spanExporter = InMemorySpanExporter.create(); - - @Mock Application application; - @Mock Activity activity; - @Mock ApplicationStateListener listener; - - @Captor ArgumentCaptor activityCallbacksCaptor; - - @Test - void shouldRegisterApplicationStateWatcher() { - OpenTelemetryRum.builder(application).build(); - - verify(application).registerActivityLifecycleCallbacks(isA(ApplicationStateWatcher.class)); - } - - @Test - void shouldBuildTracerProvider() { - OpenTelemetryRum openTelemetryRum = - OpenTelemetryRum.builder(application) - .setResource(resource) - .addTracerProviderCustomizer( - (tracerProviderBuilder, app) -> - tracerProviderBuilder.addSpanProcessor( - SimpleSpanProcessor.create(spanExporter))) - .build(); - - String sessionId = openTelemetryRum.getRumSessionId(); - openTelemetryRum - .getOpenTelemetry() - .getTracer("test") - .spanBuilder("test span") - .startSpan() - .end(); - - List spans = spanExporter.getFinishedSpanItems(); - assertThat(spans).hasSize(1); - assertThat(spans.get(0)) - .hasName("test span") - .hasResource(resource) - .hasAttributesSatisfyingExactly(equalTo(SESSION_ID_KEY, sessionId)); - } - - @Test - void shouldInstallInstrumentation() { - OpenTelemetryRum.builder(application) - .addInstrumentation( - instrumentedApplication -> { - assertThat(instrumentedApplication.getApplication()) - .isSameAs(application); - instrumentedApplication.registerApplicationStateListener(listener); - }) - .build(); - - verify(application).registerActivityLifecycleCallbacks(activityCallbacksCaptor.capture()); - - activityCallbacksCaptor.getValue().onActivityStarted(activity); - verify(listener).onApplicationForegrounded(); - - activityCallbacksCaptor.getValue().onActivityStopped(activity); - verify(listener).onApplicationBackgrounded(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/RuntimeDetailsExtractorTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/RuntimeDetailsExtractorTest.java deleted file mode 100644 index 2dbae3ea..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/RuntimeDetailsExtractorTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static io.opentelemetry.context.Context.root; -import static io.opentelemetry.rum.internal.RumConstants.BATTERY_PERCENT_KEY; -import static io.opentelemetry.rum.internal.RumConstants.HEAP_FREE_KEY; -import static io.opentelemetry.rum.internal.RumConstants.STORAGE_SPACE_FREE_KEY; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.Intent; -import android.os.BatteryManager; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; -import java.io.File; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class RuntimeDetailsExtractorTest { - - @Mock Context context; - @Mock Intent intent; - @Mock File filesDir; - - @Test - void shouldCollectRuntimeDetails() { - when(context.getFilesDir()).thenReturn(filesDir); - when(filesDir.getFreeSpace()).thenReturn(4200L); - - Integer level = 690; - when(intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)).thenReturn(level); - when(intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)).thenReturn(1000); - - RuntimeDetailsExtractor details = RuntimeDetailsExtractor.create(context); - details.onReceive(context, intent); - - AttributesBuilder attributes = Attributes.builder(); - details.onStart(attributes, root(), null); - assertThat(attributes.build()) - .hasSize(3) - .containsEntry(STORAGE_SPACE_FREE_KEY, 4200L) - .containsKey(HEAP_FREE_KEY) - .containsEntry(BATTERY_PERCENT_KEY, 69.0); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdChangeTracerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdChangeTracerTest.java deleted file mode 100644 index d5a4fb1f..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdChangeTracerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static io.opentelemetry.rum.internal.RumConstants.PREVIOUS_SESSION_ID_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.util.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -class SessionIdChangeTracerTest { - @RegisterExtension final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); - - private SessionIdChangeListener underTest; - - @BeforeEach - void setup() { - Tracer tracer = otelTesting.getOpenTelemetry().getTracer("testTracer"); - underTest = new SessionIdChangeTracer(tracer); - } - - @Test - void shouldEmitSessionIdChangeSpan() { - underTest.onChange("123", "456"); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - SpanData span = spans.get(0); - assertEquals("sessionId.change", span.getName()); - Attributes attributes = span.getAttributes(); - assertEquals(1, attributes.size()); - assertEquals("123", attributes.get(PREVIOUS_SESSION_ID_KEY)); - // splunk.rumSessionId attribute is set in the RumAttributeAppender class - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdRatioBasedSamplerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdRatioBasedSamplerTest.java deleted file mode 100644 index bef9749f..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdRatioBasedSamplerTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.trace.IdGenerator; -import io.opentelemetry.sdk.trace.data.LinkData; -import io.opentelemetry.sdk.trace.samplers.Sampler; -import io.opentelemetry.sdk.trace.samplers.SamplingDecision; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class SessionIdRatioBasedSamplerTest { - private static final String HIGH_ID = "00000000000000008fffffffffffffff"; - private static final String LOW_ID = "00000000000000000000000000000000"; - private static final IdGenerator idsGenerator = IdGenerator.random(); - - @Mock SessionId sessionId; - private final String traceId = idsGenerator.generateTraceId(); - private final Context parentContext = Context.root().with(Span.getInvalid()); - private final List parentLinks = - Collections.singletonList(LinkData.create(SpanContext.getInvalid())); - - @Test - void samplerDropsHigh() { - when(sessionId.getSessionId()).thenReturn(HIGH_ID); - - SessionIdRatioBasedSampler sampler = new SessionIdRatioBasedSampler(0.5, sessionId); - - // Sampler drops if TraceIdRatioBasedSampler would drop this sessionId - assertEquals(shouldSample(sampler), SamplingDecision.DROP); - } - - @Test - void samplerKeepsLowestId() { - // Sampler accepts if TraceIdRatioBasedSampler would accept this sessionId - when(sessionId.getSessionId()).thenReturn(LOW_ID); - - SessionIdRatioBasedSampler sampler = new SessionIdRatioBasedSampler(0.5, sessionId); - assertEquals(shouldSample(sampler), SamplingDecision.RECORD_AND_SAMPLE); - } - - @Test - void zeroRatioDropsAll() { - when(sessionId.getSessionId()).thenReturn(HIGH_ID); - - SessionIdRatioBasedSampler samplerHigh = new SessionIdRatioBasedSampler(0.0, sessionId); - assertEquals(shouldSample(samplerHigh), SamplingDecision.DROP); - - when(sessionId.getSessionId()).thenReturn(LOW_ID); - - SessionIdRatioBasedSampler samplerLow = new SessionIdRatioBasedSampler(0.0, sessionId); - assertEquals(shouldSample(samplerLow), SamplingDecision.DROP); - } - - @Test - void oneRatioAcceptsAll() { - when(sessionId.getSessionId()).thenReturn(HIGH_ID); - - SessionIdRatioBasedSampler samplerHigh = new SessionIdRatioBasedSampler(1.0, sessionId); - assertEquals(shouldSample(samplerHigh), SamplingDecision.RECORD_AND_SAMPLE); - - when(sessionId.getSessionId()).thenReturn(LOW_ID); - - SessionIdRatioBasedSampler samplerLow = new SessionIdRatioBasedSampler(1.0, sessionId); - assertEquals(shouldSample(samplerLow), SamplingDecision.RECORD_AND_SAMPLE); - } - - private SamplingDecision shouldSample(Sampler sampler) { - return sampler.shouldSample( - parentContext, - traceId, - "name", - SpanKind.INTERNAL, - Attributes.empty(), - parentLinks) - .getDecision(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdSpanAppenderTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdSpanAppenderTest.java deleted file mode 100644 index c065113b..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdSpanAppenderTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static io.opentelemetry.rum.internal.RumConstants.SESSION_ID_KEY; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class SessionIdSpanAppenderTest { - - @Mock SessionId sessionId; - @Mock ReadWriteSpan span; - - @Test - void shouldSetSessionIdAsSpanAttribute() { - when(sessionId.getSessionId()).thenReturn("42"); - - SessionIdSpanAppender underTest = new SessionIdSpanAppender(sessionId); - - assertTrue(underTest.isStartRequired()); - underTest.onStart(Context.root(), span); - - verify(span).setAttribute(SESSION_ID_KEY, "42"); - - assertFalse(underTest.isEndRequired()); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdTest.java deleted file mode 100644 index 0fa2faca..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.opentelemetry.sdk.testing.time.TestClock; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class SessionIdTest { - - @Mock SessionIdTimeoutHandler timeoutHandler; - - @Test - void valueValid() { - String sessionId = new SessionId(TestClock.create(), timeoutHandler).getSessionId(); - assertNotNull(sessionId); - assertEquals(32, sessionId.length()); - assertTrue(Pattern.compile("[a-f0-9]+").matcher(sessionId).matches()); - } - - @Test - void valueSameUntil4Hours() { - TestClock clock = TestClock.create(); - SessionId sessionId = new SessionId(clock, timeoutHandler); - String value = sessionId.getSessionId(); - assertEquals(value, sessionId.getSessionId()); - clock.advance(3, TimeUnit.HOURS); - assertEquals(value, sessionId.getSessionId()); - clock.advance(59, TimeUnit.MINUTES); - assertEquals(value, sessionId.getSessionId()); - clock.advance(59, TimeUnit.SECONDS); - assertEquals(value, sessionId.getSessionId()); - - // now it should change. - clock.advance(1, TimeUnit.SECONDS); - String newSessionId = sessionId.getSessionId(); - assertNotNull(newSessionId); - assertNotEquals(value, newSessionId); - } - - @Test - void shouldCallSessionIdChangeListener() { - TestClock clock = TestClock.create(); - SessionIdChangeListener listener = mock(SessionIdChangeListener.class); - SessionId sessionId = new SessionId(clock, timeoutHandler); - sessionId.setSessionIdChangeListener(listener); - - String firstSessionId = sessionId.getSessionId(); - clock.advance(3, TimeUnit.HOURS); - sessionId.getSessionId(); - verify(timeoutHandler, times(2)).bump(); - verify(listener, never()).onChange(anyString(), anyString()); - - clock.advance(1, TimeUnit.HOURS); - String secondSessionId = sessionId.getSessionId(); - InOrder io = inOrder(timeoutHandler, listener); - io.verify(timeoutHandler).bump(); - io.verify(listener).onChange(firstSessionId, secondSessionId); - io.verifyNoMoreInteractions(); - } - - @Test - void shouldCreateNewSessionIdAfterTimeout() { - SessionId sessionId = new SessionId(timeoutHandler); - - String value = sessionId.getSessionId(); - verify(timeoutHandler).bump(); - - assertEquals(value, sessionId.getSessionId()); - verify(timeoutHandler, times(2)).bump(); - - when(timeoutHandler.hasTimedOut()).thenReturn(true); - - assertNotEquals(value, sessionId.getSessionId()); - verify(timeoutHandler, times(3)).bump(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdTimeoutHandlerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdTimeoutHandlerTest.java deleted file mode 100644 index e0265ca7..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/SessionIdTimeoutHandlerTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.opentelemetry.sdk.testing.time.TestClock; -import java.time.Duration; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; - -class SessionIdTimeoutHandlerTest { - - @Test - void shouldNeverTimeOutInForeground() { - TestClock clock = TestClock.create(); - SessionIdTimeoutHandler timeoutHandler = new SessionIdTimeoutHandler(clock); - - assertFalse(timeoutHandler.hasTimedOut()); - timeoutHandler.bump(); - - // never time out in foreground - clock.advance(Duration.ofHours(4)); - assertFalse(timeoutHandler.hasTimedOut()); - } - - @Test - void shouldApply15MinutesTimeoutToAppsInBackground() { - TestClock clock = TestClock.create(); - SessionIdTimeoutHandler timeoutHandler = new SessionIdTimeoutHandler(clock); - - timeoutHandler.onApplicationBackgrounded(); - timeoutHandler.bump(); - - assertFalse(timeoutHandler.hasTimedOut()); - timeoutHandler.bump(); - - // do not timeout if <15 minutes have passed - clock.advance(14, TimeUnit.MINUTES); - clock.advance(59, TimeUnit.SECONDS); - assertFalse(timeoutHandler.hasTimedOut()); - timeoutHandler.bump(); - - // restart the timeout counter after bump() - clock.advance(1, TimeUnit.MINUTES); - assertFalse(timeoutHandler.hasTimedOut()); - timeoutHandler.bump(); - - // timeout after 15 minutes - clock.advance(15, TimeUnit.MINUTES); - assertTrue(timeoutHandler.hasTimedOut()); - - // bump() resets the counter - timeoutHandler.bump(); - assertFalse(timeoutHandler.hasTimedOut()); - } - - @Test - void shouldApplyTimeoutToFirstSpanAfterAppBeingMovedToForeground() { - TestClock clock = TestClock.create(); - SessionIdTimeoutHandler timeoutHandler = new SessionIdTimeoutHandler(clock); - - timeoutHandler.onApplicationBackgrounded(); - timeoutHandler.bump(); - - // the first span after app is moved to the foreground gets timed out - timeoutHandler.onApplicationForegrounded(); - clock.advance(20, TimeUnit.MINUTES); - assertTrue(timeoutHandler.hasTimedOut()); - timeoutHandler.bump(); - - // after the initial span it's the same as the usual foreground scenario - clock.advance(Duration.ofHours(4)); - assertFalse(timeoutHandler.hasTimedOut()); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/AttributeModifyingSpanExporterTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/AttributeModifyingSpanExporterTest.java deleted file mode 100644 index 2082730f..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/AttributeModifyingSpanExporterTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.rum.internal.export.TestSpanHelper.span; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; -import static java.util.Collections.emptyMap; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class AttributeModifyingSpanExporterTest { - - @Mock SpanExporter exporter; - @Captor ArgumentCaptor> spansCaptor; - - @Test - void testEmptyMap() { - SpanData span1 = span("span1"); - SpanData span2 = span("span2"); - SpanData span3 = span("span3"); - Collection spans = Arrays.asList(span1, span2, span3); - CompletableResultCode expectedResult = mock(CompletableResultCode.class); - when(exporter.export(spans)).thenReturn(expectedResult); - - AttributeModifyingSpanExporter underTest = - new AttributeModifyingSpanExporter(exporter, emptyMap()); - - CompletableResultCode result = underTest.export(spans); - assertSame(expectedResult, result); - } - - @Test - void testRemappedToNull() { - AttributeKey key = stringKey("foo"); - SpanData span1 = span("span1", Attributes.of(key, "bar")); - Collection originalSpans = Collections.singletonList(span1); - - Map, Function> remappers = new HashMap<>(); - remappers.put(key, s -> null); - - CompletableResultCode expectedResult = mock(CompletableResultCode.class); - when(exporter.export(spansCaptor.capture())).thenReturn(expectedResult); - - AttributeModifyingSpanExporter underTest = - new AttributeModifyingSpanExporter(exporter, remappers); - - underTest.export(originalSpans); - assertThat(spansCaptor.getValue()) - .satisfiesExactly(span -> assertThat(span).hasTotalAttributeCount(0)); - } - - @Test - void modify() { - Attributes attr1 = buildAttr(1); - SpanData span1 = span("span1", attr1); - Attributes attr2 = buildAttr(2); - SpanData span2 = span("span2", attr2); - Attributes attr3 = buildAttr(3); - SpanData span3 = span("span3", attr3); - Collection spans = Arrays.asList(span1, span2, span3); - Map, Function> modifiers = new HashMap<>(); - modifiers.put(stringKey("foo1"), x -> "" + x + x); - modifiers.put(stringKey("foo3"), x -> "3" + x + x); - modifiers.put(stringKey("boop2"), x -> "2" + x + x); - - CompletableResultCode expectedResult = mock(CompletableResultCode.class); - when(exporter.export(spansCaptor.capture())).thenReturn(expectedResult); - - AttributeModifyingSpanExporter underTest = - new AttributeModifyingSpanExporter(exporter, modifiers); - CompletableResultCode result = underTest.export(spans); - assertSame(expectedResult, result); - assertThat(spansCaptor.getValue()) - .satisfiesExactly( - s -> - assertThat(s) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("foo1"), "bar1bar1"), - equalTo(stringKey("bar1"), "baz1"), - equalTo(stringKey("boop1"), "beep1")), - s -> - assertThat(s) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("foo2"), "bar2"), - equalTo(stringKey("bar2"), "baz2"), - equalTo(stringKey("boop2"), "2beep2beep2")), - s -> - assertThat(s) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("foo3"), "3bar3bar3"), - equalTo(stringKey("bar3"), "baz3"), - equalTo(stringKey("boop3"), "beep3"))); - } - - private static Attributes buildAttr(int num) { - return Attributes.builder() - .put("foo" + num, "bar" + num) - .put("bar" + num, "baz" + num) - .put("boop" + num, "beep" + num) - .build(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/FilteringSpanExporterTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/FilteringSpanExporterTest.java deleted file mode 100644 index ffa12455..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/FilteringSpanExporterTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.rum.internal.export.TestSpanHelper.span; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Predicate; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class FilteringSpanExporterTest { - - @Captor ArgumentCaptor> spansCaptor; - - @Test - void filter() { - SpanData span1 = span("one"); - SpanData span2 = span("two"); - SpanData span3 = span("three"); - SpanData span4 = span("four"); - SpanData span5 = span("FIVE"); - Attributes attr6 = Attributes.of(stringKey("herp"), "derp"); - SpanData span6 = span("six", attr6); - Attributes attr7 = Attributes.of(stringKey("dig"), "dug"); - SpanData span7 = span("seven", attr7); - SpanData span8 = span("eight"); - Collection spans = - Arrays.asList(span1, span2, span3, span4, span5, span6, span7, span8); - Map, Predicate> attrRejects = new HashMap<>(); - attrRejects.put(stringKey("herp"), "derp"::equals); - attrRejects.put(stringKey("dig"), v -> ((String) v).startsWith("d")); - - SpanExporter exporter = mock(SpanExporter.class); - CompletableResultCode expectedResult = mock(CompletableResultCode.class); - - when(exporter.export(spansCaptor.capture())).thenReturn(expectedResult); - - SpanExporter underTest = - FilteringSpanExporter.builder(exporter) - .rejecting(x -> x == span2) - .rejectSpansWithNameContaining("hree") - .rejectSpansNamed("four") - .rejectSpansNamed(x -> x.equalsIgnoreCase("five")) - .rejectSpansWithAttributesMatching(attrRejects) - .build(); - - CompletableResultCode result = underTest.export(spans); - assertThat(result).isSameAs(expectedResult); - Collection resultSpans = spansCaptor.getValue(); - assertThat(resultSpans) - .satisfiesExactly( - s -> assertThat(s).isSameAs(span1), s -> assertThat(s).isSameAs(span8)); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/ModifiedSpanDataTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/ModifiedSpanDataTest.java deleted file mode 100644 index c7760f59..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/ModifiedSpanDataTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static java.util.Collections.emptyList; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanId; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.TraceFlags; -import io.opentelemetry.api.trace.TraceId; -import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.trace.TestSpanData; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.data.StatusData; -import org.junit.jupiter.api.Test; - -class ModifiedSpanDataTest { - private static final String TRACE_ID = TraceId.fromLongs(0, 42); - private static final String SPAN_ID = SpanId.fromLong(123); - - @Test - void shouldForwardAllCallsExceptAttributesToTheOriginal() { - SpanData original = - TestSpanData.builder() - .setName("test") - .setKind(SpanKind.CLIENT) - .setSpanContext( - SpanContext.create( - TRACE_ID, - SPAN_ID, - TraceFlags.getSampled(), - TraceState.getDefault())) - .setParentSpanContext(SpanContext.getInvalid()) - .setStatus(StatusData.ok()) - .setStartEpochNanos(123) - .setAttributes(Attributes.of(stringKey("attribute"), "original value")) - .setEvents(emptyList()) - .setLinks(emptyList()) - .setEndEpochNanos(456) - .setHasEnded(true) - .setTotalRecordedEvents(0) - .setTotalRecordedLinks(0) - .setTotalAttributeCount(12) - .setInstrumentationLibraryInfo( - InstrumentationLibraryInfo.create("test", "0.0.1")) - .setResource(Resource.getDefault()) - .build(); - - SpanData modified = - new ModifiedSpanData(original, Attributes.of(stringKey("attribute"), "modified")); - - assertEquals(original.getName(), modified.getName()); - assertEquals(original.getKind(), modified.getKind()); - assertEquals(original.getSpanContext(), modified.getSpanContext()); - assertEquals(original.getParentSpanContext(), modified.getParentSpanContext()); - assertEquals(original.getStatus(), modified.getStatus()); - assertEquals(original.getStartEpochNanos(), modified.getStartEpochNanos()); - assertEquals(Attributes.of(stringKey("attribute"), "modified"), modified.getAttributes()); - assertEquals(original.getEvents(), modified.getEvents()); - assertEquals(original.getLinks(), modified.getLinks()); - assertEquals(original.getEndEpochNanos(), modified.getEndEpochNanos()); - assertEquals(original.hasEnded(), modified.hasEnded()); - assertEquals(original.getTotalRecordedEvents(), modified.getTotalRecordedEvents()); - assertEquals(original.getTotalRecordedLinks(), modified.getTotalRecordedLinks()); - assertEquals(1, modified.getTotalAttributeCount()); - assertEquals( - original.getInstrumentationLibraryInfo(), modified.getInstrumentationLibraryInfo()); - assertEquals(original.getResource(), modified.getResource()); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/SpanDataModifierTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/SpanDataModifierTest.java deleted file mode 100644 index 42e4bd23..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/SpanDataModifierTest.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.rum.internal.export.TestSpanHelper.span; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class SpanDataModifierTest { - static final AttributeKey ATTRIBUTE = stringKey("attribute"); - static final AttributeKey OTHER_ATTRIBUTE = stringKey("other_attribute"); - static final AttributeKey LONG_ATTRIBUTE = longKey("long_attribute"); - - @Mock SpanExporter delegate; - - @Captor ArgumentCaptor> spansCaptor; - - @Test - void shouldRejectSpansByName() { - // given - SpanExporter underTest = - SpanDataModifier.builder(delegate) - .rejectSpansByName(spanName -> spanName.equals("span2")) - .rejectSpansByName(spanName -> spanName.equals("span4")) - .build(); - - SpanData span1 = span("span1"); - SpanData span2 = span("span2"); - SpanData span3 = span("span3"); - SpanData span4 = span("span4"); - - CompletableResultCode expectedResult = new CompletableResultCode(); - when(delegate.export(spansCaptor.capture())).thenReturn(expectedResult); - - // when - CompletableResultCode result = underTest.export(asList(span1, span2, span3, span4)); - - // then - assertSame(expectedResult, result); - - assertThat(spansCaptor.getValue()) - .satisfiesExactly( - s -> assertThat(s).hasName(span1.getName()), - s -> assertThat(s).hasName(span3.getName())); - } - - @Test - void shouldRejectSpansByAttributeValue() { - // given - SpanExporter underTest = - SpanDataModifier.builder(delegate) - .rejectSpansByAttributeValue(ATTRIBUTE, value -> value.equals("test")) - .rejectSpansByAttributeValue(ATTRIBUTE, value -> value.equals("rejected!")) - .rejectSpansByAttributeValue(LONG_ATTRIBUTE, value -> value > 100) - .build(); - - SpanData rejected = span("span", Attributes.of(ATTRIBUTE, "test")); - SpanData differentKey = - span("span", Attributes.of(OTHER_ATTRIBUTE, "test", LONG_ATTRIBUTE, 42L)); - SpanData anotherRejected = span("span", Attributes.of(ATTRIBUTE, "rejected!")); - SpanData differentValue = span("span", Attributes.of(ATTRIBUTE, "not really test")); - SpanData yetAnotherRejected = - span("span", Attributes.of(ATTRIBUTE, "pass", LONG_ATTRIBUTE, 123L)); - - CompletableResultCode expectedResult = new CompletableResultCode(); - when(delegate.export(spansCaptor.capture())).thenReturn(expectedResult); - - // when - CompletableResultCode result = - underTest.export( - asList( - rejected, - differentKey, - anotherRejected, - differentValue, - yetAnotherRejected)); - - // then - assertSame(expectedResult, result); - - assertThat(spansCaptor.getValue()) - .satisfiesExactly( - s -> - assertThat(s) - .hasName(differentKey.getName()) - .hasAttributes(differentKey.getAttributes()), - s -> - assertThat(s) - .hasName(differentValue.getName()) - .hasAttributes(differentValue.getAttributes())); - } - - @Test - void shouldRemoveSpanAttributes() { - // given - SpanExporter underTest = - SpanDataModifier.builder(delegate) - .removeSpanAttribute(ATTRIBUTE, value -> value.equals("test")) - // make sure that attribute types are taken into account - .removeSpanAttribute(stringKey("long_attribute")) - .build(); - - SpanData span1 = span("first", Attributes.of(ATTRIBUTE, "test", LONG_ATTRIBUTE, 42L)); - SpanData span2 = - span("second", Attributes.of(ATTRIBUTE, "not test", OTHER_ATTRIBUTE, "test")); - - CompletableResultCode expectedResult = new CompletableResultCode(); - when(delegate.export(spansCaptor.capture())).thenReturn(expectedResult); - - // when - CompletableResultCode result = underTest.export(asList(span1, span2)); - - // then - assertSame(expectedResult, result); - - List exportedSpans = new ArrayList<>(spansCaptor.getValue()); - assertEquals(2, exportedSpans.size()); - assertEquals("first", exportedSpans.get(0).getName()); - assertEquals(Attributes.of(LONG_ATTRIBUTE, 42L), exportedSpans.get(0).getAttributes()); - assertEquals("second", exportedSpans.get(1).getName()); - assertEquals( - Attributes.of(ATTRIBUTE, "not test", OTHER_ATTRIBUTE, "test"), - exportedSpans.get(1).getAttributes()); - } - - @Test - void shouldReplaceSpanAttributes() { - // given - SpanExporter underTest = - SpanDataModifier.builder(delegate) - .replaceSpanAttribute(ATTRIBUTE, value -> value + "!!!") - .replaceSpanAttribute(ATTRIBUTE, value -> value + "1") - .replaceSpanAttribute(LONG_ATTRIBUTE, value -> value + 1) - // make sure that attribute types are taken into account - .replaceSpanAttribute(stringKey("long_attribute"), value -> "abc") - .build(); - - SpanData span1 = span("first", Attributes.of(ATTRIBUTE, "test", LONG_ATTRIBUTE, 42L)); - SpanData span2 = span("second", Attributes.of(OTHER_ATTRIBUTE, "test")); - - CompletableResultCode expectedResult = new CompletableResultCode(); - when(delegate.export(spansCaptor.capture())).thenReturn(expectedResult); - - // when - CompletableResultCode result = underTest.export(asList(span1, span2)); - - // then - assertSame(expectedResult, result); - - List exportedSpans = new ArrayList<>(spansCaptor.getValue()); - assertEquals(2, exportedSpans.size()); - assertEquals("first", exportedSpans.get(0).getName()); - assertEquals( - Attributes.of(ATTRIBUTE, "test!!!1", LONG_ATTRIBUTE, 43L), - exportedSpans.get(0).getAttributes()); - assertEquals("second", exportedSpans.get(1).getName()); - assertEquals(Attributes.of(OTHER_ATTRIBUTE, "test"), exportedSpans.get(1).getAttributes()); - } - - @Test - void shouldReplaceSpanAttributes_removeAttributeByReturningNull() { - // given - SpanExporter underTest = - SpanDataModifier.builder(delegate) - .replaceSpanAttribute(ATTRIBUTE, value -> null) - .build(); - - SpanData span = span("first", Attributes.of(ATTRIBUTE, "test", LONG_ATTRIBUTE, 42L)); - - CompletableResultCode expectedResult = new CompletableResultCode(); - when(delegate.export(spansCaptor.capture())).thenReturn(expectedResult); - - // when - CompletableResultCode result = underTest.export(singletonList(span)); - - // then - assertSame(expectedResult, result); - - List exportedSpans = new ArrayList<>(spansCaptor.getValue()); - assertEquals(1, exportedSpans.size()); - assertEquals("first", exportedSpans.get(0).getName()); - assertEquals(Attributes.of(LONG_ATTRIBUTE, 42L), exportedSpans.get(0).getAttributes()); - } - - @Test - void builderChangesShouldNotApplyToAlreadyDecoratedExporter() { - // given - SpanDataModifier builder = SpanDataModifier.builder(delegate); - SpanExporter underTest = builder.build(); - - builder.rejectSpansByName(spanName -> spanName.equals("span")) - .rejectSpansByAttributeValue(ATTRIBUTE, value -> true) - .removeSpanAttribute(ATTRIBUTE, value -> true) - .replaceSpanAttribute(ATTRIBUTE, value -> "abc"); - - SpanData span = span("span", Attributes.of(ATTRIBUTE, "test")); - - CompletableResultCode expectedResult = new CompletableResultCode(); - when(delegate.export(spansCaptor.capture())).thenReturn(expectedResult); - - // when - CompletableResultCode result = underTest.export(singletonList(span)); - - // then - assertSame(expectedResult, result); - - assertThat(spansCaptor.getValue()) - .satisfiesExactly( - s -> - assertThat(s) - .hasName(span.getName()) - .hasAttributes(span.getAttributes())); - } - - @Test - void shouldDelegateCalls() { - SpanExporter underTest = SpanDataModifier.builder(delegate).build(); - - underTest.flush(); - verify(delegate).flush(); - - underTest.shutdown(); - verify(delegate).shutdown(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/TestSpanHelper.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/TestSpanHelper.java deleted file mode 100644 index 0366f1c7..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/export/TestSpanHelper.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.export; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.sdk.testing.trace.TestSpanData; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.data.StatusData; - -public class TestSpanHelper { - - static SpanData span(String name) { - return span(name, Attributes.empty()); - } - - static SpanData span(String name, Attributes attributes) { - return TestSpanData.builder() - .setName(name) - .setKind(SpanKind.INTERNAL) - .setStatus(StatusData.unset()) - .setHasEnded(true) - .setStartEpochNanos(0) - .setEndEpochNanos(123) - .setAttributes(attributes) - .build(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbackTestHarness.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbackTestHarness.java deleted file mode 100644 index 9e2847e5..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbackTestHarness.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static org.mockito.Mockito.mock; - -import android.app.Activity; -import android.os.Bundle; - -class ActivityCallbackTestHarness { - - private final ActivityCallbacks callbacks; - - ActivityCallbackTestHarness(ActivityCallbacks callbacks) { - this.callbacks = callbacks; - } - - void runAppStartupLifecycle(Activity mainActivity) { - // app startup lifecycle is the same as a normal activity lifecycle - runActivityCreationLifecycle(mainActivity); - } - - void runActivityCreationLifecycle(Activity activity) { - Bundle bundle = mock(Bundle.class); - - callbacks.onActivityPreCreated(activity, bundle); - callbacks.onActivityCreated(activity, bundle); - callbacks.onActivityPostCreated(activity, bundle); - - runActivityStartedLifecycle(activity); - runActivityResumedLifecycle(activity); - } - - void runActivityStartedLifecycle(Activity activity) { - callbacks.onActivityPreStarted(activity); - callbacks.onActivityStarted(activity); - callbacks.onActivityPostStarted(activity); - } - - void runActivityPausedLifecycle(Activity activity) { - callbacks.onActivityPrePaused(activity); - callbacks.onActivityPaused(activity); - callbacks.onActivityPostPaused(activity); - } - - void runActivityResumedLifecycle(Activity activity) { - callbacks.onActivityPreResumed(activity); - callbacks.onActivityResumed(activity); - callbacks.onActivityPostResumed(activity); - } - - void runActivityStoppedFromRunningLifecycle(Activity activity) { - runActivityPausedLifecycle(activity); - runActivityStoppedFromPausedLifecycle(activity); - } - - void runActivityStoppedFromPausedLifecycle(Activity activity) { - callbacks.onActivityPreStopped(activity); - callbacks.onActivityStopped(activity); - callbacks.onActivityPostStopped(activity); - } - - void runActivityDestroyedFromStoppedLifecycle(Activity activity) { - callbacks.onActivityPreDestroyed(activity); - callbacks.onActivityDestroyed(activity); - callbacks.onActivityPostDestroyed(activity); - } - - void runActivityDestroyedFromPausedLifecycle(Activity activity) { - runActivityStoppedFromPausedLifecycle(activity); - runActivityDestroyedFromStoppedLifecycle(activity); - } - - void runActivityDestroyedFromRunningLifecycle(Activity activity) { - runActivityStoppedFromRunningLifecycle(activity); - runActivityDestroyedFromStoppedLifecycle(activity); - } - - void runActivityRestartedLifecycle(Activity activity) { - runActivityStartedLifecycle(activity); - runActivityResumedLifecycle(activity); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbacksTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbacksTest.java deleted file mode 100644 index 4015ea71..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityCallbacksTest.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static io.opentelemetry.rum.internal.RumConstants.LAST_SCREEN_NAME_KEY; -import static io.opentelemetry.rum.internal.RumConstants.SCREEN_NAME_KEY; -import static io.opentelemetry.rum.internal.RumConstants.START_TYPE_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.ScreenNameExtractor; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import io.opentelemetry.sdk.trace.data.EventData; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.util.List; -import java.util.Optional; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -class ActivityCallbacksTest { - @RegisterExtension final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); - - private ActivityTracerCache tracers; - private VisibleScreenTracker visibleScreenTracker; - - @BeforeEach - public void setup() { - Tracer tracer = otelTesting.getOpenTelemetry().getTracer("testTracer"); - AppStartupTimer startupTimer = new AppStartupTimer(); - visibleScreenTracker = mock(VisibleScreenTracker.class); - ScreenNameExtractor extractor = mock(ScreenNameExtractor.class); - when(extractor.extract(isA(Activity.class))).thenReturn("Activity"); - tracers = new ActivityTracerCache(tracer, visibleScreenTracker, startupTimer, extractor); - } - - @Test - void appStartup() { - ActivityCallbacks activityCallbacks = new ActivityCallbacks(tracers); - ActivityCallbackTestHarness testHarness = - new ActivityCallbackTestHarness(activityCallbacks); - - Activity activity = mock(Activity.class); - testHarness.runAppStartupLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData creationSpan = spans.get(0); - - // TODO: ADD THIS TEST TO THE NEW COMPONENT(S) - // assertEquals("AppStart", startupSpan.getName()); - // assertEquals("cold", startupSpan.getAttributes().get(SplunkRum.START_TYPE_KEY)); - - assertEquals( - activity.getClass().getSimpleName(), - creationSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - creationSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(creationSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = creationSpan.getEvents(); - assertEquals(9, events.size()); - - checkEventExists(events, "activityPreCreated"); - checkEventExists(events, "activityCreated"); - checkEventExists(events, "activityPostCreated"); - - checkEventExists(events, "activityPreStarted"); - checkEventExists(events, "activityStarted"); - checkEventExists(events, "activityPostStarted"); - - checkEventExists(events, "activityPreResumed"); - checkEventExists(events, "activityResumed"); - checkEventExists(events, "activityPostResumed"); - } - - @Test - void activityCreation() { - ActivityCallbacks activityCallbacks = new ActivityCallbacks(tracers); - - ActivityCallbackTestHarness testHarness = - new ActivityCallbackTestHarness(activityCallbacks); - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityCreationLifecycle(activity); - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData span = spans.get(0); - - assertEquals("AppStart", span.getName()); - assertEquals("warm", span.getAttributes().get(START_TYPE_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - span.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), span.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = span.getEvents(); - assertEquals(9, events.size()); - - checkEventExists(events, "activityPreCreated"); - checkEventExists(events, "activityCreated"); - checkEventExists(events, "activityPostCreated"); - - checkEventExists(events, "activityPreStarted"); - checkEventExists(events, "activityStarted"); - checkEventExists(events, "activityPostStarted"); - - checkEventExists(events, "activityPreResumed"); - checkEventExists(events, "activityResumed"); - checkEventExists(events, "activityPostResumed"); - } - - private void startupAppAndClearSpans(ActivityCallbackTestHarness testHarness) { - // make sure that the initial state has been set up & the application is started. - testHarness.runAppStartupLifecycle(mock(Activity.class)); - otelTesting.clearSpans(); - } - - @Test - void activityRestart() { - ActivityCallbacks activityCallbacks = new ActivityCallbacks(tracers); - - ActivityCallbackTestHarness testHarness = - new ActivityCallbackTestHarness(activityCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityRestartedLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData span = spans.get(0); - - assertEquals("AppStart", span.getName()); - assertEquals("hot", span.getAttributes().get(START_TYPE_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - span.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), span.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = span.getEvents(); - assertEquals(6, events.size()); - - checkEventExists(events, "activityPreStarted"); - checkEventExists(events, "activityStarted"); - checkEventExists(events, "activityPostStarted"); - - checkEventExists(events, "activityPreResumed"); - checkEventExists(events, "activityResumed"); - checkEventExists(events, "activityPostResumed"); - } - - @Test - void activityResumed() { - when(visibleScreenTracker.getPreviouslyVisibleScreen()).thenReturn("previousScreen"); - ActivityCallbacks activityCallbacks = new ActivityCallbacks(tracers); - - ActivityCallbackTestHarness testHarness = - new ActivityCallbackTestHarness(activityCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityResumedLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData span = spans.get(0); - - assertEquals("Resumed", span.getName()); - assertEquals( - activity.getClass().getSimpleName(), - span.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), span.getAttributes().get(SCREEN_NAME_KEY)); - assertEquals("previousScreen", span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = span.getEvents(); - assertEquals(3, events.size()); - - checkEventExists(events, "activityPreResumed"); - checkEventExists(events, "activityResumed"); - checkEventExists(events, "activityPostResumed"); - } - - @Test - void activityDestroyedFromStopped() { - ActivityCallbacks activityCallbacks = new ActivityCallbacks(tracers); - - ActivityCallbackTestHarness testHarness = - new ActivityCallbackTestHarness(activityCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityDestroyedFromStoppedLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData span = spans.get(0); - - assertEquals("Destroyed", span.getName()); - assertEquals( - activity.getClass().getSimpleName(), - span.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), span.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = span.getEvents(); - assertEquals(3, events.size()); - - checkEventExists(events, "activityPreDestroyed"); - checkEventExists(events, "activityDestroyed"); - checkEventExists(events, "activityPostDestroyed"); - } - - @Test - void activityDestroyedFromPaused() { - ActivityCallbacks activityCallbacks = new ActivityCallbacks(tracers); - - ActivityCallbackTestHarness testHarness = - new ActivityCallbackTestHarness(activityCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityDestroyedFromPausedLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(2, spans.size()); - - SpanData stoppedSpan = spans.get(0); - - assertEquals("Stopped", stoppedSpan.getName()); - assertEquals( - activity.getClass().getSimpleName(), - stoppedSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - stoppedSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(stoppedSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = stoppedSpan.getEvents(); - assertEquals(3, events.size()); - - checkEventExists(events, "activityPreStopped"); - checkEventExists(events, "activityStopped"); - checkEventExists(events, "activityPostStopped"); - - SpanData destroyedSpan = spans.get(1); - - assertEquals("Destroyed", destroyedSpan.getName()); - assertEquals( - activity.getClass().getSimpleName(), - destroyedSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - destroyedSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(destroyedSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - events = destroyedSpan.getEvents(); - assertEquals(3, events.size()); - - checkEventExists(events, "activityPreDestroyed"); - checkEventExists(events, "activityDestroyed"); - checkEventExists(events, "activityPostDestroyed"); - } - - @Test - void activityStoppedFromRunning() { - ActivityCallbacks activityCallbacks = new ActivityCallbacks(tracers); - - ActivityCallbackTestHarness testHarness = - new ActivityCallbackTestHarness(activityCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityStoppedFromRunningLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(2, spans.size()); - - SpanData stoppedSpan = spans.get(0); - - assertEquals("Paused", stoppedSpan.getName()); - assertEquals( - activity.getClass().getSimpleName(), - stoppedSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - stoppedSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(stoppedSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = stoppedSpan.getEvents(); - assertEquals(3, events.size()); - - checkEventExists(events, "activityPrePaused"); - checkEventExists(events, "activityPaused"); - checkEventExists(events, "activityPostPaused"); - - SpanData destroyedSpan = spans.get(1); - - assertEquals("Stopped", destroyedSpan.getName()); - assertEquals( - activity.getClass().getSimpleName(), - destroyedSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - destroyedSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(destroyedSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - events = destroyedSpan.getEvents(); - assertEquals(3, events.size()); - - checkEventExists(events, "activityPreStopped"); - checkEventExists(events, "activityStopped"); - checkEventExists(events, "activityPostStopped"); - } - - private void checkEventExists(List events, String eventName) { - Optional event = - events.stream().filter(e -> e.getName().equals(eventName)).findAny(); - assertTrue(event.isPresent(), "Event with name " + eventName + " not found"); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerCacheTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerCacheTest.java deleted file mode 100644 index 776be894..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerCacheTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class ActivityTracerCacheTest { - - @Mock Activity activity; - - @Mock ActivityTracer activityTracer; - @Mock Function tracerCreator; - AtomicReference initialActivity; - - @BeforeEach - void setup() { - initialActivity = new AtomicReference<>(); - } - - @Test - void addEventNewActivity() { - when(tracerCreator.apply(activity)).thenReturn(activityTracer); - when(activityTracer.addEvent(anyString())).thenReturn(activityTracer); - - ActivityTracerCache underTest = new ActivityTracerCache(tracerCreator); - ActivityTracer result = underTest.addEvent(activity, "beep"); - assertSame(activityTracer, result); - verify(activityTracer).addEvent("beep"); - verifyNoMoreInteractions(tracerCreator); - } - - @Test - void addEventExistingActivity() { - when(tracerCreator.apply(activity)).thenReturn(activityTracer); - when(activityTracer.addEvent(anyString())).thenReturn(activityTracer); - - ActivityTracerCache underTest = new ActivityTracerCache(tracerCreator); - ActivityTracer result1 = underTest.addEvent(activity, "beep1"); - ActivityTracer result2 = underTest.addEvent(activity, "beep2"); - ActivityTracer result3 = underTest.addEvent(activity, "beep3"); - assertSame(activityTracer, result1); - assertSame(activityTracer, result2); - assertSame(activityTracer, result3); - verify(activityTracer).addEvent("beep1"); - verify(activityTracer).addEvent("beep2"); - verify(activityTracer).addEvent("beep3"); - verify(tracerCreator).apply(activity); - } - - @Test - void startSpanIfNoneInProgress() { - when(tracerCreator.apply(activity)).thenReturn(activityTracer); - when(activityTracer.startSpanIfNoneInProgress("wrenchy")).thenReturn(activityTracer); - - ActivityTracerCache underTest = new ActivityTracerCache(tracerCreator); - - ActivityTracer result = underTest.startSpanIfNoneInProgress(activity, "wrenchy"); - assertSame(activityTracer, result); - verify(activityTracer).startSpanIfNoneInProgress("wrenchy"); - verifyNoMoreInteractions(tracerCreator); - } - - @Test - void initiateRestartSpanIfNecessary_singleActivity() { - - when(tracerCreator.apply(activity)).thenReturn(activityTracer); - when(activityTracer.initiateRestartSpanIfNecessary(false)).thenReturn(activityTracer); - - ActivityTracerCache underTest = new ActivityTracerCache(tracerCreator); - - ActivityTracer result = underTest.initiateRestartSpanIfNecessary(activity); - assertSame(activityTracer, result); - verify(activityTracer).initiateRestartSpanIfNecessary(false); - verifyNoMoreInteractions(tracerCreator); - } - - @Test - void initiateRestartSpanIfNecessary_multiActivity() { - Activity activity2 = new Activity() { - // to get a new class name used in the cache - }; - ActivityTracer activityTracer2 = mock(ActivityTracer.class); - - when(tracerCreator.apply(activity)).thenReturn(activityTracer); - when(tracerCreator.apply(activity2)).thenReturn(activityTracer2); - when(activityTracer.addEvent(anyString())).thenReturn(activityTracer); - when(activityTracer.initiateRestartSpanIfNecessary(true)).thenReturn(activityTracer); - - ActivityTracerCache underTest = new ActivityTracerCache(tracerCreator); - - underTest.addEvent(activity, "foo"); - underTest.addEvent(activity2, "bar"); - ActivityTracer result = underTest.initiateRestartSpanIfNecessary(activity); - assertSame(activityTracer, result); - verify(activityTracer).initiateRestartSpanIfNecessary(true); - } - - @Test - void startActivityCreation() { - when(tracerCreator.apply(activity)).thenReturn(activityTracer); - when(activityTracer.startActivityCreation()).thenReturn(activityTracer); - - ActivityTracerCache underTest = new ActivityTracerCache(tracerCreator); - - ActivityTracer result = underTest.startActivityCreation(activity); - assertSame(activityTracer, result); - verify(activityTracer).startActivityCreation(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerTest.java deleted file mode 100644 index 30096f1d..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/ActivityTracerTest.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static io.opentelemetry.rum.internal.RumConstants.LAST_SCREEN_NAME_KEY; -import static io.opentelemetry.rum.internal.RumConstants.SCREEN_NAME_KEY; -import static io.opentelemetry.rum.internal.RumConstants.START_TYPE_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; -import io.opentelemetry.rum.internal.util.ActiveSpan; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.util.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -public class ActivityTracerTest { - @RegisterExtension final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); - - private Tracer tracer; - private final VisibleScreenTracker visibleScreenTracker = mock(VisibleScreenTracker.class); - private final AppStartupTimer appStartupTimer = new AppStartupTimer(); - private ActiveSpan activeSpan; - - @BeforeEach - public void setup() { - tracer = otelTesting.getOpenTelemetry().getTracer("testTracer"); - activeSpan = new ActiveSpan(visibleScreenTracker::getPreviouslyVisibleScreen); - } - - @Test - void restart_nonInitialActivity() { - ActivityTracer trackableTracer = - ActivityTracer.builder(mock(Activity.class)) - .setInitialAppActivity("FirstActivity") - .setTracer(tracer) - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - trackableTracer.initiateRestartSpanIfNecessary(false); - trackableTracer.endActiveSpan(); - SpanData span = getSingleSpan(); - assertEquals("Restarted", span.getName()); - assertNull(span.getAttributes().get(START_TYPE_KEY)); - } - - @Test - public void restart_initialActivity() { - ActivityTracer trackableTracer = - ActivityTracer.builder(mock(Activity.class)) - .setInitialAppActivity("Activity") - .setTracer(tracer) - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - trackableTracer.initiateRestartSpanIfNecessary(false); - trackableTracer.endActiveSpan(); - SpanData span = getSingleSpan(); - assertEquals("AppStart", span.getName()); - assertEquals("hot", span.getAttributes().get(START_TYPE_KEY)); - } - - @Test - public void restart_initialActivity_multiActivityApp() { - ActivityTracer trackableTracer = - ActivityTracer.builder(mock(Activity.class)) - .setInitialAppActivity("Activity") - .setTracer(tracer) - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - trackableTracer.initiateRestartSpanIfNecessary(true); - trackableTracer.endActiveSpan(); - SpanData span = getSingleSpan(); - assertEquals("Restarted", span.getName()); - assertNull(span.getAttributes().get(START_TYPE_KEY)); - } - - @Test - public void create_nonInitialActivity() { - ActivityTracer trackableTracer = - ActivityTracer.builder(mock(Activity.class)) - .setInitialAppActivity("FirstActivity") - .setTracer(tracer) - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - - trackableTracer.startActivityCreation(); - trackableTracer.endActiveSpan(); - SpanData span = getSingleSpan(); - assertEquals("Created", span.getName()); - assertNull(span.getAttributes().get(START_TYPE_KEY)); - } - - @Test - public void create_initialActivity() { - ActivityTracer trackableTracer = - ActivityTracer.builder(mock(Activity.class)) - .setInitialAppActivity("Activity") - .setTracer(tracer) - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - trackableTracer.startActivityCreation(); - trackableTracer.endActiveSpan(); - SpanData span = getSingleSpan(); - assertEquals("AppStart", span.getName()); - assertEquals("warm", span.getAttributes().get(START_TYPE_KEY)); - } - - @Test - public void create_initialActivity_firstTime() { - appStartupTimer.start(tracer); - ActivityTracer trackableTracer = - ActivityTracer.builder(mock(Activity.class)) - .setTracer(tracer) - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - trackableTracer.startActivityCreation(); - trackableTracer.endActiveSpan(); - appStartupTimer.end(); - - List spans = otelTesting.getSpans(); - assertEquals(2, spans.size()); - - SpanData appStartSpan = spans.get(0); - assertEquals("AppStart", appStartSpan.getName()); - assertEquals("cold", appStartSpan.getAttributes().get(START_TYPE_KEY)); - - SpanData innerSpan = spans.get(1); - assertEquals("Created", innerSpan.getName()); - } - - @Test - public void addPreviousScreen_noPrevious() { - ActivityTracer trackableTracer = - ActivityTracer.builder(mock(Activity.class)) - .setTracer(tracer) - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - - trackableTracer.startSpanIfNoneInProgress("starting"); - trackableTracer.addPreviousScreenAttribute(); - trackableTracer.endActiveSpan(); - - SpanData span = getSingleSpan(); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - } - - @Test - public void addPreviousScreen_currentSameAsPrevious() { - VisibleScreenTracker visibleScreenTracker = mock(VisibleScreenTracker.class); - when(visibleScreenTracker.getPreviouslyVisibleScreen()).thenReturn("Activity"); - - ActivityTracer trackableTracer = - ActivityTracer.builder(mock(Activity.class)) - .setTracer(tracer) - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - - trackableTracer.startSpanIfNoneInProgress("starting"); - trackableTracer.addPreviousScreenAttribute(); - trackableTracer.endActiveSpan(); - - SpanData span = getSingleSpan(); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - } - - @Test - public void addPreviousScreen() { - when(visibleScreenTracker.getPreviouslyVisibleScreen()).thenReturn("previousScreen"); - - ActivityTracer trackableTracer = - ActivityTracer.builder(mock(Activity.class)) - .setTracer(tracer) - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - - trackableTracer.startSpanIfNoneInProgress("starting"); - trackableTracer.addPreviousScreenAttribute(); - trackableTracer.endActiveSpan(); - - SpanData span = getSingleSpan(); - assertEquals("previousScreen", span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - } - - @Test - public void testScreenName() { - ActivityTracer activityTracer = - ActivityTracer.builder(mock(Activity.class)) - .setTracer(tracer) - .setScreenName("squarely") - .setAppStartupTimer(appStartupTimer) - .setActiveSpan(activeSpan) - .build(); - activityTracer.startActivityCreation(); - activityTracer.endActiveSpan(); - SpanData span = getSingleSpan(); - assertEquals("squarely", span.getAttributes().get(SCREEN_NAME_KEY)); - } - - private SpanData getSingleSpan() { - List generatedSpans = otelTesting.getSpans(); - assertEquals(1, generatedSpans.size()); - return generatedSpans.get(0); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityCallbackTestHarness.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityCallbackTestHarness.java deleted file mode 100644 index e8c7eb1d..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityCallbackTestHarness.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static org.mockito.Mockito.mock; - -import android.app.Activity; -import android.os.Bundle; - -class Pre29ActivityCallbackTestHarness { - - private final Pre29ActivityCallbacks callbacks; - - Pre29ActivityCallbackTestHarness(Pre29ActivityCallbacks callbacks) { - this.callbacks = callbacks; - } - - void runAppStartupLifecycle(Activity mainActivity) { - // app startup lifecycle is the same as a normal activity lifecycle - runActivityCreationLifecycle(mainActivity); - } - - void runActivityCreationLifecycle(Activity activity) { - Bundle bundle = mock(Bundle.class); - - callbacks.onActivityCreated(activity, bundle); - - runActivityStartedLifecycle(activity); - runActivityResumedLifecycle(activity); - } - - void runActivityStartedLifecycle(Activity activity) { - callbacks.onActivityStarted(activity); - } - - void runActivityPausedLifecycle(Activity activity) { - callbacks.onActivityPaused(activity); - } - - void runActivityResumedLifecycle(Activity activity) { - callbacks.onActivityResumed(activity); - } - - void runActivityStoppedFromRunningLifecycle(Activity activity) { - runActivityPausedLifecycle(activity); - runActivityStoppedFromPausedLifecycle(activity); - } - - void runActivityStoppedFromPausedLifecycle(Activity activity) { - callbacks.onActivityStopped(activity); - } - - void runActivityDestroyedFromStoppedLifecycle(Activity activity) { - callbacks.onActivityDestroyed(activity); - } - - void runActivityDestroyedFromPausedLifecycle(Activity activity) { - runActivityStoppedFromPausedLifecycle(activity); - runActivityDestroyedFromStoppedLifecycle(activity); - } - - void runActivityDestroyedFromRunningLifecycle(Activity activity) { - runActivityStoppedFromRunningLifecycle(activity); - runActivityDestroyedFromStoppedLifecycle(activity); - } - - void runActivityRestartedLifecycle(Activity activity) { - runActivityStartedLifecycle(activity); - runActivityResumedLifecycle(activity); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityLifecycleCallbacksTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityLifecycleCallbacksTest.java deleted file mode 100644 index 8a520785..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29ActivityLifecycleCallbacksTest.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static io.opentelemetry.rum.internal.RumConstants.LAST_SCREEN_NAME_KEY; -import static io.opentelemetry.rum.internal.RumConstants.SCREEN_NAME_KEY; -import static io.opentelemetry.rum.internal.RumConstants.START_TYPE_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.ScreenNameExtractor; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import io.opentelemetry.sdk.trace.data.EventData; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.util.List; -import java.util.Optional; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -class Pre29ActivityLifecycleCallbacksTest { - @RegisterExtension final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); - private ActivityTracerCache tracers; - - private VisibleScreenTracker visibleScreenTracker; - - @BeforeEach - void setup() { - AppStartupTimer appStartupTimer = new AppStartupTimer(); - Tracer tracer = otelTesting.getOpenTelemetry().getTracer("testTracer"); - visibleScreenTracker = mock(VisibleScreenTracker.class); - ScreenNameExtractor extractor = mock(ScreenNameExtractor.class); - when(extractor.extract(isA(Activity.class))).thenReturn("Activity"); - tracers = new ActivityTracerCache(tracer, visibleScreenTracker, appStartupTimer, extractor); - } - - @Test - void appStartup() { - Pre29ActivityCallbacks rumLifecycleCallbacks = new Pre29ActivityCallbacks(tracers); - Pre29ActivityCallbackTestHarness testHarness = - new Pre29ActivityCallbackTestHarness(rumLifecycleCallbacks); - - Activity activity = mock(Activity.class); - testHarness.runAppStartupLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData creationSpan = spans.get(0); - - // TODO: Add test to relevant components - // assertEquals("AppStart", appStartSpan.getName()); - // assertEquals("cold", appStartSpan.getAttributes().get(SplunkRum.START_TYPE_KEY)); - - assertEquals( - activity.getClass().getSimpleName(), - creationSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - creationSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(creationSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = creationSpan.getEvents(); - assertEquals(3, events.size()); - - checkEventExists(events, "activityCreated"); - checkEventExists(events, "activityStarted"); - checkEventExists(events, "activityResumed"); - } - - @Test - void activityCreation() { - Pre29ActivityCallbacks rumLifecycleCallbacks = new Pre29ActivityCallbacks(tracers); - Pre29ActivityCallbackTestHarness testHarness = - new Pre29ActivityCallbackTestHarness(rumLifecycleCallbacks); - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityCreationLifecycle(activity); - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData span = spans.get(0); - - assertEquals("AppStart", span.getName()); - assertEquals("warm", span.getAttributes().get(START_TYPE_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - span.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), span.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = span.getEvents(); - assertEquals(3, events.size()); - - checkEventExists(events, "activityCreated"); - checkEventExists(events, "activityStarted"); - checkEventExists(events, "activityResumed"); - } - - private void startupAppAndClearSpans(Pre29ActivityCallbackTestHarness testHarness) { - // make sure that the initial state has been set up & the application is started. - testHarness.runAppStartupLifecycle(mock(Activity.class)); - otelTesting.clearSpans(); - } - - @Test - void activityRestart() { - Pre29ActivityCallbacks rumLifecycleCallbacks = new Pre29ActivityCallbacks(tracers); - Pre29ActivityCallbackTestHarness testHarness = - new Pre29ActivityCallbackTestHarness(rumLifecycleCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityRestartedLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData span = spans.get(0); - - assertEquals("AppStart", span.getName()); - assertEquals("hot", span.getAttributes().get(START_TYPE_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - span.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), span.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = span.getEvents(); - assertEquals(2, events.size()); - - checkEventExists(events, "activityStarted"); - checkEventExists(events, "activityResumed"); - } - - @Test - void activityResumed() { - when(visibleScreenTracker.getPreviouslyVisibleScreen()).thenReturn("previousScreen"); - - Pre29ActivityCallbacks rumLifecycleCallbacks = new Pre29ActivityCallbacks(tracers); - Pre29ActivityCallbackTestHarness testHarness = - new Pre29ActivityCallbackTestHarness(rumLifecycleCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityResumedLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData span = spans.get(0); - - assertEquals("Resumed", span.getName()); - assertEquals( - activity.getClass().getSimpleName(), - span.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), span.getAttributes().get(SCREEN_NAME_KEY)); - assertEquals("previousScreen", span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = span.getEvents(); - assertEquals(1, events.size()); - - checkEventExists(events, "activityResumed"); - } - - @Test - void activityDestroyedFromStopped() { - Pre29ActivityCallbacks rumLifecycleCallbacks = new Pre29ActivityCallbacks(tracers); - Pre29ActivityCallbackTestHarness testHarness = - new Pre29ActivityCallbackTestHarness(rumLifecycleCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityDestroyedFromStoppedLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData span = spans.get(0); - - assertEquals("Destroyed", span.getName()); - assertEquals( - activity.getClass().getSimpleName(), - span.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), span.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = span.getEvents(); - assertEquals(1, events.size()); - - checkEventExists(events, "activityDestroyed"); - } - - @Test - void activityDestroyedFromPaused() { - Pre29ActivityCallbacks rumLifecycleCallbacks = new Pre29ActivityCallbacks(tracers); - Pre29ActivityCallbackTestHarness testHarness = - new Pre29ActivityCallbackTestHarness(rumLifecycleCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityDestroyedFromPausedLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(2, spans.size()); - - SpanData stoppedSpan = spans.get(0); - - assertEquals("Stopped", stoppedSpan.getName()); - assertEquals( - activity.getClass().getSimpleName(), - stoppedSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - stoppedSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(stoppedSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = stoppedSpan.getEvents(); - assertEquals(1, events.size()); - - checkEventExists(events, "activityStopped"); - - SpanData destroyedSpan = spans.get(1); - - assertEquals("Destroyed", destroyedSpan.getName()); - assertEquals( - activity.getClass().getSimpleName(), - destroyedSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - destroyedSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(destroyedSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - events = destroyedSpan.getEvents(); - assertEquals(1, events.size()); - - checkEventExists(events, "activityDestroyed"); - } - - @Test - void activityStoppedFromRunning() { - Pre29ActivityCallbacks rumLifecycleCallbacks = new Pre29ActivityCallbacks(tracers); - Pre29ActivityCallbackTestHarness testHarness = - new Pre29ActivityCallbackTestHarness(rumLifecycleCallbacks); - - startupAppAndClearSpans(testHarness); - - Activity activity = mock(Activity.class); - testHarness.runActivityStoppedFromRunningLifecycle(activity); - - List spans = otelTesting.getSpans(); - assertEquals(2, spans.size()); - - SpanData stoppedSpan = spans.get(0); - - assertEquals("Paused", stoppedSpan.getName()); - assertEquals( - activity.getClass().getSimpleName(), - stoppedSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - stoppedSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(stoppedSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = stoppedSpan.getEvents(); - assertEquals(1, events.size()); - - checkEventExists(events, "activityPaused"); - - SpanData destroyedSpan = spans.get(1); - - assertEquals("Stopped", destroyedSpan.getName()); - assertEquals( - activity.getClass().getSimpleName(), - destroyedSpan.getAttributes().get(ActivityTracer.ACTIVITY_NAME_KEY)); - assertEquals( - activity.getClass().getSimpleName(), - destroyedSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(destroyedSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - events = destroyedSpan.getEvents(); - assertEquals(1, events.size()); - - checkEventExists(events, "activityStopped"); - } - - private void checkEventExists(List events, String eventName) { - Optional event = - events.stream().filter(e -> e.getName().equals(eventName)).findAny(); - assertTrue(event.isPresent(), "Event with name " + eventName + " not found"); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29VisibleScreenLifecycleBindingTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29VisibleScreenLifecycleBindingTest.java deleted file mode 100644 index 65a2ccea..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/Pre29VisibleScreenLifecycleBindingTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import android.app.Activity; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class Pre29VisibleScreenLifecycleBindingTest { - @Mock Activity activity; - @Mock VisibleScreenTracker tracker; - - @Test - void postResumed() { - Pre29VisibleScreenLifecycleBinding underTest = - new Pre29VisibleScreenLifecycleBinding(tracker); - underTest.onActivityResumed(activity); - verify(tracker).activityResumed(activity); - verifyNoMoreInteractions(tracker); - } - - @Test - void prePaused() { - Pre29VisibleScreenLifecycleBinding underTest = - new Pre29VisibleScreenLifecycleBinding(tracker); - underTest.onActivityPaused(activity); - verify(tracker).activityPaused(activity); - verifyNoMoreInteractions(tracker); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/RumFragmentActivityRegistererTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/RumFragmentActivityRegistererTest.java deleted file mode 100644 index fa141703..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/RumFragmentActivityRegistererTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.app.Application; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class RumFragmentActivityRegistererTest { - - @Mock FragmentManager.FragmentLifecycleCallbacks fragmentCallbacks; - - @Test - void createHappyPath() { - FragmentActivity activity = mock(FragmentActivity.class); - FragmentManager manager = mock(FragmentManager.class); - - when(activity.getSupportFragmentManager()).thenReturn(manager); - - Application.ActivityLifecycleCallbacks underTest = - RumFragmentActivityRegisterer.create(fragmentCallbacks); - - underTest.onActivityPreCreated(activity, null); - verify(manager).registerFragmentLifecycleCallbacks(fragmentCallbacks, true); - } - - @Test - void callbackIgnoresNonFragmentActivity() { - Activity activity = mock(Activity.class); - - Application.ActivityLifecycleCallbacks underTest = - RumFragmentActivityRegisterer.create(fragmentCallbacks); - - underTest.onActivityPreCreated(activity, null); - } - - @Test - void createPre29HappyPath() { - FragmentActivity activity = mock(FragmentActivity.class); - FragmentManager manager = mock(FragmentManager.class); - - when(activity.getSupportFragmentManager()).thenReturn(manager); - - Application.ActivityLifecycleCallbacks underTest = - RumFragmentActivityRegisterer.createPre29(fragmentCallbacks); - - underTest.onActivityCreated(activity, null); - verify(manager).registerFragmentLifecycleCallbacks(fragmentCallbacks, true); - } - - @Test - void pre29CallbackIgnoresNonFragmentActivity() { - Activity activity = mock(Activity.class); - - Application.ActivityLifecycleCallbacks underTest = - RumFragmentActivityRegisterer.createPre29(fragmentCallbacks); - - underTest.onActivityCreated(activity, null); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenLifecycleBindingTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenLifecycleBindingTest.java deleted file mode 100644 index d25864f5..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenLifecycleBindingTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import android.app.Activity; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class VisibleScreenLifecycleBindingTest { - - @Mock Activity activity; - @Mock VisibleScreenTracker tracker; - - @Test - void postResumed() { - VisibleScreenLifecycleBinding underTest = new VisibleScreenLifecycleBinding(tracker); - underTest.onActivityPostResumed(activity); - verify(tracker).activityResumed(activity); - verifyNoMoreInteractions(tracker); - } - - @Test - void prePaused() { - VisibleScreenLifecycleBinding underTest = new VisibleScreenLifecycleBinding(tracker); - underTest.onActivityPrePaused(activity); - verify(tracker).activityPaused(activity); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenTrackerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenTrackerTest.java deleted file mode 100644 index efd3ff3e..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/activity/VisibleScreenTrackerTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.activity; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.mockito.Mockito.mock; - -import android.app.Activity; -import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; -import androidx.navigation.fragment.NavHostFragment; -import org.junit.jupiter.api.Test; - -class VisibleScreenTrackerTest { - - @Test - void activityLifecycle() { - VisibleScreenTracker visibleScreenTracker = new VisibleScreenTracker(); - Activity activity = mock(Activity.class); - - assertEquals("unknown", visibleScreenTracker.getCurrentlyVisibleScreen()); - - visibleScreenTracker.activityResumed(activity); - assertEquals( - activity.getClass().getSimpleName(), - visibleScreenTracker.getCurrentlyVisibleScreen()); - assertNull(visibleScreenTracker.getPreviouslyVisibleScreen()); - - visibleScreenTracker.activityPaused(activity); - assertEquals("unknown", visibleScreenTracker.getCurrentlyVisibleScreen()); - assertEquals( - activity.getClass().getSimpleName(), - visibleScreenTracker.getPreviouslyVisibleScreen()); - } - - @Test - void fragmentLifecycle() { - VisibleScreenTracker visibleScreenTracker = new VisibleScreenTracker(); - Fragment fragment = mock(Fragment.class); - - assertEquals("unknown", visibleScreenTracker.getCurrentlyVisibleScreen()); - - visibleScreenTracker.fragmentResumed(fragment); - assertEquals( - fragment.getClass().getSimpleName(), - visibleScreenTracker.getCurrentlyVisibleScreen()); - assertNull(visibleScreenTracker.getPreviouslyVisibleScreen()); - - visibleScreenTracker.fragmentPaused(fragment); - assertEquals("unknown", visibleScreenTracker.getCurrentlyVisibleScreen()); - assertEquals( - fragment.getClass().getSimpleName(), - visibleScreenTracker.getPreviouslyVisibleScreen()); - } - - @Test - void fragmentLifecycle_navHostIgnored() { - VisibleScreenTracker visibleScreenTracker = new VisibleScreenTracker(); - Fragment fragment = mock(Fragment.class); - NavHostFragment navHostFragment = mock(NavHostFragment.class); - - assertEquals("unknown", visibleScreenTracker.getCurrentlyVisibleScreen()); - - visibleScreenTracker.fragmentResumed(fragment); - visibleScreenTracker.fragmentResumed(navHostFragment); - assertEquals( - fragment.getClass().getSimpleName(), - visibleScreenTracker.getCurrentlyVisibleScreen()); - assertNull(visibleScreenTracker.getPreviouslyVisibleScreen()); - - visibleScreenTracker.fragmentPaused(navHostFragment); - visibleScreenTracker.fragmentPaused(fragment); - assertEquals("unknown", visibleScreenTracker.getCurrentlyVisibleScreen()); - assertEquals( - fragment.getClass().getSimpleName(), - visibleScreenTracker.getPreviouslyVisibleScreen()); - } - - @Test - void fragmentLifecycle_dialogFragment() { - VisibleScreenTracker visibleScreenTracker = new VisibleScreenTracker(); - Fragment fragment = mock(Fragment.class); - DialogFragment dialogFragment = mock(DialogFragment.class); - - assertEquals("unknown", visibleScreenTracker.getCurrentlyVisibleScreen()); - - visibleScreenTracker.fragmentResumed(fragment); - visibleScreenTracker.fragmentResumed(dialogFragment); - assertEquals( - dialogFragment.getClass().getSimpleName(), - visibleScreenTracker.getCurrentlyVisibleScreen()); - assertEquals( - fragment.getClass().getSimpleName(), - visibleScreenTracker.getPreviouslyVisibleScreen()); - - visibleScreenTracker.fragmentPaused(dialogFragment); - assertEquals( - fragment.getClass().getSimpleName(), - visibleScreenTracker.getCurrentlyVisibleScreen()); - assertEquals( - dialogFragment.getClass().getSimpleName(), - visibleScreenTracker.getPreviouslyVisibleScreen()); - } - - @Test - void fragmentWinsOverActivityLifecycle() { - VisibleScreenTracker visibleScreenTracker = new VisibleScreenTracker(); - Activity activity = mock(Activity.class); - Fragment fragment = mock(Fragment.class); - - assertEquals("unknown", visibleScreenTracker.getCurrentlyVisibleScreen()); - - visibleScreenTracker.activityResumed(activity); - visibleScreenTracker.fragmentResumed(fragment); - assertEquals( - fragment.getClass().getSimpleName(), - visibleScreenTracker.getCurrentlyVisibleScreen()); - assertNull(visibleScreenTracker.getPreviouslyVisibleScreen()); - - visibleScreenTracker.fragmentPaused(fragment); - assertEquals( - activity.getClass().getSimpleName(), - visibleScreenTracker.getCurrentlyVisibleScreen()); - assertEquals( - fragment.getClass().getSimpleName(), - visibleScreenTracker.getPreviouslyVisibleScreen()); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorTest.java deleted file mode 100644 index 15c103a7..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.anr; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor.constant; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.os.Looper; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class AnrDetectorTest { - - @Mock Looper mainLooper; - @Mock ScheduledExecutorService scheduler; - @Mock InstrumentedApplication instrumentedApplication; - - @Test - void shouldInstallInstrumentation() { - when(instrumentedApplication.getOpenTelemetrySdk()) - .thenReturn(OpenTelemetrySdk.builder().build()); - - AnrDetector anrDetector = - AnrDetector.builder() - .setMainLooper(mainLooper) - .setScheduler(scheduler) - .addAttributesExtractor(constant(stringKey("test.key"), "abc")) - .build(); - anrDetector.installOn(instrumentedApplication); - - // verify that the ANR scheduler was started - verify(scheduler) - .scheduleAtFixedRate(isA(AnrWatcher.class), eq(1L), eq(1L), eq(TimeUnit.SECONDS)); - // verify that an application listener was installed - verify(instrumentedApplication) - .registerApplicationStateListener(isA(AnrDetectorToggler.class)); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorTogglerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorTogglerTest.java deleted file mode 100644 index ee6210b6..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorTogglerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.anr; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class AnrDetectorTogglerTest { - - @Mock Runnable anrWatcher; - @Mock ScheduledExecutorService scheduler; - @Mock ScheduledFuture future; - - @InjectMocks AnrDetectorToggler underTest; - - @Test - void testOnApplicationForegrounded() { - doReturn(future).when(scheduler).scheduleAtFixedRate(anrWatcher, 1, 1, TimeUnit.SECONDS); - - underTest.onApplicationForegrounded(); - underTest.onApplicationForegrounded(); - underTest.onApplicationForegrounded(); - - verify(scheduler, times(1)).scheduleAtFixedRate(anrWatcher, 1, 1, TimeUnit.SECONDS); - } - - @Test - void testOnApplicationBackgrounded() { - doReturn(future).when(scheduler).scheduleAtFixedRate(anrWatcher, 1, 1, TimeUnit.SECONDS); - - underTest.onApplicationForegrounded(); - - underTest.onApplicationBackgrounded(); - underTest.onApplicationBackgrounded(); - underTest.onApplicationBackgrounded(); - - verify(future, times(1)).cancel(true); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrWatcherTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrWatcherTest.java deleted file mode 100644 index 3bf34b08..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrWatcherTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.anr; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.os.Handler; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class AnrWatcherTest { - - @RegisterExtension - static final OpenTelemetryExtension testing = OpenTelemetryExtension.create(); - - @Mock Handler handler; - @Mock Thread mainThread; - @Mock Instrumenter instrumenter; - - @Test - void mainThreadDisappearing() { - AnrWatcher anrWatcher = new AnrWatcher(handler, mainThread, instrumenter); - for (int i = 0; i < 5; i++) { - when(handler.post(isA(Runnable.class))).thenReturn(false); - anrWatcher.run(); - } - verifyNoInteractions(instrumenter); - } - - @Test - void noAnr() { - AnrWatcher anrWatcher = new AnrWatcher(handler, mainThread, instrumenter); - for (int i = 0; i < 5; i++) { - when(handler.post(isA(Runnable.class))) - .thenAnswer( - invocation -> { - Runnable callback = (Runnable) invocation.getArgument(0); - callback.run(); - return true; - }); - anrWatcher.run(); - } - verifyNoInteractions(instrumenter); - } - - @Test - void noAnr_temporaryPause() { - AnrWatcher anrWatcher = new AnrWatcher(handler, mainThread, instrumenter); - for (int i = 0; i < 5; i++) { - int index = i; - when(handler.post(isA(Runnable.class))) - .thenAnswer( - invocation -> { - Runnable callback = invocation.getArgument(0); - // have it fail once - if (index != 3) { - callback.run(); - } - return true; - }); - anrWatcher.run(); - } - verifyNoInteractions(instrumenter); - } - - @Test - void anr_detected() { - StackTraceElement[] stackTrace = new StackTraceElement[0]; - when(mainThread.getStackTrace()).thenReturn(stackTrace); - - AnrWatcher anrWatcher = new AnrWatcher(handler, mainThread, instrumenter); - when(handler.post(isA(Runnable.class))).thenReturn(true); - for (int i = 0; i < 5; i++) { - anrWatcher.run(); - } - verify(instrumenter, times(1)).start(any(), same(stackTrace)); - verify(instrumenter, times(1)).end(any(), same(stackTrace), isNull(), isNull()); - for (int i = 0; i < 4; i++) { - anrWatcher.run(); - } - verifyNoMoreInteractions(instrumenter); - - anrWatcher.run(); - verify(instrumenter, times(2)).start(any(), same(stackTrace)); - verify(instrumenter, times(2)).end(any(), same(stackTrace), isNull(), isNull()); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/StackTraceFormatterTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/StackTraceFormatterTest.java deleted file mode 100644 index 4cc9e516..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/anr/StackTraceFormatterTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.anr; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.context.Context; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -import org.junit.jupiter.api.Test; - -class StackTraceFormatterTest { - - @Test - void shouldSerializeStackTrace() { - StackTraceElement[] stackTrace = - new StackTraceElement[] { - new StackTraceElement("a.b.Class", "foo", "/src/a/b/Class.java", 42), - new StackTraceElement( - "a.b.AnotherClass", "bar", "/src/a/b/AnotherClass.java", 123) - }; - StackTraceFormatter underTest = new StackTraceFormatter(); - - AttributesBuilder startAttributes = Attributes.builder(); - underTest.onStart(startAttributes, Context.current(), stackTrace); - assertThat(startAttributes.build()) - .hasSize(1) - .containsEntry( - SemanticAttributes.EXCEPTION_STACKTRACE, - "a.b.Class.foo(/src/a/b/Class.java:42)\n" - + "a.b.AnotherClass.bar(/src/a/b/AnotherClass.java:123)\n"); - - AttributesBuilder endAttributes = Attributes.builder(); - underTest.onEnd(endAttributes, Context.current(), stackTrace, null, null); - assertThat(endAttributes.build()).isEmpty(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporterTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporterTest.java deleted file mode 100644 index 130048f7..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReporterTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.crash; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor.constant; -import static org.awaitility.Awaitility.await; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.testing.assertj.TraceAssert; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import io.opentelemetry.sdk.trace.data.StatusData; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -import java.time.Duration; -import java.util.function.Consumer; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -class CrashReporterTest { - - @RegisterExtension - static final OpenTelemetryExtension testing = OpenTelemetryExtension.create(); - - static Thread.UncaughtExceptionHandler existingHandler; - - @BeforeAll - static void setUp() { - existingHandler = Thread.getDefaultUncaughtExceptionHandler(); - // disable the handler installed by junit - Thread.setDefaultUncaughtExceptionHandler(null); - } - - @AfterAll - static void tearDown() { - Thread.setDefaultUncaughtExceptionHandler(existingHandler); - } - - @Test - void integrationTest() throws InterruptedException { - InstrumentedApplication instrumentedApplication = mock(InstrumentedApplication.class); - when(instrumentedApplication.getOpenTelemetrySdk()) - .thenReturn((OpenTelemetrySdk) testing.getOpenTelemetry()); - - CrashReporter.builder() - .addAttributesExtractor(constant(stringKey("test.key"), "abc")) - .build() - .installOn(instrumentedApplication); - - RuntimeException crash = new RuntimeException("boooom!"); - Thread crashingThread = - new Thread( - () -> { - throw crash; - }); - crashingThread.setDaemon(true); - crashingThread.start(); - crashingThread.join(); - - Attributes expectedAttributes = - Attributes.builder() - .put(SemanticAttributes.EXCEPTION_ESCAPED, true) - .put(SemanticAttributes.THREAD_ID, crashingThread.getId()) - .put(SemanticAttributes.THREAD_NAME, crashingThread.getName()) - .put(stringKey("test.key"), "abc") - .build(); - assertTrace( - trace -> - trace.hasSpansSatisfyingExactly( - span -> - span.hasName("RuntimeException") - .hasKind(SpanKind.INTERNAL) - .hasStatus(StatusData.error()) - .hasException(crash) - .hasAttributes(expectedAttributes))); - } - - private static void assertTrace(Consumer assertion) { - await().atMost(Duration.ofSeconds(30)) - .untilAsserted(() -> testing.assertTraces().hasTracesSatisfyingExactly(assertion)); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReportingExceptionHandlerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReportingExceptionHandlerTest.java deleted file mode 100644 index 46466db5..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/crash/CrashReportingExceptionHandlerTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.crash; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.when; - -import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CrashReportingExceptionHandlerTest { - - @Mock Instrumenter instrumenter; - @Mock SdkTracerProvider sdkTracerProvider; - @Mock Thread.UncaughtExceptionHandler existingHandler; - @Mock CompletableResultCode flushResult; - - @Test - void shouldReportCrash() { - when(sdkTracerProvider.forceFlush()).thenReturn(flushResult); - - CrashReportingExceptionHandler handler = - new CrashReportingExceptionHandler( - instrumenter, sdkTracerProvider, existingHandler); - - NullPointerException oopsie = new NullPointerException("oopsie"); - Thread crashThread = new Thread("badThread"); - - handler.uncaughtException(crashThread, oopsie); - - CrashDetails crashDetails = CrashDetails.create(crashThread, oopsie); - InOrder io = inOrder(instrumenter, sdkTracerProvider, flushResult, existingHandler); - io.verify(instrumenter).start(Context.current(), crashDetails); - io.verify(instrumenter).end(any(), eq(crashDetails), isNull(), eq(oopsie)); - io.verify(sdkTracerProvider).forceFlush(); - io.verify(flushResult).join(10, TimeUnit.SECONDS); - io.verify(existingHandler).uncaughtException(crashThread, oopsie); - io.verifyNoMoreInteractions(); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentCallbackTestHarness.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentCallbackTestHarness.java deleted file mode 100644 index 9101d2d3..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentCallbackTestHarness.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.fragment; - -import static org.mockito.Mockito.mock; - -import android.content.Context; -import android.os.Bundle; -import android.view.View; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; - -class FragmentCallbackTestHarness { - - private final RumFragmentLifecycleCallbacks callbacks; - - FragmentCallbackTestHarness(RumFragmentLifecycleCallbacks callbacks) { - this.callbacks = callbacks; - } - - void runFragmentCreationLifecycle(Fragment fragment) { - Context context = mock(Context.class); - FragmentManager fragmentManager = mock(FragmentManager.class); - Bundle bundle = mock(Bundle.class); - - callbacks.onFragmentPreAttached(fragmentManager, fragment, context); - callbacks.onFragmentAttached(fragmentManager, fragment, context); - callbacks.onFragmentPreCreated(fragmentManager, fragment, bundle); - callbacks.onFragmentCreated(fragmentManager, fragment, bundle); - runFragmentRestoredLifecycle(fragment); - } - - void runFragmentRestoredLifecycle(Fragment fragment) { - FragmentManager fragmentManager = mock(FragmentManager.class); - Bundle bundle = mock(Bundle.class); - View view = mock(View.class); - callbacks.onFragmentViewCreated(fragmentManager, fragment, view, bundle); - callbacks.onFragmentStarted(fragmentManager, fragment); - callbacks.onFragmentResumed(fragmentManager, fragment); - } - - void runFragmentResumedLifecycle(Fragment fragment) { - FragmentManager fragmentManager = mock(FragmentManager.class); - callbacks.onFragmentResumed(fragmentManager, fragment); - } - - void runFragmentPausedLifecycle(Fragment fragment) { - FragmentManager fragmentManager = mock(FragmentManager.class); - callbacks.onFragmentPaused(fragmentManager, fragment); - callbacks.onFragmentStopped(fragmentManager, fragment); - } - - void runFragmentDetachedFromActiveLifecycle(Fragment fragment) { - FragmentManager fragmentManager = mock(FragmentManager.class); - - runFragmentPausedLifecycle(fragment); - callbacks.onFragmentViewDestroyed(fragmentManager, fragment); - callbacks.onFragmentDestroyed(fragmentManager, fragment); - runFragmentDetachedLifecycle(fragment); - } - - void runFragmentViewDestroyedFromStoppedLifecycle(Fragment fragment) { - FragmentManager fragmentManager = mock(FragmentManager.class); - - callbacks.onFragmentViewDestroyed(fragmentManager, fragment); - } - - void runFragmentDetachedFromStoppedLifecycle(Fragment fragment) { - FragmentManager fragmentManager = mock(FragmentManager.class); - - runFragmentViewDestroyedFromStoppedLifecycle(fragment); - callbacks.onFragmentDestroyed(fragmentManager, fragment); - runFragmentDetachedLifecycle(fragment); - } - - void runFragmentDetachedLifecycle(Fragment fragment) { - FragmentManager fragmentManager = mock(FragmentManager.class); - - callbacks.onFragmentDetached(fragmentManager, fragment); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentTracerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentTracerTest.java deleted file mode 100644 index 42dbf423..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/FragmentTracerTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.fragment; - -import static io.opentelemetry.rum.internal.RumConstants.LAST_SCREEN_NAME_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import androidx.fragment.app.Fragment; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.activity.VisibleScreenTracker; -import io.opentelemetry.rum.internal.util.ActiveSpan; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.util.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -class FragmentTracerTest { - @RegisterExtension final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); - private Tracer tracer; - private ActiveSpan activeSpan; - - @BeforeEach - void setup() { - tracer = otelTesting.getOpenTelemetry().getTracer("testTracer"); - VisibleScreenTracker visibleScreenTracker = mock(VisibleScreenTracker.class); - activeSpan = new ActiveSpan(visibleScreenTracker::getPreviouslyVisibleScreen); - } - - @Test - void create() { - FragmentTracer trackableTracer = - FragmentTracer.builder(mock(Fragment.class)) - .setTracer(tracer) - .setActiveSpan(activeSpan) - .build(); - trackableTracer.startFragmentCreation(); - trackableTracer.endActiveSpan(); - SpanData span = getSingleSpan(); - assertEquals("Created", span.getName()); - } - - @Test - void addPreviousScreen_noPrevious() { - VisibleScreenTracker visibleScreenTracker = mock(VisibleScreenTracker.class); - - FragmentTracer trackableTracer = - FragmentTracer.builder(mock(Fragment.class)) - .setTracer(tracer) - .setActiveSpan(activeSpan) - .build(); - - trackableTracer.startSpanIfNoneInProgress("starting"); - trackableTracer.addPreviousScreenAttribute(); - trackableTracer.endActiveSpan(); - - SpanData span = getSingleSpan(); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - } - - @Test - void addPreviousScreen_currentSameAsPrevious() { - VisibleScreenTracker visibleScreenTracker = mock(VisibleScreenTracker.class); - when(visibleScreenTracker.getPreviouslyVisibleScreen()).thenReturn("Fragment"); - - FragmentTracer trackableTracer = - FragmentTracer.builder(mock(Fragment.class)) - .setTracer(tracer) - .setActiveSpan(activeSpan) - .build(); - - trackableTracer.startSpanIfNoneInProgress("starting"); - trackableTracer.addPreviousScreenAttribute(); - trackableTracer.endActiveSpan(); - - SpanData span = getSingleSpan(); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - } - - @Test - void addPreviousScreen() { - - VisibleScreenTracker visibleScreenTracker = mock(VisibleScreenTracker.class); - when(visibleScreenTracker.getPreviouslyVisibleScreen()).thenReturn("previousScreen"); - activeSpan = new ActiveSpan(visibleScreenTracker::getPreviouslyVisibleScreen); - - FragmentTracer fragmentTracer = - FragmentTracer.builder(mock(Fragment.class)) - .setTracer(tracer) - .setActiveSpan(activeSpan) - .build(); - - fragmentTracer.startSpanIfNoneInProgress("starting"); - fragmentTracer.addPreviousScreenAttribute(); - fragmentTracer.endActiveSpan(); - - SpanData span = getSingleSpan(); - assertEquals("previousScreen", span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - } - - private SpanData getSingleSpan() { - List generatedSpans = otelTesting.getSpans(); - assertEquals(1, generatedSpans.size()); - return generatedSpans.get(0); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/RumFragmentLifecycleCallbacksTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/RumFragmentLifecycleCallbacksTest.java deleted file mode 100644 index 536c37f9..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/RumFragmentLifecycleCallbacksTest.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.fragment; - -import static io.opentelemetry.rum.internal.RumConstants.LAST_SCREEN_NAME_KEY; -import static io.opentelemetry.rum.internal.RumConstants.SCREEN_NAME_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import androidx.fragment.app.Fragment; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.instrumentation.ScreenNameExtractor; -import io.opentelemetry.rum.internal.instrumentation.activity.VisibleScreenTracker; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import io.opentelemetry.sdk.trace.data.EventData; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.util.List; -import java.util.Optional; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class RumFragmentLifecycleCallbacksTest { - @RegisterExtension final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); - private final VisibleScreenTracker visibleScreenTracker = mock(VisibleScreenTracker.class); - private Tracer tracer; - @Mock private ScreenNameExtractor screenNameExtractor; - - @BeforeEach - void setup() { - tracer = otelTesting.getOpenTelemetry().getTracer("testTracer"); - when(screenNameExtractor.extract(isA(Fragment.class))).thenReturn("Fragment"); - } - - @Test - void fragmentCreation() { - FragmentCallbackTestHarness testHarness = - new FragmentCallbackTestHarness( - new RumFragmentLifecycleCallbacks( - tracer, visibleScreenTracker, screenNameExtractor)); - - Fragment fragment = mock(Fragment.class); - testHarness.runFragmentCreationLifecycle(fragment); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData spanData = spans.get(0); - - assertEquals("Created", spanData.getName()); - assertEquals( - fragment.getClass().getSimpleName(), - spanData.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertEquals( - fragment.getClass().getSimpleName(), spanData.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(spanData.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = spanData.getEvents(); - assertEquals(7, events.size()); - checkEventExists(events, "fragmentPreAttached"); - checkEventExists(events, "fragmentAttached"); - checkEventExists(events, "fragmentPreCreated"); - checkEventExists(events, "fragmentCreated"); - checkEventExists(events, "fragmentViewCreated"); - checkEventExists(events, "fragmentStarted"); - checkEventExists(events, "fragmentResumed"); - } - - @Test - void fragmentRestored() { - when(visibleScreenTracker.getPreviouslyVisibleScreen()).thenReturn("previousScreen"); - FragmentCallbackTestHarness testHarness = - new FragmentCallbackTestHarness( - new RumFragmentLifecycleCallbacks( - tracer, visibleScreenTracker, screenNameExtractor)); - - Fragment fragment = mock(Fragment.class); - testHarness.runFragmentRestoredLifecycle(fragment); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData spanData = spans.get(0); - - assertEquals("Restored", spanData.getName()); - assertEquals( - fragment.getClass().getSimpleName(), - spanData.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertEquals( - fragment.getClass().getSimpleName(), spanData.getAttributes().get(SCREEN_NAME_KEY)); - assertEquals("previousScreen", spanData.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = spanData.getEvents(); - assertEquals(3, events.size()); - checkEventExists(events, "fragmentViewCreated"); - checkEventExists(events, "fragmentStarted"); - checkEventExists(events, "fragmentResumed"); - } - - @Test - void fragmentResumed() { - FragmentCallbackTestHarness testHarness = - new FragmentCallbackTestHarness( - new RumFragmentLifecycleCallbacks( - tracer, visibleScreenTracker, screenNameExtractor)); - - Fragment fragment = mock(Fragment.class); - testHarness.runFragmentResumedLifecycle(fragment); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData spanData = spans.get(0); - - assertEquals("Resumed", spanData.getName()); - assertEquals( - fragment.getClass().getSimpleName(), - spanData.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertNull(spanData.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = spanData.getEvents(); - assertEquals(1, events.size()); - checkEventExists(events, "fragmentResumed"); - } - - @Test - void fragmentPaused() { - FragmentCallbackTestHarness testHarness = - new FragmentCallbackTestHarness( - new RumFragmentLifecycleCallbacks( - tracer, visibleScreenTracker, screenNameExtractor)); - - Fragment fragment = mock(Fragment.class); - testHarness.runFragmentPausedLifecycle(fragment); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData spanData = spans.get(0); - - assertEquals("Paused", spanData.getName()); - assertEquals( - fragment.getClass().getSimpleName(), - spanData.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertEquals( - fragment.getClass().getSimpleName(), spanData.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(spanData.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = spanData.getEvents(); - assertEquals(2, events.size()); - checkEventExists(events, "fragmentPaused"); - checkEventExists(events, "fragmentStopped"); - } - - @Test - void fragmentDetachedFromActive() { - FragmentCallbackTestHarness testHarness = - new FragmentCallbackTestHarness( - new RumFragmentLifecycleCallbacks( - tracer, visibleScreenTracker, screenNameExtractor)); - - Fragment fragment = mock(Fragment.class); - testHarness.runFragmentDetachedFromActiveLifecycle(fragment); - - List spans = otelTesting.getSpans(); - assertEquals(3, spans.size()); - - SpanData pauseSpan = spans.get(0); - - assertEquals("Paused", pauseSpan.getName()); - assertEquals( - fragment.getClass().getSimpleName(), - pauseSpan.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertEquals( - fragment.getClass().getSimpleName(), - pauseSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(pauseSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = pauseSpan.getEvents(); - assertEquals(2, events.size()); - checkEventExists(events, "fragmentPaused"); - checkEventExists(events, "fragmentStopped"); - - SpanData destroyViewSpan = spans.get(1); - - assertEquals("ViewDestroyed", destroyViewSpan.getName()); - assertEquals( - fragment.getClass().getSimpleName(), - destroyViewSpan.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertEquals( - fragment.getClass().getSimpleName(), - destroyViewSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertNull(destroyViewSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - events = destroyViewSpan.getEvents(); - assertEquals(1, events.size()); - checkEventExists(events, "fragmentViewDestroyed"); - - SpanData detachSpan = spans.get(2); - - assertEquals("Destroyed", detachSpan.getName()); - assertNotNull(detachSpan.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertNull(detachSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - events = detachSpan.getEvents(); - assertEquals(2, events.size()); - checkEventExists(events, "fragmentDestroyed"); - checkEventExists(events, "fragmentDetached"); - } - - @Test - void fragmentDestroyedFromStopped() { - FragmentCallbackTestHarness testHarness = - new FragmentCallbackTestHarness( - new RumFragmentLifecycleCallbacks( - tracer, visibleScreenTracker, screenNameExtractor)); - - Fragment fragment = mock(Fragment.class); - testHarness.runFragmentViewDestroyedFromStoppedLifecycle(fragment); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData span = spans.get(0); - - assertEquals("ViewDestroyed", span.getName()); - assertEquals( - fragment.getClass().getSimpleName(), span.getAttributes().get(SCREEN_NAME_KEY)); - assertEquals( - fragment.getClass().getSimpleName(), - span.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertNull(span.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = span.getEvents(); - assertEquals(1, events.size()); - checkEventExists(events, "fragmentViewDestroyed"); - } - - @Test - void fragmentDetachedFromStopped() { - FragmentCallbackTestHarness testHarness = - new FragmentCallbackTestHarness( - new RumFragmentLifecycleCallbacks( - tracer, visibleScreenTracker, screenNameExtractor)); - - Fragment fragment = mock(Fragment.class); - testHarness.runFragmentDetachedFromStoppedLifecycle(fragment); - - List spans = otelTesting.getSpans(); - assertEquals(2, spans.size()); - - SpanData destroyViewSpan = spans.get(0); - - assertEquals("ViewDestroyed", destroyViewSpan.getName()); - assertEquals( - fragment.getClass().getSimpleName(), - destroyViewSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertEquals( - fragment.getClass().getSimpleName(), - destroyViewSpan.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertNull(destroyViewSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = destroyViewSpan.getEvents(); - assertEquals(1, events.size()); - checkEventExists(events, "fragmentViewDestroyed"); - - SpanData detachSpan = spans.get(1); - - assertEquals("Destroyed", detachSpan.getName()); - assertEquals( - fragment.getClass().getSimpleName(), - detachSpan.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertNull(detachSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - events = detachSpan.getEvents(); - assertEquals(2, events.size()); - checkEventExists(events, "fragmentDestroyed"); - checkEventExists(events, "fragmentDetached"); - } - - @Test - void fragmentDetached() { - FragmentCallbackTestHarness testHarness = - new FragmentCallbackTestHarness( - new RumFragmentLifecycleCallbacks( - tracer, visibleScreenTracker, screenNameExtractor)); - - Fragment fragment = mock(Fragment.class); - testHarness.runFragmentDetachedLifecycle(fragment); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - - SpanData detachSpan = spans.get(0); - - assertEquals("Detached", detachSpan.getName()); - assertEquals( - fragment.getClass().getSimpleName(), - detachSpan.getAttributes().get(SCREEN_NAME_KEY)); - assertEquals( - fragment.getClass().getSimpleName(), - detachSpan.getAttributes().get(FragmentTracer.FRAGMENT_NAME_KEY)); - assertNull(detachSpan.getAttributes().get(LAST_SCREEN_NAME_KEY)); - - List events = detachSpan.getEvents(); - assertEquals(1, events.size()); - checkEventExists(events, "fragmentDetached"); - } - - private void checkEventExists(List events, String eventName) { - Optional event = - events.stream().filter(e -> e.getName().equals(eventName)).findAny(); - assertTrue(event.isPresent(), "Event with name " + eventName + " not found"); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/ScreenNameExtractorTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/ScreenNameExtractorTest.java deleted file mode 100644 index e17b865a..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/fragment/ScreenNameExtractorTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.fragment; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import android.app.Activity; -import androidx.fragment.app.Fragment; -import io.opentelemetry.rum.internal.instrumentation.RumScreenName; -import io.opentelemetry.rum.internal.instrumentation.ScreenNameExtractor; -import org.junit.jupiter.api.Test; - -class ScreenNameExtractorTest { - - @Test - void testActivity() { - Activity activity = new Activity(); - String name = ScreenNameExtractor.DEFAULT.extract(activity); - assertEquals("Activity", name); - } - - @Test - void testFragment() { - Fragment fragment = new Fragment(); - String name = ScreenNameExtractor.DEFAULT.extract(fragment); - assertEquals("Fragment", name); - } - - @Test - void testAnnotatedActivity() { - Activity activity = new AnnotatedActivity(); - String name = ScreenNameExtractor.DEFAULT.extract(activity); - assertEquals("squarely", name); - } - - @Test - void testAnnotatedFragment() { - Fragment fragment = new AnnotatedFragment(); - String name = ScreenNameExtractor.DEFAULT.extract(fragment); - assertEquals("bumpity", name); - } - - @RumScreenName("bumpity") - static class AnnotatedFragment extends Fragment {} - - @RumScreenName("squarely") - static class AnnotatedActivity extends Activity {} -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CarrierFinderTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CarrierFinderTest.java deleted file mode 100644 index 805b98a0..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CarrierFinderTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.telephony.TelephonyManager; -import org.junit.jupiter.api.Test; - -class CarrierFinderTest { - - @Test - void testSimpleGet() { - Carrier expected = - Carrier.builder() - .id(206) - .name("ShadyTel") - .isoCountryCode("US") - .mobileCountryCode("usa") - .mobileNetworkCode("omg") - .build(); - - TelephonyManager manager = mock(TelephonyManager.class); - when(manager.getSimCarrierId()).thenReturn(expected.getId()); - when(manager.getSimCarrierIdName()).thenReturn(expected.getName()); - when(manager.getSimCountryIso()).thenReturn(expected.getIsoCountryCode()); - when(manager.getSimOperator()) - .thenReturn(expected.getMobileCountryCode() + expected.getMobileNetworkCode()); - - CarrierFinder finder = new CarrierFinder(manager); - Carrier carrier = finder.get(); - assertThat(carrier).isEqualTo(expected); - } - - @Test - void testMostlyInvalid() { - Carrier expected = Carrier.builder().build(); - - TelephonyManager manager = mock(TelephonyManager.class); - when(manager.getSimCarrierId()).thenReturn(-1); - when(manager.getSimCarrierIdName()).thenReturn(null); - when(manager.getSimCountryIso()).thenReturn(null); - when(manager.getSimOperator()).thenReturn(null); - - CarrierFinder finder = new CarrierFinder(manager); - Carrier carrier = finder.get(); - assertThat(carrier).isEqualTo(expected); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkAttributesExtractorTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkAttributesExtractorTest.java deleted file mode 100644 index 9df8d881..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkAttributesExtractorTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.entry; - -import android.os.Build; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -public class CurrentNetworkAttributesExtractorTest { - - final CurrentNetworkAttributesExtractor underTest = new CurrentNetworkAttributesExtractor(); - - @Config(sdk = Build.VERSION_CODES.P) - @Test - public void getNetworkAttributes_withCarrier() { - CurrentNetwork currentNetwork = - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .subType("aaa") - .carrier( - Carrier.builder() - .id(206) - .name("ShadyTel") - .isoCountryCode("US") - .mobileCountryCode("usa") - .mobileNetworkCode("omg") - .build()) - .build(); - - assertThat(underTest.extract(currentNetwork)) - .containsOnly( - entry(SemanticAttributes.NET_HOST_CONNECTION_TYPE, "cell"), - entry(SemanticAttributes.NET_HOST_CONNECTION_SUBTYPE, "aaa"), - entry(SemanticAttributes.NET_HOST_CARRIER_NAME, "ShadyTel"), - entry(SemanticAttributes.NET_HOST_CARRIER_ICC, "US"), - entry(SemanticAttributes.NET_HOST_CARRIER_MCC, "usa"), - entry(SemanticAttributes.NET_HOST_CARRIER_MNC, "omg")); - } - - @Config(sdk = Build.VERSION_CODES.O) - @Test - public void getNetworkAttributes_withoutCarrier() { - CurrentNetwork currentNetwork = - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .subType("aaa") - .carrier(Carrier.builder().id(42).name("ShadyTel").build()) - .build(); - - assertThat(underTest.extract(currentNetwork)) - .containsOnly( - entry(SemanticAttributes.NET_HOST_CONNECTION_TYPE, "cell"), - entry(SemanticAttributes.NET_HOST_CONNECTION_SUBTYPE, "aaa")); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkProviderTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkProviderTest.java deleted file mode 100644 index 435b0c1e..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/CurrentNetworkProviderTest.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.net.ConnectivityManager; -import android.net.ConnectivityManager.NetworkCallback; -import android.net.Network; -import android.net.NetworkRequest; -import android.os.Build; -import java.util.concurrent.atomic.AtomicInteger; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -@Config(maxSdk = Build.VERSION_CODES.S) -public class CurrentNetworkProviderTest { - - @Test - @Config(maxSdk = Build.VERSION_CODES.LOLLIPOP) - public void lollipop() { - NetworkRequest networkRequest = mock(NetworkRequest.class); - NetworkDetector networkDetector = mock(NetworkDetector.class); - ConnectivityManager connectivityManager = mock(ConnectivityManager.class); - - when(networkDetector.detectCurrentNetwork()) - .thenReturn( - CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI) - .build()) // called on init - .thenReturn( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .subType("LTE") - .build()); - - CurrentNetworkProvider currentNetworkProvider = new CurrentNetworkProvider(networkDetector); - currentNetworkProvider.startMonitoring(() -> networkRequest, connectivityManager); - - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build(), - currentNetworkProvider.getCurrentNetwork()); - - ArgumentCaptor monitorCaptor = - ArgumentCaptor.forClass(NetworkCallback.class); - verify(connectivityManager) - .registerNetworkCallback(eq(networkRequest), monitorCaptor.capture()); - - AtomicInteger notified = new AtomicInteger(0); - currentNetworkProvider.addNetworkChangeListener( - (currentNetwork) -> { - int timesCalled = notified.incrementAndGet(); - if (timesCalled == 1) { - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .subType("LTE") - .build(), - currentNetwork); - } else { - assertEquals( - CurrentNetwork.builder(NetworkState.NO_NETWORK_AVAILABLE).build(), - currentNetwork); - } - }); - // note: we ignore the network passed in and just rely on refreshing the network info when - // this is happens - monitorCaptor.getValue().onAvailable(null); - assertEquals(1, notified.get()); - monitorCaptor.getValue().onLost(null); - assertEquals(2, notified.get()); - } - - @Test - @Config(maxSdk = Build.VERSION_CODES.S, minSdk = Build.VERSION_CODES.O) - public void modernSdks() { - NetworkRequest networkRequest = mock(NetworkRequest.class); - NetworkDetector networkDetector = mock(NetworkDetector.class); - ConnectivityManager connectivityManager = mock(ConnectivityManager.class); - - when(networkDetector.detectCurrentNetwork()) - .thenReturn(CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build()) - .thenReturn( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .subType("LTE") - .build()); - - CurrentNetworkProvider currentNetworkProvider = new CurrentNetworkProvider(networkDetector); - currentNetworkProvider.startMonitoring(() -> networkRequest, connectivityManager); - - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build(), - currentNetworkProvider.getCurrentNetwork()); - verify(connectivityManager, never()) - .registerNetworkCallback(eq(networkRequest), isA(NetworkCallback.class)); - - ArgumentCaptor monitorCaptor = - ArgumentCaptor.forClass(NetworkCallback.class); - verify(connectivityManager).registerDefaultNetworkCallback(monitorCaptor.capture()); - - AtomicInteger notified = new AtomicInteger(0); - currentNetworkProvider.addNetworkChangeListener( - (currentNetwork) -> { - int timesCalled = notified.incrementAndGet(); - if (timesCalled == 1) { - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .subType("LTE") - .build(), - currentNetwork); - } else { - assertEquals( - CurrentNetwork.builder(NetworkState.NO_NETWORK_AVAILABLE).build(), - currentNetwork); - } - }); - // note: we ignore the network passed in and just rely on refreshing the network info when - // this is happens - monitorCaptor.getValue().onAvailable(null); - assertEquals(1, notified.get()); - monitorCaptor.getValue().onLost(null); - assertEquals(2, notified.get()); - } - - @Test - public void networkDetectorException() { - NetworkDetector networkDetector = mock(NetworkDetector.class); - when(networkDetector.detectCurrentNetwork()).thenThrow(new SecurityException("bug")); - - CurrentNetworkProvider currentNetworkProvider = new CurrentNetworkProvider(networkDetector); - assertEquals( - CurrentNetworkProvider.UNKNOWN_NETWORK, - currentNetworkProvider.refreshNetworkStatus()); - } - - @Test - @Config(maxSdk = Build.VERSION_CODES.S, minSdk = Build.VERSION_CODES.O) - public void networkDetectorExceptionOnCallbackRegistration() { - NetworkDetector networkDetector = mock(NetworkDetector.class); - ConnectivityManager connectivityManager = mock(ConnectivityManager.class); - - when(networkDetector.detectCurrentNetwork()) - .thenReturn(CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build()); - doThrow(new SecurityException("bug")) - .when(connectivityManager) - .registerDefaultNetworkCallback(isA(NetworkCallback.class)); - - CurrentNetworkProvider currentNetworkProvider = new CurrentNetworkProvider(networkDetector); - currentNetworkProvider.startMonitoring( - () -> mock(NetworkRequest.class), connectivityManager); - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build(), - currentNetworkProvider.refreshNetworkStatus()); - } - - @Test - @Config(maxSdk = Build.VERSION_CODES.LOLLIPOP) - public void networkDetectorExceptionOnCallbackRegistration_lollipop() { - NetworkDetector networkDetector = mock(NetworkDetector.class); - ConnectivityManager connectivityManager = mock(ConnectivityManager.class); - NetworkRequest networkRequest = mock(NetworkRequest.class); - - when(networkDetector.detectCurrentNetwork()) - .thenReturn(CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build()); - doThrow(new SecurityException("bug")) - .when(connectivityManager) - .registerNetworkCallback(eq(networkRequest), isA(NetworkCallback.class)); - - CurrentNetworkProvider currentNetworkProvider = new CurrentNetworkProvider(networkDetector); - currentNetworkProvider.startMonitoring(() -> networkRequest, connectivityManager); - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build(), - currentNetworkProvider.refreshNetworkStatus()); - } - - @Test - @Config(maxSdk = Build.VERSION_CODES.LOLLIPOP) - public void shouldNotFailOnImmediateConnectionManagerCall_lollipop() { - NetworkRequest networkRequest = mock(NetworkRequest.class); - NetworkDetector networkDetector = mock(NetworkDetector.class); - ConnectivityManager connectivityManager = mock(ConnectivityManager.class); - - doAnswer( - invocation -> { - NetworkCallback callback = invocation.getArgument(1); - callback.onAvailable(mock(Network.class)); - return null; - }) - .when(connectivityManager) - .registerNetworkCallback(eq(networkRequest), any(NetworkCallback.class)); - - CurrentNetworkProvider currentNetworkProvider = new CurrentNetworkProvider(networkDetector); - currentNetworkProvider.startMonitoring(() -> networkRequest, connectivityManager); - } - - @Test - @Config(maxSdk = Build.VERSION_CODES.S, minSdk = Build.VERSION_CODES.O) - public void shouldNotFailOnImmediateConnectionManagerCall() { - NetworkRequest networkRequest = mock(NetworkRequest.class); - NetworkDetector networkDetector = mock(NetworkDetector.class); - ConnectivityManager connectivityManager = mock(ConnectivityManager.class); - - doAnswer( - invocation -> { - NetworkCallback callback = invocation.getArgument(0); - callback.onAvailable(mock(Network.class)); - return null; - }) - .when(connectivityManager) - .registerDefaultNetworkCallback(any(NetworkCallback.class)); - - CurrentNetworkProvider currentNetworkProvider = new CurrentNetworkProvider(networkDetector); - currentNetworkProvider.startMonitoring(() -> networkRequest, connectivityManager); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkAttributesSpanAppenderTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkAttributesSpanAppenderTest.java deleted file mode 100644 index 4cb37f12..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkAttributesSpanAppenderTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class NetworkAttributesSpanAppenderTest { - - @Mock CurrentNetworkProvider currentNetworkProvider; - @Mock ReadWriteSpan span; - - @InjectMocks NetworkAttributesSpanAppender underTest; - - @Test - void shouldAppendNetworkAttributes() { - when(currentNetworkProvider.getCurrentNetwork()) - .thenReturn( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .subType("LTE") - .build()); - - assertTrue(underTest.isStartRequired()); - underTest.onStart(Context.current(), span); - - verify(span) - .setAllAttributes( - Attributes.of( - SemanticAttributes.NET_HOST_CONNECTION_TYPE, "cell", - SemanticAttributes.NET_HOST_CONNECTION_SUBTYPE, "LTE")); - - assertFalse(underTest.isEndRequired()); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitorTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitorTest.java deleted file mode 100644 index 03717634..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkChangeMonitorTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.os.Build; -import io.opentelemetry.rum.internal.instrumentation.ApplicationStateListener; -import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.testing.junit4.OpenTelemetryRule; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -import java.util.List; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@Config(sdk = Build.VERSION_CODES.P) -@RunWith(RobolectricTestRunner.class) -public class NetworkChangeMonitorTest { - - @Rule public OpenTelemetryRule otelTesting = OpenTelemetryRule.create(); - - @Captor ArgumentCaptor applicationStateListenerCaptor; - @Captor ArgumentCaptor networkChangeListenerCaptor; - - @Mock CurrentNetworkProvider currentNetworkProvider; - @Mock InstrumentedApplication instrumentedApplication; - - AutoCloseable mocks; - - @Before - public void setUp() { - mocks = MockitoAnnotations.openMocks(this); - when(instrumentedApplication.getOpenTelemetrySdk()) - .thenReturn((OpenTelemetrySdk) otelTesting.getOpenTelemetry()); - } - - @After - public void tearDown() throws Exception { - mocks.close(); - } - - @Test - public void networkAvailable_wifi() { - NetworkChangeMonitor.create(currentNetworkProvider).installOn(instrumentedApplication); - - verify(currentNetworkProvider) - .addNetworkChangeListener(networkChangeListenerCaptor.capture()); - NetworkChangeListener listener = networkChangeListenerCaptor.getValue(); - - listener.onNetworkChange(CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build()); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - assertThat(spans.get(0)) - .hasName("network.change") - .hasAttributesSatisfyingExactly( - equalTo(NetworkApplicationListener.NETWORK_STATUS_KEY, "available"), - equalTo(SemanticAttributes.NET_HOST_CONNECTION_TYPE, "wifi")); - } - - @Test - public void networkAvailable_cellular() { - NetworkChangeMonitor.create(currentNetworkProvider).installOn(instrumentedApplication); - - verify(currentNetworkProvider) - .addNetworkChangeListener(networkChangeListenerCaptor.capture()); - NetworkChangeListener listener = networkChangeListenerCaptor.getValue(); - - CurrentNetwork network = - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .subType("LTE") - .carrier( - Carrier.builder() - .id(206) - .name("ShadyTel") - .isoCountryCode("US") - .mobileCountryCode("usa") - .mobileNetworkCode("omg") - .build()) - .build(); - - listener.onNetworkChange(network); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - assertThat(spans.get(0)) - .hasName("network.change") - .hasAttributesSatisfyingExactly( - equalTo(NetworkApplicationListener.NETWORK_STATUS_KEY, "available"), - equalTo(SemanticAttributes.NET_HOST_CONNECTION_TYPE, "cell"), - equalTo(SemanticAttributes.NET_HOST_CONNECTION_SUBTYPE, "LTE"), - equalTo(SemanticAttributes.NET_HOST_CARRIER_NAME, "ShadyTel"), - equalTo(SemanticAttributes.NET_HOST_CARRIER_ICC, "US"), - equalTo(SemanticAttributes.NET_HOST_CARRIER_MCC, "usa"), - equalTo(SemanticAttributes.NET_HOST_CARRIER_MNC, "omg")); - } - - @Test - public void networkLost() { - NetworkChangeMonitor.create(currentNetworkProvider).installOn(instrumentedApplication); - - verify(currentNetworkProvider) - .addNetworkChangeListener(networkChangeListenerCaptor.capture()); - NetworkChangeListener listener = networkChangeListenerCaptor.getValue(); - - listener.onNetworkChange(CurrentNetwork.builder(NetworkState.NO_NETWORK_AVAILABLE).build()); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - assertThat(spans.get(0)) - .hasName("network.change") - .hasAttributesSatisfyingExactly( - equalTo(NetworkApplicationListener.NETWORK_STATUS_KEY, "lost"), - equalTo(SemanticAttributes.NET_HOST_CONNECTION_TYPE, "unavailable")); - } - - @Test - public void noEventsPlease() { - NetworkChangeMonitor.create(currentNetworkProvider).installOn(instrumentedApplication); - - verify(currentNetworkProvider) - .addNetworkChangeListener(networkChangeListenerCaptor.capture()); - NetworkChangeListener networkListener = networkChangeListenerCaptor.getValue(); - - verify(instrumentedApplication) - .registerApplicationStateListener(applicationStateListenerCaptor.capture()); - ApplicationStateListener applicationListener = applicationStateListenerCaptor.getValue(); - - applicationListener.onApplicationBackgrounded(); - - networkListener.onNetworkChange( - CurrentNetwork.builder(NetworkState.NO_NETWORK_AVAILABLE).build()); - assertTrue(otelTesting.getSpans().isEmpty()); - networkListener.onNetworkChange( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR).subType("LTE").build()); - assertTrue(otelTesting.getSpans().isEmpty()); - - applicationListener.onApplicationForegrounded(); - - networkListener.onNetworkChange( - CurrentNetwork.builder(NetworkState.NO_NETWORK_AVAILABLE).build()); - assertEquals(1, otelTesting.getSpans().size()); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkDetectorTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkDetectorTest.java deleted file mode 100644 index 28cb8b5f..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/NetworkDetectorTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static org.junit.Assert.assertTrue; - -import android.content.Context; -import android.os.Build; -import androidx.test.core.app.ApplicationProvider; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -public class NetworkDetectorTest { - - @Test - @Config(sdk = Build.VERSION_CODES.Q) - public void quiznos() { - Context context = ApplicationProvider.getApplicationContext(); - - NetworkDetector networkDetector = NetworkDetector.create(context); - assertTrue(networkDetector instanceof PostApi28NetworkDetector); - } - - @Test - @Config(sdk = Build.VERSION_CODES.LOLLIPOP) - public void lollipop() { - Context context = ApplicationProvider.getApplicationContext(); - - NetworkDetector networkDetector = NetworkDetector.create(context); - assertTrue(networkDetector instanceof SimpleNetworkDetector); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/PostApi28NetworkDetectorTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/PostApi28NetworkDetectorTest.java deleted file mode 100644 index c925f2fc..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/PostApi28NetworkDetectorTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.os.Build; -import android.telephony.TelephonyManager; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -@Config(sdk = Build.VERSION_CODES.P) -public class PostApi28NetworkDetectorTest { - - ConnectivityManager connectivityManager; - TelephonyManager telephonyManager; - Context context; - Network network; - NetworkCapabilities networkCapabilities; - CarrierFinder carrierFinder; - - @Before - public void setup() { - connectivityManager = mock(ConnectivityManager.class); - telephonyManager = mock(TelephonyManager.class); - context = mock(Context.class); - network = mock(Network.class); - carrierFinder = mock(CarrierFinder.class); - networkCapabilities = mock(NetworkCapabilities.class); - - when(connectivityManager.getActiveNetwork()).thenReturn(network); - when(connectivityManager.getNetworkCapabilities(network)).thenReturn(networkCapabilities); - } - - @Test - public void none() { - when(connectivityManager.getNetworkCapabilities(network)).thenReturn(null); - - PostApi28NetworkDetector networkDetector = - new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context); - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - assertEquals( - CurrentNetwork.builder(NetworkState.NO_NETWORK_AVAILABLE).build(), currentNetwork); - } - - @Test - public void wifi() { - when(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)).thenReturn(true); - - PostApi28NetworkDetector networkDetector = - new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context); - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - assertEquals(CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build(), currentNetwork); - } - - @Test - public void cellular() { - when(telephonyManager.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE); - when(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) - .thenReturn(true); - - PostApi28NetworkDetector networkDetector = - new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context); - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR).subType("LTE").build(), - currentNetwork); - } - - @Test - public void cellular_noTelephonyPermissions() { - when(telephonyManager.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE); - when(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) - .thenReturn(true); - - PostApi28NetworkDetector networkDetector = - new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context) { - @Override - boolean hasPermission(String permission) { - return false; - } - }; - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR).build(), currentNetwork); - } - - @Test - public void other() { - PostApi28NetworkDetector networkDetector = - new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context); - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_UNKNOWN).build(), currentNetwork); - } - - @Test - public void vpn() { - when(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)).thenReturn(true); - - PostApi28NetworkDetector networkDetector = - new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context); - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - assertEquals(CurrentNetwork.builder(NetworkState.TRANSPORT_VPN).build(), currentNetwork); - } - - @Test - public void carrierIsSet() { - Carrier carrier = Carrier.builder().name("flib").build(); - when(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) - .thenReturn(true); - when(carrierFinder.get()).thenReturn(carrier); - PostApi28NetworkDetector networkDetector = - new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context); - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - assertThat(currentNetwork.getCarrierName()).isEqualTo("flib"); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/SimpleNetworkDetectorTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/SimpleNetworkDetectorTest.java deleted file mode 100644 index 04a9c541..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/network/SimpleNetworkDetectorTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.network; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.Build; -import androidx.test.core.app.ApplicationProvider; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.Shadows; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowNetworkInfo; - -@RunWith(RobolectricTestRunner.class) -@Config(sdk = Build.VERSION_CODES.P) -public class SimpleNetworkDetectorTest { - @Test - public void none() { - ConnectivityManager connectivityManager = - (ConnectivityManager) - ApplicationProvider.getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - - Shadows.shadowOf(connectivityManager).setActiveNetworkInfo(null); - SimpleNetworkDetector networkDetector = new SimpleNetworkDetector(connectivityManager); - - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - - assertEquals( - CurrentNetwork.builder(NetworkState.NO_NETWORK_AVAILABLE).build(), currentNetwork); - } - - @Test - public void other() { - ConnectivityManager connectivityManager = - (ConnectivityManager) - ApplicationProvider.getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - - NetworkInfo networkInfo = - ShadowNetworkInfo.newInstance( - NetworkInfo.DetailedState.CONNECTED, - ConnectivityManager.TYPE_DUMMY, - 0, - true, - NetworkInfo.State.CONNECTED); - Shadows.shadowOf(connectivityManager).setActiveNetworkInfo(networkInfo); - - SimpleNetworkDetector networkDetector = new SimpleNetworkDetector(connectivityManager); - - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_UNKNOWN).build(), currentNetwork); - } - - @Test - public void wifi() { - ConnectivityManager connectivityManager = - (ConnectivityManager) - ApplicationProvider.getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - - NetworkInfo networkInfo = - ShadowNetworkInfo.newInstance( - NetworkInfo.DetailedState.CONNECTED, - ConnectivityManager.TYPE_WIFI, - 0, - true, - NetworkInfo.State.CONNECTED); - Shadows.shadowOf(connectivityManager).setActiveNetworkInfo(networkInfo); - - SimpleNetworkDetector networkDetector = new SimpleNetworkDetector(connectivityManager); - - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - - assertEquals(CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build(), currentNetwork); - } - - @Test - public void vpn() { - ConnectivityManager connectivityManager = - (ConnectivityManager) - ApplicationProvider.getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - - NetworkInfo networkInfo = - ShadowNetworkInfo.newInstance( - NetworkInfo.DetailedState.CONNECTED, - ConnectivityManager.TYPE_VPN, - 0, - true, - NetworkInfo.State.CONNECTED); - Shadows.shadowOf(connectivityManager).setActiveNetworkInfo(networkInfo); - - SimpleNetworkDetector networkDetector = new SimpleNetworkDetector(connectivityManager); - - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - - assertEquals(CurrentNetwork.builder(NetworkState.TRANSPORT_VPN).build(), currentNetwork); - } - - @Test - public void cellularWithSubtype() { - ConnectivityManager connectivityManager = - (ConnectivityManager) - ApplicationProvider.getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - - // note: looks like the ShadowNetworkInfo doesn't support setting subtype name. - NetworkInfo networkInfo = mock(NetworkInfo.class); - when(networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); - when(networkInfo.getSubtypeName()).thenReturn("LTE"); - - Shadows.shadowOf(connectivityManager).setActiveNetworkInfo(networkInfo); - - SimpleNetworkDetector networkDetector = new SimpleNetworkDetector(connectivityManager); - - CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - - assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR).subType("LTE").build(), - currentNetwork); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderListenerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderListenerTest.java deleted file mode 100644 index f229f6fa..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/slowrendering/SlowRenderListenerTest.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.slowrendering; - -import static android.view.FrameMetrics.DRAW_DURATION; -import static android.view.FrameMetrics.FIRST_DRAW_FRAME; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.app.Application; -import android.content.ComponentName; -import android.os.Build; -import android.os.Handler; -import android.view.FrameMetrics; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.sdk.testing.junit4.OpenTelemetryRule; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.time.Duration; -import java.util.List; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -@Config(sdk = Build.VERSION_CODES.N) -public class SlowRenderListenerTest { - - private static final AttributeKey COUNT_KEY = AttributeKey.longKey("count"); - - @Rule public OpenTelemetryRule otelTesting = OpenTelemetryRule.create(); - @Rule public MockitoRule mocks = MockitoJUnit.rule(); - - @Mock Handler frameMetricsHandler; - @Mock Application application; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - Activity activity; - - @Mock FrameMetrics frameMetrics; - Tracer tracer; - - @Captor ArgumentCaptor activityListenerCaptor; - - @Before - public void setup() { - tracer = otelTesting.getOpenTelemetry().getTracer("testTracer"); - ComponentName componentName = new ComponentName("io.otel", "Komponent"); - when(activity.getComponentName()).thenReturn(componentName); - } - - @Test - public void add() { - SlowRenderListener testInstance = - new SlowRenderListener(tracer, null, frameMetricsHandler, Duration.ZERO); - - testInstance.onActivityResumed(activity); - - verify(activity.getWindow()) - .addOnFrameMetricsAvailableListener( - activityListenerCaptor.capture(), eq(frameMetricsHandler)); - assertEquals("io.otel/Komponent", activityListenerCaptor.getValue().getActivityName()); - } - - @Test - public void removeBeforeAddOk() { - SlowRenderListener testInstance = - new SlowRenderListener(tracer, null, frameMetricsHandler, Duration.ZERO); - - testInstance.onActivityPaused(activity); - - verifyNoInteractions(activity); - assertThat(otelTesting.getSpans()).hasSize(0); - } - - @Test - public void addAndRemove() { - SlowRenderListener testInstance = - new SlowRenderListener(tracer, null, frameMetricsHandler, Duration.ZERO); - - testInstance.onActivityResumed(activity); - testInstance.onActivityPaused(activity); - - verify(activity.getWindow()) - .addOnFrameMetricsAvailableListener( - activityListenerCaptor.capture(), eq(frameMetricsHandler)); - verify(activity.getWindow()) - .removeOnFrameMetricsAvailableListener(activityListenerCaptor.getValue()); - - assertThat(otelTesting.getSpans()).hasSize(0); - } - - @Test - public void removeWithMetrics() { - SlowRenderListener testInstance = - new SlowRenderListener(tracer, null, frameMetricsHandler, Duration.ZERO); - - testInstance.onActivityResumed(activity); - - verify(activity.getWindow()) - .addOnFrameMetricsAvailableListener(activityListenerCaptor.capture(), any()); - SlowRenderListener.PerActivityListener listener = activityListenerCaptor.getValue(); - for (long duration : makeSomeDurations()) { - when(frameMetrics.getMetric(DRAW_DURATION)).thenReturn(duration); - listener.onFrameMetricsAvailable(null, frameMetrics, 0); - } - - testInstance.onActivityPaused(activity); - - List spans = otelTesting.getSpans(); - assertSpanContent(spans); - } - - @Test - public void start() { - ScheduledExecutorService exec = mock(ScheduledExecutorService.class); - - doAnswer( - invocation -> { - Runnable runnable = invocation.getArgument(0); - runnable.run(); // just call it immediately - return null; - }) - .when(exec) - .scheduleAtFixedRate(any(), eq(1001L), eq(1001L), eq(TimeUnit.MILLISECONDS)); - - SlowRenderListener testInstance = - new SlowRenderListener(tracer, exec, frameMetricsHandler, Duration.ofMillis(1001)); - - testInstance.onActivityResumed(activity); - - verify(activity.getWindow()) - .addOnFrameMetricsAvailableListener(activityListenerCaptor.capture(), any()); - SlowRenderListener.PerActivityListener listener = activityListenerCaptor.getValue(); - for (long duration : makeSomeDurations()) { - when(frameMetrics.getMetric(DRAW_DURATION)).thenReturn(duration); - listener.onFrameMetricsAvailable(null, frameMetrics, 0); - } - - testInstance.start(); - - List spans = otelTesting.getSpans(); - assertSpanContent(spans); - } - - @Test - public void activityListenerSkipsFirstFrame() { - SlowRenderListener.PerActivityListener listener = - new SlowRenderListener.PerActivityListener(null); - when(frameMetrics.getMetric(FIRST_DRAW_FRAME)).thenReturn(1L); - listener.onFrameMetricsAvailable(null, frameMetrics, 99); - verify(frameMetrics, never()).getMetric(DRAW_DURATION); - } - - private static void assertSpanContent(List spans) { - assertThat(spans) - .hasSize(2) - .satisfiesExactly( - span -> - assertThat(span) - .hasName("slowRenders") - .endsAt(span.getStartEpochNanos()) - .hasAttribute(COUNT_KEY, 3L) - .hasAttribute( - AttributeKey.stringKey("activity.name"), - "io.otel/Komponent"), - span -> - assertThat(span) - .hasName("frozenRenders") - .endsAt(span.getStartEpochNanos()) - .hasAttribute(COUNT_KEY, 1L) - .hasAttribute( - AttributeKey.stringKey("activity.name"), - "io.otel/Komponent")); - } - - private List makeSomeDurations() { - return Stream.of( - 5L, 11L, 101L, // slow - 701L, // frozen - 17L, // slow - 17L, // slow - 16L, 11L) - .map(TimeUnit.MILLISECONDS::toNanos) - .collect(Collectors.toList()); - } -} diff --git a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/startup/AppStartupTimerTest.java b/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/startup/AppStartupTimerTest.java deleted file mode 100644 index a6b8108d..00000000 --- a/opentelemetry-android-instrumentation/src/test/java/io/opentelemetry/rum/internal/instrumentation/startup/AppStartupTimerTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opentelemetry.rum.internal.instrumentation.startup; - -import static io.opentelemetry.rum.internal.RumConstants.START_TYPE_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertSame; - -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.util.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -class AppStartupTimerTest { - @RegisterExtension final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); - private Tracer tracer; - - @BeforeEach - void setup() { - tracer = otelTesting.getOpenTelemetry().getTracer("testTracer"); - } - - @Test - void start_end() { - AppStartupTimer appStartupTimer = new AppStartupTimer(); - Span startSpan = appStartupTimer.start(tracer); - assertNotNull(startSpan); - appStartupTimer.end(); - - List spans = otelTesting.getSpans(); - assertEquals(1, spans.size()); - SpanData spanData = spans.get(0); - - assertEquals("AppStart", spanData.getName()); - assertEquals("cold", spanData.getAttributes().get(START_TYPE_KEY)); - } - - @Test - void multi_end() { - AppStartupTimer appStartupTimer = new AppStartupTimer(); - appStartupTimer.start(tracer); - appStartupTimer.end(); - appStartupTimer.end(); - - assertEquals(1, otelTesting.getSpans().size()); - } - - @Test - void multi_start() { - AppStartupTimer appStartupTimer = new AppStartupTimer(); - appStartupTimer.start(tracer); - assertSame(appStartupTimer.start(tracer), appStartupTimer.start(tracer)); - - appStartupTimer.end(); - assertEquals(1, otelTesting.getSpans().size()); - } -} diff --git a/sample-app/build.gradle.kts b/sample-app/build.gradle.kts index 96cfce69..45123430 100644 --- a/sample-app/build.gradle.kts +++ b/sample-app/build.gradle.kts @@ -57,7 +57,7 @@ val otelAlphaVersion = otelVersion.replaceFirst("(-SNAPSHOT)?$".toRegex(), "-alp dependencies { api(platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:$otelAlphaVersion")) - implementation(project(":opentelemetry-android-instrumentation")) + implementation("io.opentelemetry.android:instrumentation:0.1.0-alpha") implementation("androidx.legacy:legacy-support-v4:1.0.0") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3") diff --git a/sample-app/src/main/java/com/splunk/android/sample/MainActivity.java b/sample-app/src/main/java/com/splunk/android/sample/MainActivity.java index 22ac4d9b..71d3ebf1 100644 --- a/sample-app/src/main/java/com/splunk/android/sample/MainActivity.java +++ b/sample-app/src/main/java/com/splunk/android/sample/MainActivity.java @@ -40,8 +40,8 @@ import androidx.navigation.ui.NavigationUI; import com.splunk.android.sample.databinding.ActivityMainBinding; import com.splunk.rum.SplunkRum; +import io.opentelemetry.android.instrumentation.RumScreenName; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.rum.internal.instrumentation.RumScreenName; import java.util.Arrays; import java.util.concurrent.TimeUnit; diff --git a/sample-app/src/main/java/com/splunk/android/sample/SecondFragment.java b/sample-app/src/main/java/com/splunk/android/sample/SecondFragment.java index 76bdc238..670f130c 100644 --- a/sample-app/src/main/java/com/splunk/android/sample/SecondFragment.java +++ b/sample-app/src/main/java/com/splunk/android/sample/SecondFragment.java @@ -29,13 +29,13 @@ import androidx.navigation.fragment.NavHostFragment; import com.splunk.android.sample.databinding.FragmentSecondBinding; import com.splunk.rum.SplunkRum; +import io.opentelemetry.android.instrumentation.RumScreenName; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.events.EventEmitter; import io.opentelemetry.api.events.EventEmitterProvider; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Scope; -import io.opentelemetry.rum.internal.instrumentation.RumScreenName; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.logs.internal.SdkEventEmitterProvider; import java.util.Random; diff --git a/settings.gradle.kts b/settings.gradle.kts index 04b34f00..92e9e78b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,5 @@ rootProject.name = "Splunk Android RUM" -include(":opentelemetry-android-instrumentation") include(":splunk-otel-android") include(":splunk-otel-android-volley") include(":sample-app") diff --git a/splunk-otel-android/build.gradle.kts b/splunk-otel-android/build.gradle.kts index e975f27e..a0e43608 100644 --- a/splunk-otel-android/build.gradle.kts +++ b/splunk-otel-android/build.gradle.kts @@ -44,7 +44,8 @@ val otelAlphaVersion = otelVersion.replaceFirst("(-SNAPSHOT)?$".toRegex(), "-alp dependencies { api(platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:$otelAlphaVersion")) - implementation(project(":opentelemetry-android-instrumentation")) + implementation("io.opentelemetry.android:instrumentation:0.1.0-alpha") + implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.9.10")) implementation("androidx.appcompat:appcompat:1.6.1") implementation("androidx.core:core:1.12.0") diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/CrashComponentExtractor.java b/splunk-otel-android/src/main/java/com/splunk/rum/CrashComponentExtractor.java index baf5d9cc..c4550666 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/CrashComponentExtractor.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/CrashComponentExtractor.java @@ -18,10 +18,10 @@ import static com.splunk.rum.SplunkRum.COMPONENT_KEY; +import io.opentelemetry.android.instrumentation.crash.CrashDetails; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import io.opentelemetry.rum.internal.instrumentation.crash.CrashDetails; import java.util.concurrent.atomic.AtomicBoolean; final class CrashComponentExtractor implements AttributesExtractor { diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/DiskToZipkinExporter.java b/splunk-otel-android/src/main/java/com/splunk/rum/DiskToZipkinExporter.java index 9d5eb0cf..6baa94e5 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/DiskToZipkinExporter.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/DiskToZipkinExporter.java @@ -22,7 +22,7 @@ import android.util.Log; import androidx.annotation.Nullable; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; import java.io.File; import java.util.Comparator; import java.util.List; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/InitializationEvents.java b/splunk-otel-android/src/main/java/com/splunk/rum/InitializationEvents.java index e3618c62..b95626f5 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/InitializationEvents.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/InitializationEvents.java @@ -19,10 +19,10 @@ import static com.splunk.rum.SplunkRum.COMPONENT_APPSTART; import static com.splunk.rum.SplunkRum.COMPONENT_KEY; +import io.opentelemetry.android.instrumentation.startup.AppStartupTimer; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Context; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/MemoryBufferingExporter.java b/splunk-otel-android/src/main/java/com/splunk/rum/MemoryBufferingExporter.java index 61d79f06..aa7c4954 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/MemoryBufferingExporter.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/MemoryBufferingExporter.java @@ -18,7 +18,7 @@ import android.util.Log; import androidx.annotation.NonNull; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/NoOpSplunkRum.java b/splunk-otel-android/src/main/java/com/splunk/rum/NoOpSplunkRum.java index 74a97130..f1248889 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/NoOpSplunkRum.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/NoOpSplunkRum.java @@ -17,11 +17,11 @@ package com.splunk.rum; import android.webkit.WebView; +import io.opentelemetry.android.OpenTelemetryRum; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.rum.internal.OpenTelemetryRum; import java.util.function.Consumer; import okhttp3.Call; import okhttp3.OkHttpClient; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/RumInitializer.java b/splunk-otel-android/src/main/java/com/splunk/rum/RumInitializer.java index 782e7365..56c46bdb 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/RumInitializer.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/RumInitializer.java @@ -22,8 +22,8 @@ import static com.splunk.rum.SplunkRum.COMPONENT_KEY; import static com.splunk.rum.SplunkRum.COMPONENT_UI; import static com.splunk.rum.SplunkRum.RUM_TRACER_NAME; +import static io.opentelemetry.android.RumConstants.APP_START_SPAN_NAME; import static io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor.constant; -import static io.opentelemetry.rum.internal.RumConstants.APP_START_SPAN_NAME; import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.DEPLOYMENT_ENVIRONMENT; import static java.util.Objects.requireNonNull; @@ -31,23 +31,23 @@ import android.os.Looper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import io.opentelemetry.android.GlobalAttributesSpanAppender; +import io.opentelemetry.android.OpenTelemetryRum; +import io.opentelemetry.android.OpenTelemetryRumBuilder; +import io.opentelemetry.android.RuntimeDetailsExtractor; +import io.opentelemetry.android.SessionIdRatioBasedSampler; +import io.opentelemetry.android.instrumentation.activity.VisibleScreenTracker; +import io.opentelemetry.android.instrumentation.anr.AnrDetector; +import io.opentelemetry.android.instrumentation.crash.CrashReporter; +import io.opentelemetry.android.instrumentation.lifecycle.AndroidLifecycleInstrumentation; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; +import io.opentelemetry.android.instrumentation.network.NetworkAttributesSpanAppender; +import io.opentelemetry.android.instrumentation.network.NetworkChangeMonitor; +import io.opentelemetry.android.instrumentation.slowrendering.SlowRenderingDetector; +import io.opentelemetry.android.instrumentation.startup.AppStartupTimer; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; -import io.opentelemetry.rum.internal.GlobalAttributesSpanAppender; -import io.opentelemetry.rum.internal.OpenTelemetryRum; -import io.opentelemetry.rum.internal.OpenTelemetryRumBuilder; -import io.opentelemetry.rum.internal.RuntimeDetailsExtractor; -import io.opentelemetry.rum.internal.SessionIdRatioBasedSampler; -import io.opentelemetry.rum.internal.instrumentation.activity.VisibleScreenTracker; -import io.opentelemetry.rum.internal.instrumentation.anr.AnrDetector; -import io.opentelemetry.rum.internal.instrumentation.crash.CrashReporter; -import io.opentelemetry.rum.internal.instrumentation.lifecycle.AndroidLifecycleInstrumentation; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider; -import io.opentelemetry.rum.internal.instrumentation.network.NetworkAttributesSpanAppender; -import io.opentelemetry.rum.internal.instrumentation.network.NetworkChangeMonitor; -import io.opentelemetry.rum.internal.instrumentation.slowrendering.SlowRenderingDetector; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.resources.ResourceBuilder; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/ScreenAttributesAppender.java b/splunk-otel-android/src/main/java/com/splunk/rum/ScreenAttributesAppender.java index 57d831a1..32d94fa2 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/ScreenAttributesAppender.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/ScreenAttributesAppender.java @@ -16,10 +16,10 @@ package com.splunk.rum; -import static io.opentelemetry.rum.internal.RumConstants.SCREEN_NAME_KEY; +import static io.opentelemetry.android.RumConstants.SCREEN_NAME_KEY; +import io.opentelemetry.android.instrumentation.activity.VisibleScreenTracker; import io.opentelemetry.context.Context; -import io.opentelemetry.rum.internal.instrumentation.activity.VisibleScreenTracker; import io.opentelemetry.sdk.trace.ReadWriteSpan; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SpanProcessor; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/SpanFilterBuilder.java b/splunk-otel-android/src/main/java/com/splunk/rum/SpanFilterBuilder.java index d4682f19..4098023b 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/SpanFilterBuilder.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/SpanFilterBuilder.java @@ -16,8 +16,8 @@ package com.splunk.rum; +import io.opentelemetry.android.export.SpanDataModifier; import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.rum.internal.export.SpanDataModifier; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.util.function.Function; import java.util.function.Predicate; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkRum.java b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkRum.java index 4ef8e23a..05a702f8 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkRum.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkRum.java @@ -26,6 +26,10 @@ import android.util.Log; import android.webkit.WebView; import androidx.annotation.Nullable; +import io.opentelemetry.android.GlobalAttributesSpanAppender; +import io.opentelemetry.android.OpenTelemetryRum; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; +import io.opentelemetry.android.instrumentation.startup.AppStartupTimer; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -33,10 +37,6 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.instrumentation.okhttp.v3_0.OkHttpTelemetry; -import io.opentelemetry.rum.internal.GlobalAttributesSpanAppender; -import io.opentelemetry.rum.internal.OpenTelemetryRum; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; import io.opentelemetry.sdk.OpenTelemetrySdk; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkRumBuilder.java b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkRumBuilder.java index 8cac830f..44e631b9 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkRumBuilder.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkRumBuilder.java @@ -21,8 +21,8 @@ import android.app.Application; import android.util.Log; import androidx.annotation.Nullable; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.time.Duration; import java.util.function.Consumer; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkScreenNameExtractor.java b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkScreenNameExtractor.java index 11a88e58..506f5c72 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkScreenNameExtractor.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkScreenNameExtractor.java @@ -18,7 +18,7 @@ import android.app.Activity; import androidx.fragment.app.Fragment; -import io.opentelemetry.rum.internal.instrumentation.ScreenNameExtractor; +import io.opentelemetry.android.instrumentation.ScreenNameExtractor; import java.util.function.Function; /** diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkSpanDataModifier.java b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkSpanDataModifier.java index 221aa9a5..0aceaa9a 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkSpanDataModifier.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkSpanDataModifier.java @@ -25,11 +25,11 @@ import static java.util.Arrays.asList; import static java.util.Collections.unmodifiableSet; +import io.opentelemetry.android.RumConstants; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.rum.internal.RumConstants; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.data.DelegatingSpanData; import io.opentelemetry.sdk.trace.data.EventData; diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/StandardAttributes.java b/splunk-otel-android/src/main/java/com/splunk/rum/StandardAttributes.java index be964d65..71296748 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/StandardAttributes.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/StandardAttributes.java @@ -18,9 +18,9 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; +import io.opentelemetry.android.export.SpanDataModifier; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.rum.internal.export.SpanDataModifier; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; /** diff --git a/splunk-otel-android/src/test/java/com/splunk/rum/DiskToZipkinExporterTest.java b/splunk-otel-android/src/test/java/com/splunk/rum/DiskToZipkinExporterTest.java index f8cb4b22..ce571a59 100644 --- a/splunk-otel-android/src/test/java/com/splunk/rum/DiskToZipkinExporterTest.java +++ b/splunk-otel-android/src/test/java/com/splunk/rum/DiskToZipkinExporterTest.java @@ -23,8 +23,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetwork; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider; +import io.opentelemetry.android.instrumentation.network.CurrentNetwork; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; import java.io.File; import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; diff --git a/splunk-otel-android/src/test/java/com/splunk/rum/MemoryBufferingExporterTest.java b/splunk-otel-android/src/test/java/com/splunk/rum/MemoryBufferingExporterTest.java index e8ebd73a..ba7b4323 100644 --- a/splunk-otel-android/src/test/java/com/splunk/rum/MemoryBufferingExporterTest.java +++ b/splunk-otel-android/src/test/java/com/splunk/rum/MemoryBufferingExporterTest.java @@ -26,8 +26,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetwork; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider; +import io.opentelemetry.android.instrumentation.network.CurrentNetwork; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; diff --git a/splunk-otel-android/src/test/java/com/splunk/rum/RumInitializerTest.java b/splunk-otel-android/src/test/java/com/splunk/rum/RumInitializerTest.java index f68781c5..129f00f8 100644 --- a/splunk-otel-android/src/test/java/com/splunk/rum/RumInitializerTest.java +++ b/splunk-otel-android/src/test/java/com/splunk/rum/RumInitializerTest.java @@ -31,12 +31,12 @@ import android.app.Application; import android.content.Context; import android.os.Looper; +import io.opentelemetry.android.instrumentation.network.CurrentNetwork; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; +import io.opentelemetry.android.instrumentation.startup.AppStartupTimer; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetwork; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider; -import io.opentelemetry.rum.internal.instrumentation.startup.AppStartupTimer; import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.testing.trace.TestSpanData; diff --git a/splunk-otel-android/src/test/java/com/splunk/rum/ScreenAttributesAppenderTest.java b/splunk-otel-android/src/test/java/com/splunk/rum/ScreenAttributesAppenderTest.java index 20c0ac65..832e233f 100644 --- a/splunk-otel-android/src/test/java/com/splunk/rum/ScreenAttributesAppenderTest.java +++ b/splunk-otel-android/src/test/java/com/splunk/rum/ScreenAttributesAppenderTest.java @@ -16,8 +16,8 @@ package com.splunk.rum; -import static io.opentelemetry.rum.internal.RumConstants.LAST_SCREEN_NAME_KEY; -import static io.opentelemetry.rum.internal.RumConstants.SCREEN_NAME_KEY; +import static io.opentelemetry.android.RumConstants.LAST_SCREEN_NAME_KEY; +import static io.opentelemetry.android.RumConstants.SCREEN_NAME_KEY; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -27,8 +27,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.opentelemetry.android.instrumentation.activity.VisibleScreenTracker; import io.opentelemetry.context.Context; -import io.opentelemetry.rum.internal.instrumentation.activity.VisibleScreenTracker; import io.opentelemetry.sdk.trace.ReadWriteSpan; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/splunk-otel-android/src/test/java/com/splunk/rum/SplunkRumTest.java b/splunk-otel-android/src/test/java/com/splunk/rum/SplunkRumTest.java index 3000572c..f2c36e88 100644 --- a/splunk-otel-android/src/test/java/com/splunk/rum/SplunkRumTest.java +++ b/splunk-otel-android/src/test/java/com/splunk/rum/SplunkRumTest.java @@ -37,15 +37,15 @@ import android.content.Context; import android.location.Location; import android.webkit.WebView; +import io.opentelemetry.android.GlobalAttributesSpanAppender; +import io.opentelemetry.android.OpenTelemetryRum; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanId; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Scope; -import io.opentelemetry.rum.internal.GlobalAttributesSpanAppender; -import io.opentelemetry.rum.internal.OpenTelemetryRum; -import io.opentelemetry.rum.internal.instrumentation.network.CurrentNetworkProvider; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; diff --git a/splunk-otel-android/src/test/java/com/splunk/rum/SplunkSpanDataModifierTest.java b/splunk-otel-android/src/test/java/com/splunk/rum/SplunkSpanDataModifierTest.java index 9068f106..7b0033a5 100644 --- a/splunk-otel-android/src/test/java/com/splunk/rum/SplunkSpanDataModifierTest.java +++ b/splunk-otel-android/src/test/java/com/splunk/rum/SplunkSpanDataModifierTest.java @@ -26,12 +26,12 @@ import static java.util.Collections.singletonList; import static org.mockito.Mockito.when; +import io.opentelemetry.android.RumConstants; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.rum.internal.RumConstants; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.trace.TestSpanData;