diff --git a/sample-app/src/main/java/com/splunk/android/sample/SampleApplication.java b/sample-app/src/main/java/com/splunk/android/sample/SampleApplication.java index cb21dc85..9f5ed8ba 100644 --- a/sample-app/src/main/java/com/splunk/android/sample/SampleApplication.java +++ b/sample-app/src/main/java/com/splunk/android/sample/SampleApplication.java @@ -42,6 +42,7 @@ public void onCreate() { .setRumAccessToken(getResources().getString(R.string.rum_access_token)) .enableDebug() .enableDiskBuffering() + .disableBackgroundTaskReporting(BuildConfig.APPLICATION_ID) .setSlowRenderingDetectionPollInterval(Duration.ofMillis(1000)) .setDeploymentEnvironment("demo") .limitDiskUsageMegabytes(1) diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/BackgroundProcessDetector.java b/splunk-otel-android/src/main/java/com/splunk/rum/BackgroundProcessDetector.java new file mode 100644 index 00000000..eeed5daa --- /dev/null +++ b/splunk-otel-android/src/main/java/com/splunk/rum/BackgroundProcessDetector.java @@ -0,0 +1,50 @@ +/* + * 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 com.splunk.rum; + +import android.annotation.SuppressLint; +import android.app.Application; +import android.os.Build; +import java.lang.reflect.Method; +import java.util.Objects; + +public final class BackgroundProcessDetector { + + private BackgroundProcessDetector() {} + + public static Boolean isBackgroundProcess(String applicationId) { + String applicationProcessName = getApplicationProcessName(); + return Objects.equals(applicationProcessName, applicationId); + } + + private static String getApplicationProcessName() { + if (Build.VERSION.SDK_INT >= 28) { + return Application.getProcessName(); + } else { + try { + @SuppressLint("PrivateApi") + Class activityThread = Class.forName("android.app.ActivityThread"); + String methodName = "currentProcessName"; + @SuppressLint("PrivateApi") + Method getProcessName = activityThread.getDeclaredMethod(methodName); + return (String) getProcessName.invoke(null); + } catch (Exception e) { + return null; + } + } + } +} diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/ConfigFlags.java b/splunk-otel-android/src/main/java/com/splunk/rum/ConfigFlags.java index d3134fbc..ef1bab0e 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/ConfigFlags.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/ConfigFlags.java @@ -26,6 +26,7 @@ class ConfigFlags { private boolean networkMonitorEnabled = true; private boolean anrDetectionEnabled = true; private boolean slowRenderingDetectionEnabled = true; + private boolean backgroundTaskInstrumentationEnabled = true; void enableDebug() { debugEnabled = true; @@ -55,10 +56,18 @@ void disableSlowRenderingDetection() { slowRenderingDetectionEnabled = false; } + public void disableBackgroundTaskDetection() { + backgroundTaskInstrumentationEnabled = false; + } + boolean isDebugEnabled() { return debugEnabled; } + boolean isBackgroundTaskInstrumentationEnabled() { + return backgroundTaskInstrumentationEnabled; + } + boolean isAnrDetectionEnabled() { return anrDetectionEnabled; } 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 710afe52..4ef8e23a 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 @@ -100,9 +100,13 @@ static SplunkRum initialize( return INSTANCE; } - INSTANCE = - new RumInitializer(builder, application, startupTimer) - .initialize(currentNetworkProviderFactory, Looper.getMainLooper()); + if (builder.isBackgroundTaskReportingDisabled() && builder.isBackgroundProcess) { + INSTANCE = SplunkRum.noop(); + } else { + INSTANCE = + new RumInitializer(builder, application, startupTimer) + .initialize(currentNetworkProviderFactory, Looper.getMainLooper()); + } if (builder.isDebugEnabled()) { Log.i( 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 532e3e57..8cac830f 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 @@ -47,6 +47,7 @@ public final class SplunkRumBuilder { int maxUsageMegabytes = DEFAULT_MAX_STORAGE_USE_MB; boolean sessionBasedSamplerEnabled = false; double sessionBasedSamplerRatio = 1.0; + boolean isBackgroundProcess = false; /** * Sets the application name that will be used to identify your application in the Splunk RUM @@ -314,6 +315,20 @@ public SplunkRum build(Application application) { return SplunkRum.initialize(this, application, CurrentNetworkProvider::createAndStart); } + /** + * Disables the instrumentation of background process feature. If enabled, the background + * processes will be instrumented. + * + *

This feature is enabled by default. You can disable it by calling this method. + * + * @return {@code this} + */ + public SplunkRumBuilder disableBackgroundTaskReporting(String applicationId) { + isBackgroundProcess = BackgroundProcessDetector.isBackgroundProcess(applicationId); + configFlags.disableBackgroundTaskDetection(); + return this; + } + // one day maybe these can use kotlin delegation ConfigFlags getConfigFlags() { return configFlags; @@ -352,4 +367,8 @@ boolean isDiskBufferingEnabled() { boolean isReactNativeSupportEnabled() { return configFlags.isReactNativeSupportEnabled(); } + + boolean isBackgroundTaskReportingDisabled() { + return !configFlags.isBackgroundTaskInstrumentationEnabled(); + } }