From 5ffa62391933c0ea83f184e58e7a1d3cd6ea07d4 Mon Sep 17 00:00:00 2001 From: Nikita Ogorodnikov Date: Tue, 12 Mar 2024 12:54:59 +0100 Subject: [PATCH] RUM-2878: Report fatal ANRs --- dd-sdk-android-core/api/apiSurface | 11 +- .../api/dd-sdk-android-core.api | 14 +- .../datadog/android/api/feature/Feature.kt | 5 + .../com/datadog/android/core/DatadogCore.kt | 62 +- .../datadog/android/core/InternalSdkCore.kt | 29 + .../android/core/NoOpInternalSdkCore.kt | 9 + .../android/core/internal/CoreFeature.kt | 109 +- .../BroadcastReceiverNetworkInfoProvider.kt | 5 +- .../net/info/CallbackNetworkInfoProvider.kt | 5 +- .../core/internal/persistence/file/FileExt.kt | 12 + .../system/BuildSdkVersionProvider.kt | 15 +- .../system/DefaultBuildSdkVersionProvider.kt | 20 - .../ndk/internal/DatadogNdkCrashHandler.kt | 30 +- .../android/ndk/internal/NdkCrashHandler.kt | 1 + .../datadog/android/core/DatadogCoreTest.kt | 143 +- .../android/core/internal/CoreFeatureTest.kt | 195 ++- ...roadcastReceiverNetworkInfoProviderTest.kt | 14 +- .../info/CallbackNetworkInfoProviderTest.kt | 6 +- .../system/DefaultAndroidInfoProviderTest.kt | 2 +- .../internal/DatadogNdkCrashHandlerTest.kt | 38 +- detekt_custom.yml | 8 + .../ndk/internal/NdkCrashReportsFeature.kt | 2 +- .../kotlin/com/datadog/android/rum/Rum.kt | 10 + ...Handler.kt => DatadogLateCrashReporter.kt} | 201 ++- .../internal/DefaultAppStartTimeProvider.kt | 5 +- .../android/rum/internal/LateCrashReporter.kt | 25 + .../android/rum/internal/RumFeature.kt | 62 +- .../rum/internal/anr/AndroidTraceParser.kt | 124 ++ .../rum/internal/monitor/DatadogRumMonitor.kt | 2 +- .../rum/internal/ndk/NdkCrashEventHandler.kt | 14 - .../OreoFragmentLifecycleCallbacks.kt | 7 +- .../JankStatsActivityLifecycleListener.kt | 14 +- .../tracking/FragmentViewTrackingStrategy.kt | 47 +- ...est.kt => DatadogLateCrashReporterTest.kt} | 559 +++++- .../DefaultAppStartTimeProviderTest.kt | 4 +- .../android/rum/internal/RumFeatureTest.kt | 213 ++- .../internal/anr/AndroidTraceParserTest.kt | 304 ++++ .../OreoFragmentLifecycleCallbacksTest.kt | 10 +- .../JankStatsActivityLifecycleListenerTest.kt | 6 +- .../FragmentViewTrackingStrategyTest.kt | 78 +- .../src/test/resources/anr_crash_trace.txt | 1551 +++++++++++++++++ 41 files changed, 3620 insertions(+), 351 deletions(-) delete mode 100644 dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/DefaultBuildSdkVersionProvider.kt rename features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/{ndk/DatadogNdkCrashEventHandler.kt => DatadogLateCrashReporter.kt} (54%) create mode 100644 features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/LateCrashReporter.kt create mode 100644 features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/anr/AndroidTraceParser.kt delete mode 100644 features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/ndk/NdkCrashEventHandler.kt rename features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/{ndk/DatadogNdkCrashEventHandlerTest.kt => DatadogLateCrashReporterTest.kt} (50%) create mode 100644 features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/anr/AndroidTraceParserTest.kt create mode 100644 features/dd-sdk-android-rum/src/test/resources/anr_crash_trace.txt diff --git a/dd-sdk-android-core/api/apiSurface b/dd-sdk-android-core/api/apiSurface index 15c2e14ae6..c80b4bdae0 100644 --- a/dd-sdk-android-core/api/apiSurface +++ b/dd-sdk-android-core/api/apiSurface @@ -96,6 +96,7 @@ interface com.datadog.android.api.feature.Feature const val RUM_FEATURE_NAME: String const val TRACING_FEATURE_NAME: String const val SESSION_REPLAY_FEATURE_NAME: String + const val NDK_CRASH_REPORTS_FEATURE_NAME: String interface com.datadog.android.api.feature.FeatureEventReceiver fun onReceive(Any) interface com.datadog.android.api.feature.FeatureScope @@ -145,7 +146,11 @@ interface com.datadog.android.core.InternalSdkCore : com.datadog.android.api.fea val rootStorageDir: java.io.File? val isDeveloperModeEnabled: Boolean val firstPartyHostResolver: com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver + val lastViewEvent: com.google.gson.JsonObject? + val lastFatalAnrSent: Long? fun writeLastViewEvent(ByteArray) + fun deleteLastViewEvent() + fun writeLastFatalAnrSent(Long) fun getPersistenceExecutorService(): java.util.concurrent.ExecutorService fun getAllFeatures(): List fun getDatadogContext(): com.datadog.android.api.context.DatadogContext? @@ -228,9 +233,9 @@ fun java.io.File.existsSafe(com.datadog.android.api.InternalLogger): Boolean fun java.io.File.readTextSafe(java.nio.charset.Charset = Charsets.UTF_8, com.datadog.android.api.InternalLogger): String? fun java.io.File.readLinesSafe(java.nio.charset.Charset = Charsets.UTF_8, com.datadog.android.api.InternalLogger): List? interface com.datadog.android.core.internal.system.BuildSdkVersionProvider - fun version(): Int -class com.datadog.android.core.internal.system.DefaultBuildSdkVersionProvider : BuildSdkVersionProvider - override fun version(): Int + val version: Int + companion object + val DEFAULT: BuildSdkVersionProvider class com.datadog.android.core.internal.thread.LoggingScheduledThreadPoolExecutor : java.util.concurrent.ScheduledThreadPoolExecutor constructor(Int, com.datadog.android.api.InternalLogger) override fun afterExecute(Runnable?, Throwable?) diff --git a/dd-sdk-android-core/api/dd-sdk-android-core.api b/dd-sdk-android-core/api/dd-sdk-android-core.api index 4ae514b637..0ed4b4ef93 100644 --- a/dd-sdk-android-core/api/dd-sdk-android-core.api +++ b/dd-sdk-android-core/api/dd-sdk-android-core.api @@ -294,6 +294,7 @@ public final class com/datadog/android/api/context/UserInfo { public abstract interface class com/datadog/android/api/feature/Feature { public static final field Companion Lcom/datadog/android/api/feature/Feature$Companion; public static final field LOGS_FEATURE_NAME Ljava/lang/String; + public static final field NDK_CRASH_REPORTS_FEATURE_NAME Ljava/lang/String; public static final field RUM_FEATURE_NAME Ljava/lang/String; public static final field SESSION_REPLAY_FEATURE_NAME Ljava/lang/String; public static final field TRACING_FEATURE_NAME Ljava/lang/String; @@ -304,6 +305,7 @@ public abstract interface class com/datadog/android/api/feature/Feature { public final class com/datadog/android/api/feature/Feature$Companion { public static final field LOGS_FEATURE_NAME Ljava/lang/String; + public static final field NDK_CRASH_REPORTS_FEATURE_NAME Ljava/lang/String; public static final field RUM_FEATURE_NAME Ljava/lang/String; public static final field SESSION_REPLAY_FEATURE_NAME Ljava/lang/String; public static final field TRACING_FEATURE_NAME Ljava/lang/String; @@ -430,14 +432,18 @@ public final class com/datadog/android/api/storage/RawBatchEvent { } public abstract interface class com/datadog/android/core/InternalSdkCore : com/datadog/android/api/feature/FeatureSdkCore { + public abstract fun deleteLastViewEvent ()V public abstract fun getAllFeatures ()Ljava/util/List; public abstract fun getDatadogContext ()Lcom/datadog/android/api/context/DatadogContext; public abstract fun getFirstPartyHostResolver ()Lcom/datadog/android/core/internal/net/FirstPartyHostHeaderTypeResolver; + public abstract fun getLastFatalAnrSent ()Ljava/lang/Long; + public abstract fun getLastViewEvent ()Lcom/google/gson/JsonObject; public abstract fun getNetworkInfo ()Lcom/datadog/android/api/context/NetworkInfo; public abstract fun getPersistenceExecutorService ()Ljava/util/concurrent/ExecutorService; public abstract fun getRootStorageDir ()Ljava/io/File; public abstract fun getTrackingConsent ()Lcom/datadog/android/privacy/TrackingConsent; public abstract fun isDeveloperModeEnabled ()Z + public abstract fun writeLastFatalAnrSent (J)V public abstract fun writeLastViewEvent ([B)V } @@ -624,12 +630,12 @@ public final class com/datadog/android/core/internal/persistence/file/FileExtKt } public abstract interface class com/datadog/android/core/internal/system/BuildSdkVersionProvider { - public abstract fun version ()I + public static final field Companion Lcom/datadog/android/core/internal/system/BuildSdkVersionProvider$Companion; + public abstract fun getVersion ()I } -public final class com/datadog/android/core/internal/system/DefaultBuildSdkVersionProvider : com/datadog/android/core/internal/system/BuildSdkVersionProvider { - public fun ()V - public fun version ()I +public final class com/datadog/android/core/internal/system/BuildSdkVersionProvider$Companion { + public final fun getDEFAULT ()Lcom/datadog/android/core/internal/system/BuildSdkVersionProvider; } public final class com/datadog/android/core/internal/thread/LoggingScheduledThreadPoolExecutor : java/util/concurrent/ScheduledThreadPoolExecutor { diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/api/feature/Feature.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/api/feature/Feature.kt index b85b02bc72..295731da66 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/api/feature/Feature.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/api/feature/Feature.kt @@ -53,5 +53,10 @@ interface Feature { * Session Replay feature name. */ const val SESSION_REPLAY_FEATURE_NAME: String = "session-replay" + + /** + * NDK Crash Reports feature name. + */ + const val NDK_CRASH_REPORTS_FEATURE_NAME: String = "ndk-crash-reporting" } } diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/DatadogCore.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/DatadogCore.kt index b082b457a6..b46058a9fd 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/DatadogCore.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/DatadogCore.kt @@ -9,6 +9,7 @@ package com.datadog.android.core import android.app.Application import android.content.Context import android.content.pm.ApplicationInfo +import android.os.Build import android.util.Log import androidx.annotation.WorkerThread import com.datadog.android.Datadog @@ -22,7 +23,6 @@ import com.datadog.android.api.feature.Feature import com.datadog.android.api.feature.FeatureEventReceiver import com.datadog.android.api.feature.FeatureScope import com.datadog.android.api.feature.FeatureSdkCore -import com.datadog.android.api.storage.RawBatchEvent import com.datadog.android.core.configuration.BatchSize import com.datadog.android.core.configuration.Configuration import com.datadog.android.core.configuration.UploadFrequency @@ -32,14 +32,12 @@ import com.datadog.android.core.internal.SdkFeature import com.datadog.android.core.internal.lifecycle.ProcessLifecycleCallback import com.datadog.android.core.internal.lifecycle.ProcessLifecycleMonitor import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver -import com.datadog.android.core.internal.persistence.file.FileWriter -import com.datadog.android.core.internal.persistence.file.batch.BatchFileReaderWriter -import com.datadog.android.core.internal.persistence.file.existsSafe +import com.datadog.android.core.internal.system.BuildSdkVersionProvider import com.datadog.android.core.internal.utils.scheduleSafe import com.datadog.android.error.internal.CrashReportsFeature -import com.datadog.android.ndk.internal.DatadogNdkCrashHandler import com.datadog.android.ndk.internal.NdkCrashHandler import com.datadog.android.privacy.TrackingConsent +import com.google.gson.JsonObject import java.io.File import java.util.Locale import java.util.concurrent.ExecutorService @@ -52,6 +50,7 @@ import java.util.concurrent.TimeUnit * @param name the name of this instance * @param internalLoggerProvider Provider for [InternalLogger] instance. * @param persistenceExecutorServiceFactory Custom factory for persistence executor, used only in unit-tests + * @param buildSdkVersionProvider Build.VERSION.SDK_INT provider used for the test */ @Suppress("TooManyFunctions") internal class DatadogCore( @@ -60,7 +59,8 @@ internal class DatadogCore( override val name: String, internalLoggerProvider: (FeatureSdkCore) -> InternalLogger = { SdkInternalLogger(it) }, // only for unit tests - private val persistenceExecutorServiceFactory: ((InternalLogger) -> ExecutorService)? = null + private val persistenceExecutorServiceFactory: ((InternalLogger) -> ExecutorService)? = null, + private val buildSdkVersionProvider: BuildSdkVersionProvider = BuildSdkVersionProvider.DEFAULT ) : InternalSdkCore { internal lateinit var coreFeature: CoreFeature @@ -81,13 +81,6 @@ internal class DatadogCore( internal val isActive: Boolean get() = coreFeature.initialized.get() - private val ndkLastViewEventFileWriter: FileWriter by lazy { - BatchFileReaderWriter.create( - internalLogger = internalLogger, - encryption = coreFeature.localDataEncryption - ) - } - private var processLifecycleMonitor: ProcessLifecycleMonitor? = null // region SdkCore @@ -183,6 +176,10 @@ internal class DatadogCore( features.values.forEach { it.clearAllData() } + @Suppress("ThreadSafety") // removal of the data is done in synchronous manner + coreFeature.deleteLastViewEvent() + @Suppress("ThreadSafety") // removal of the data is done in synchronous manner + coreFeature.deleteLastFatalAnrSent() } /** @inheritDoc */ @@ -245,23 +242,41 @@ internal class DatadogCore( override val rootStorageDir: File get() = coreFeature.storageDir + @get:WorkerThread + override val lastViewEvent: JsonObject? + get() = coreFeature.lastViewEvent + + @get:WorkerThread + override val lastFatalAnrSent: Long? + get() = coreFeature.lastFatalAnrSent + @WorkerThread override fun writeLastViewEvent(data: ByteArray) { - // directory structure may not exist: currently it is a file which is located in NDK reports - // folder, so if NDK reporting plugin is not initialized, this NDK reports dir won't exist - // as well (and no need to write). - val lastViewEventFile = DatadogNdkCrashHandler.getLastViewEventFile(coreFeature.storageDir) - if (lastViewEventFile.parentFile?.existsSafe(internalLogger) == true) { - ndkLastViewEventFileWriter.writeData(lastViewEventFile, RawBatchEvent(data), false) + // we need to write it only if we are going to read ApplicationExitInfo (available on + // API 30+) or if there is NDK crash tracking enabled + if (buildSdkVersionProvider.version >= Build.VERSION_CODES.R || + features.containsKey(Feature.NDK_CRASH_REPORTS_FEATURE_NAME) + ) { + coreFeature.writeLastViewEvent(data) } else { internalLogger.log( - InternalLogger.Level.WARN, + InternalLogger.Level.INFO, InternalLogger.Target.MAINTAINER, - { LAST_VIEW_EVENT_DIR_MISSING_MESSAGE.format(Locale.US, lastViewEventFile.parent) } + { NO_NEED_TO_WRITE_LAST_VIEW_EVENT } ) } } + @WorkerThread + override fun deleteLastViewEvent() { + coreFeature.deleteLastViewEvent() + } + + @WorkerThread + override fun writeLastFatalAnrSent(anrTimestamp: Long) { + coreFeature.writeLastFatalAnrSent(anrTimestamp) + } + override fun getPersistenceExecutorService(): ExecutorService { return coreFeature.persistenceExecutorService } @@ -487,8 +502,9 @@ internal class DatadogCore( internal const val EVENT_RECEIVER_ALREADY_EXISTS = "Feature \"%s\" already has event receiver registered, overwriting it." - const val LAST_VIEW_EVENT_DIR_MISSING_MESSAGE = "Directory structure %s for writing" + - " last view event doesn't exist." + internal const val NO_NEED_TO_WRITE_LAST_VIEW_EVENT = + "No need to write last RUM view event: NDK" + + " crash reports feature is not enabled and API is below 30." internal val CONFIGURATION_TELEMETRY_DELAY_MS = TimeUnit.SECONDS.toMillis(5) } diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/InternalSdkCore.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/InternalSdkCore.kt index e8ea3a17f4..5f33cf73e7 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/InternalSdkCore.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/InternalSdkCore.kt @@ -15,6 +15,7 @@ import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver import com.datadog.android.lint.InternalApi import com.datadog.android.privacy.TrackingConsent +import com.google.gson.JsonObject import java.io.File import java.util.concurrent.ExecutorService @@ -54,6 +55,20 @@ interface InternalSdkCore : FeatureSdkCore { */ val firstPartyHostResolver: FirstPartyHostHeaderTypeResolver + /** + * Reads last known RUM view event stored. + */ + @get:WorkerThread + @InternalApi + val lastViewEvent: JsonObject? + + /** + * Reads information about last fatal ANR sent. + */ + @get:WorkerThread + @InternalApi + val lastFatalAnrSent: Long? + /** * Writes current RUM view event to the dedicated file for the needs of NDK crash reporting. * @@ -63,6 +78,20 @@ interface InternalSdkCore : FeatureSdkCore { @WorkerThread fun writeLastViewEvent(data: ByteArray) + /** + * Deletes last RUM view event written. + */ + @InternalApi + @WorkerThread + fun deleteLastViewEvent() + + /** + * Writes timestamp of the last fatal ANR sent. + */ + @InternalApi + @WorkerThread + fun writeLastFatalAnrSent(anrTimestamp: Long) + /** * Get an executor service for persistence purposes. * @return the persistence executor to use for this SDK diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/NoOpInternalSdkCore.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/NoOpInternalSdkCore.kt index 32bdc37095..77447625fd 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/NoOpInternalSdkCore.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/NoOpInternalSdkCore.kt @@ -17,6 +17,7 @@ import com.datadog.android.api.feature.FeatureScope import com.datadog.android.core.internal.net.DefaultFirstPartyHostHeaderTypeResolver import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver import com.datadog.android.privacy.TrackingConsent +import com.google.gson.JsonObject import java.io.File import java.util.concurrent.Callable import java.util.concurrent.ExecutorService @@ -57,6 +58,10 @@ internal object NoOpInternalSdkCore : InternalSdkCore { get() = false override val firstPartyHostResolver: FirstPartyHostHeaderTypeResolver get() = DefaultFirstPartyHostHeaderTypeResolver(emptyMap()) + override val lastViewEvent: JsonObject? + get() = null + override val lastFatalAnrSent: Long? + get() = null // endregion @@ -100,6 +105,10 @@ internal object NoOpInternalSdkCore : InternalSdkCore { override fun writeLastViewEvent(data: ByteArray) = Unit + override fun deleteLastViewEvent() = Unit + + override fun writeLastFatalAnrSent(anrTimestamp: Long) = Unit + override fun getPersistenceExecutorService(): ExecutorService = NoOpExecutorService() override fun getAllFeatures(): List = emptyList() diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt index a1216dcc27..2a012bf1ff 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt @@ -18,6 +18,7 @@ import com.datadog.android.BuildConfig import com.datadog.android.Datadog import com.datadog.android.DatadogSite import com.datadog.android.api.InternalLogger +import com.datadog.android.api.storage.RawBatchEvent import com.datadog.android.core.allowThreadDiskReads import com.datadog.android.core.configuration.BatchProcessingLevel import com.datadog.android.core.configuration.BatchSize @@ -36,8 +37,13 @@ import com.datadog.android.core.internal.persistence.JsonObjectDeserializer import com.datadog.android.core.internal.persistence.file.FileMover import com.datadog.android.core.internal.persistence.file.FilePersistenceConfig import com.datadog.android.core.internal.persistence.file.FileReaderWriter +import com.datadog.android.core.internal.persistence.file.FileWriter import com.datadog.android.core.internal.persistence.file.advanced.ScheduledWriter import com.datadog.android.core.internal.persistence.file.batch.BatchFileReaderWriter +import com.datadog.android.core.internal.persistence.file.deleteSafe +import com.datadog.android.core.internal.persistence.file.existsSafe +import com.datadog.android.core.internal.persistence.file.readTextSafe +import com.datadog.android.core.internal.persistence.file.writeTextSafe import com.datadog.android.core.internal.privacy.ConsentProvider import com.datadog.android.core.internal.privacy.NoOpConsentProvider import com.datadog.android.core.internal.privacy.TrackingConsentProvider @@ -72,6 +78,7 @@ import com.datadog.android.ndk.internal.NdkUserInfoDataWriter import com.datadog.android.ndk.internal.NoOpNdkCrashHandler import com.datadog.android.privacy.TrackingConsent import com.datadog.android.security.Encryption +import com.google.gson.JsonObject import com.lyft.kronos.AndroidClockFactory import com.lyft.kronos.KronosClock import okhttp3.CipherSuite @@ -145,6 +152,37 @@ internal class CoreFeature( internal val featuresContext: MutableMap> = ConcurrentHashMap() + // lazy here on purpose: we need to read it only once, even if it is used in different features + @get:WorkerThread + internal val lastViewEvent: JsonObject? by lazy { + @Suppress("ThreadSafety") // called in worker thread context + val viewEvent = readLastViewEvent() + if (viewEvent != null) { + @Suppress("ThreadSafety") // called in worker thread context + deleteLastViewEvent() + } + viewEvent + } + + @get:WorkerThread + private val lastViewEventFile: File by lazy { File(storageDir, LAST_RUM_VIEW_EVENT_FILE_NAME) } + private val lastViewEventFileWriter: FileWriter by lazy { + BatchFileReaderWriter.create( + internalLogger = internalLogger, + encryption = localDataEncryption + ) + } + + internal val lastFatalAnrSent: Long? + get() { + val file = File(storageDir, LAST_FATAL_ANR_SENT_FILE_NAME) + return if (file.existsSafe(internalLogger)) { + file.readTextSafe(Charsets.UTF_8, internalLogger)?.toLongOrNull() + } else { + null + } + } + fun initialize( appContext: Context, sdkInstanceId: String, @@ -256,19 +294,81 @@ internal class CoreFeature( // region Internal + @WorkerThread + internal fun writeLastViewEvent(data: ByteArray) { + lastViewEventFileWriter.writeData(lastViewEventFile, RawBatchEvent(data), false) + } + + @WorkerThread + internal fun deleteLastViewEvent() { + if (lastViewEventFile.existsSafe(internalLogger)) { + lastViewEventFile.deleteSafe(internalLogger) + } else { + @Suppress("DEPRECATION") + val legacyViewEventFile = DatadogNdkCrashHandler.getLastViewEventFile(storageDir) + if (legacyViewEventFile.existsSafe(internalLogger)) { + legacyViewEventFile.deleteSafe(internalLogger) + } + } + } + + @WorkerThread + internal fun writeLastFatalAnrSent(anrTimestamp: Long) { + // TODO RUMM-0000 this is temporary solution for storing just a timestamp, later we will + // migrate to a dedicated data store solution (same applies to the last RUM view event) + val file = File(storageDir, LAST_FATAL_ANR_SENT_FILE_NAME) + file.writeTextSafe(anrTimestamp.toString(), Charsets.UTF_8, internalLogger) + } + + @WorkerThread + internal fun deleteLastFatalAnrSent() { + val file = File(storageDir, LAST_FATAL_ANR_SENT_FILE_NAME) + if (file.existsSafe(internalLogger)) { + file.deleteSafe(internalLogger) + } + } + + @WorkerThread + private fun readLastViewEvent(): JsonObject? { + val lastViewEventFile = if (lastViewEventFile.existsSafe(internalLogger)) { + lastViewEventFile + } else { + @Suppress("DEPRECATION") + val legacyViewEventFile = DatadogNdkCrashHandler.getLastViewEventFile(storageDir) + if (legacyViewEventFile.existsSafe(internalLogger)) { + legacyViewEventFile + } else { + null + } + } + + if (lastViewEventFile == null) return null + + val reader = + BatchFileReaderWriter.create(internalLogger, localDataEncryption) + val content = reader.readData(lastViewEventFile) + return if (content.isEmpty()) { + null + } else { + @Suppress("UnsafeThirdPartyFunctionCall") // safe to call last, collection is not empty + String(content.last().data, Charsets.UTF_8).run { + JsonObjectDeserializer(internalLogger).deserialize(this) + } + } + } + private fun prepareNdkCrashData(nativeSourceType: String?) { if (isMainProcess) { ndkCrashHandler = DatadogNdkCrashHandler( storageDir, persistenceExecutorService, NdkCrashLogDeserializer(internalLogger), - rumEventDeserializer = JsonObjectDeserializer(internalLogger), NetworkInfoDeserializer(internalLogger), UserInfoDeserializer(internalLogger), internalLogger, - rumFileReader = BatchFileReaderWriter.create(internalLogger, localDataEncryption), envFileReader = FileReaderWriter.create(internalLogger, localDataEncryption), - nativeSourceType ?: "ndk" + lastRumViewEventProvider = { lastViewEvent }, + nativeCrashSourceType = nativeSourceType ?: "ndk" ) ndkCrashHandler.prepareData() } @@ -542,6 +642,9 @@ internal class CoreFeature( internal const val DEFAULT_SDK_VERSION = BuildConfig.SDK_VERSION_NAME internal const val DEFAULT_APP_VERSION = "?" + internal const val LAST_RUM_VIEW_EVENT_FILE_NAME = "last_view_event" + internal const val LAST_FATAL_ANR_SENT_FILE_NAME = "last_fatal_anr_sent" + internal val RESTRICTED_CIPHER_SUITES = arrayOf( // TLS 1.3 diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/net/info/BroadcastReceiverNetworkInfoProvider.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/net/info/BroadcastReceiverNetworkInfoProvider.kt index d256ddc76b..5db0a4b095 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/net/info/BroadcastReceiverNetworkInfoProvider.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/net/info/BroadcastReceiverNetworkInfoProvider.kt @@ -19,14 +19,13 @@ import com.datadog.android.api.context.NetworkInfo import com.datadog.android.core.internal.persistence.DataWriter import com.datadog.android.core.internal.receiver.ThreadSafeReceiver import com.datadog.android.core.internal.system.BuildSdkVersionProvider -import com.datadog.android.core.internal.system.DefaultBuildSdkVersionProvider import android.net.NetworkInfo as AndroidNetworkInfo @Suppress("DEPRECATION") @SuppressLint("InlinedApi") internal class BroadcastReceiverNetworkInfoProvider( private val dataWriter: DataWriter, - private val buildSdkVersionProvider: BuildSdkVersionProvider = DefaultBuildSdkVersionProvider() + private val buildSdkVersionProvider: BuildSdkVersionProvider = BuildSdkVersionProvider.DEFAULT ) : ThreadSafeReceiver(), NetworkInfoProvider { @@ -104,7 +103,7 @@ internal class BroadcastReceiverNetworkInfoProvider( } val cellularTechnology = getCellularTechnology(subtype) - return if (buildSdkVersionProvider.version() >= Build.VERSION_CODES.P) { + return if (buildSdkVersionProvider.version >= Build.VERSION_CODES.P) { val telephonyMgr = context.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager val carrierName = telephonyMgr?.simCarrierIdName ?: UNKNOWN_CARRIER_NAME diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/net/info/CallbackNetworkInfoProvider.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/net/info/CallbackNetworkInfoProvider.kt index 4feb892915..b3643362ec 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/net/info/CallbackNetworkInfoProvider.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/net/info/CallbackNetworkInfoProvider.kt @@ -17,12 +17,11 @@ import com.datadog.android.api.InternalLogger import com.datadog.android.api.context.NetworkInfo import com.datadog.android.core.internal.persistence.DataWriter import com.datadog.android.core.internal.system.BuildSdkVersionProvider -import com.datadog.android.core.internal.system.DefaultBuildSdkVersionProvider @TargetApi(Build.VERSION_CODES.N) internal class CallbackNetworkInfoProvider( private val dataWriter: DataWriter, - private val buildSdkVersionProvider: BuildSdkVersionProvider = DefaultBuildSdkVersionProvider(), + private val buildSdkVersionProvider: BuildSdkVersionProvider = BuildSdkVersionProvider.DEFAULT, private val internalLogger: InternalLogger ) : ConnectivityManager.NetworkCallback(), @@ -164,7 +163,7 @@ internal class CallbackNetworkInfoProvider( @SuppressLint("NewApi") private fun resolveStrength(networkCapabilities: NetworkCapabilities): Long? { - return if (buildSdkVersionProvider.version() >= Build.VERSION_CODES.Q && + return if (buildSdkVersionProvider.version >= Build.VERSION_CODES.Q && networkCapabilities.signalStrength != NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED ) { networkCapabilities.signalStrength.toLong() diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/persistence/file/FileExt.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/persistence/file/FileExt.kt index 71769c0ef7..d3e6a3372d 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/persistence/file/FileExt.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/persistence/file/FileExt.kt @@ -182,3 +182,15 @@ fun File.readLinesSafe( null } } + +internal fun File.writeTextSafe( + text: String, charset: Charset = Charsets.UTF_8, + internalLogger: InternalLogger +) { + if (existsSafe(internalLogger) && canWriteSafe(internalLogger)) { + safeCall(default = null, internalLogger) { + @Suppress("UnsafeThirdPartyFunctionCall") + writeText(text, charset) + } + } +} diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/BuildSdkVersionProvider.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/BuildSdkVersionProvider.kt index 22edfb319f..062d8a1de2 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/BuildSdkVersionProvider.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/BuildSdkVersionProvider.kt @@ -7,6 +7,7 @@ package com.datadog.android.core.internal.system import android.os.Build +import androidx.annotation.ChecksSdkIntAtLeast /** * Wrapper around [Build.VERSION.SDK_INT] in order to simplify mocking in tests. @@ -18,5 +19,17 @@ interface BuildSdkVersionProvider { /** * Value of [Build.VERSION.SDK_INT]. */ - fun version(): Int + val version: Int + + companion object { + + /** + * Default implementation which calls Build.VERSION under the hood. + */ + val DEFAULT: BuildSdkVersionProvider = object : BuildSdkVersionProvider { + + @ChecksSdkIntAtLeast + override val version: Int = Build.VERSION.SDK_INT + } + } } diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/DefaultBuildSdkVersionProvider.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/DefaultBuildSdkVersionProvider.kt deleted file mode 100644 index f1a491c210..0000000000 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/DefaultBuildSdkVersionProvider.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2016-Present Datadog, Inc. - */ - -package com.datadog.android.core.internal.system - -import android.os.Build - -/** - * Check [BuildSdkVersionProvider] docs. - * - * FOR INTERNAL USAGE ONLY. - */ -class DefaultBuildSdkVersionProvider : BuildSdkVersionProvider { - - /** @inheritdoc */ - override fun version(): Int = Build.VERSION.SDK_INT -} diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/ndk/internal/DatadogNdkCrashHandler.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/ndk/internal/DatadogNdkCrashHandler.kt index 612383b431..d56bef184b 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/ndk/internal/DatadogNdkCrashHandler.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/ndk/internal/DatadogNdkCrashHandler.kt @@ -14,11 +14,9 @@ import com.datadog.android.api.feature.Feature import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.core.internal.persistence.Deserializer import com.datadog.android.core.internal.persistence.file.FileReader -import com.datadog.android.core.internal.persistence.file.batch.BatchFileReader import com.datadog.android.core.internal.persistence.file.existsSafe import com.datadog.android.core.internal.persistence.file.listFilesSafe import com.datadog.android.core.internal.persistence.file.readTextSafe -import com.datadog.android.core.internal.utils.join import com.datadog.android.core.internal.utils.submitSafe import com.datadog.android.log.LogAttributes import com.google.gson.JsonObject @@ -31,12 +29,11 @@ internal class DatadogNdkCrashHandler( storageDir: File, private val dataPersistenceExecutorService: ExecutorService, private val ndkCrashLogDeserializer: Deserializer, - private val rumEventDeserializer: Deserializer, private val networkInfoDeserializer: Deserializer, private val userInfoDeserializer: Deserializer, private val internalLogger: InternalLogger, - private val rumFileReader: BatchFileReader, private val envFileReader: FileReader, + private val lastRumViewEventProvider: () -> JsonObject?, internal val nativeCrashSourceType: String = "ndk" ) : NdkCrashHandler { @@ -80,6 +77,8 @@ internal class DatadogNdkCrashHandler( return } try { + lastRumViewEvent = lastRumViewEventProvider() + ndkCrashDataDirectory.listFilesSafe(internalLogger)?.forEach { file -> when (file.name) { // TODO RUMM-1944 Data from NDK should be also encrypted @@ -89,13 +88,6 @@ internal class DatadogNdkCrashHandler( ndkCrashLogDeserializer.deserialize(it) } - RUM_VIEW_EVENT_FILE_NAME -> - lastRumViewEvent = - readRumFileContent( - file, - rumFileReader - )?.let { rumEventDeserializer.deserialize(it) } - USER_INFO_FILE_NAME -> lastUserInfo = readFileContent( @@ -145,16 +137,6 @@ internal class DatadogNdkCrashHandler( } } - @WorkerThread - private fun readRumFileContent(file: File, fileReader: BatchFileReader): String? { - val content = fileReader.readData(file) - return if (content.isEmpty()) { - null - } else { - String(content.map { it.data }.join(ByteArray(0), internalLogger = internalLogger)) - } - } - @WorkerThread private fun checkAndHandleNdkCrashReport( sdkCore: FeatureSdkCore, @@ -363,7 +345,7 @@ internal class DatadogNdkCrashHandler( companion object { - internal const val RUM_VIEW_EVENT_FILE_NAME = "last_view_event" + private const val RUM_VIEW_EVENT_FILE_NAME = "last_view_event" internal const val CRASH_DATA_FILE_NAME = "crash_log" internal const val USER_INFO_FILE_NAME = "user_information" internal const val NETWORK_INFO_FILE_NAME = "network_information" @@ -395,6 +377,10 @@ internal class DatadogNdkCrashHandler( return File(storageDir, NDK_CRASH_REPORTS_PENDING_FOLDER_NAME) } + @Deprecated( + "We will still process this path to check file from the old SDK" + + " versions, but don't use it anymore for writing." + ) internal fun getLastViewEventFile(storageDir: File): File { return File(getNdkGrantedDir(storageDir), RUM_VIEW_EVENT_FILE_NAME) } diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/ndk/internal/NdkCrashHandler.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/ndk/internal/NdkCrashHandler.kt index 9eac129817..6e1aac6c01 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/ndk/internal/NdkCrashHandler.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/ndk/internal/NdkCrashHandler.kt @@ -11,6 +11,7 @@ import com.datadog.tools.annotation.NoOpImplementation @NoOpImplementation internal interface NdkCrashHandler { + fun prepareData() fun handleNdkCrash(sdkCore: FeatureSdkCore, reportTarget: ReportTarget) diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/DatadogCoreTest.kt b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/DatadogCoreTest.kt index 21f2d70831..76ace66b28 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/DatadogCoreTest.kt +++ b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/DatadogCoreTest.kt @@ -7,6 +7,7 @@ package com.datadog.android.core import android.app.Application +import android.os.Build import com.datadog.android.api.InternalLogger import com.datadog.android.api.context.NetworkInfo import com.datadog.android.api.context.TimeInfo @@ -21,22 +22,23 @@ import com.datadog.android.core.internal.lifecycle.ProcessLifecycleMonitor import com.datadog.android.core.internal.net.DefaultFirstPartyHostHeaderTypeResolver import com.datadog.android.core.internal.net.info.NetworkInfoProvider import com.datadog.android.core.internal.privacy.ConsentProvider +import com.datadog.android.core.internal.system.BuildSdkVersionProvider import com.datadog.android.core.internal.time.NoOpTimeProvider import com.datadog.android.core.internal.time.TimeProvider import com.datadog.android.core.internal.user.MutableUserInfoProvider -import com.datadog.android.ndk.internal.DatadogNdkCrashHandler import com.datadog.android.ndk.internal.NdkCrashHandler import com.datadog.android.privacy.TrackingConsent -import com.datadog.android.security.Encryption import com.datadog.android.utils.config.ApplicationContextTestConfiguration import com.datadog.android.utils.forge.Configurator import com.datadog.android.utils.verifyLog import com.datadog.tools.unit.annotations.TestConfigurationsProvider import com.datadog.tools.unit.extensions.TestConfigurationExtension import com.datadog.tools.unit.extensions.config.TestConfiguration +import com.google.gson.JsonObject import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.AdvancedForgery import fr.xgouchet.elmyr.annotation.Forgery +import fr.xgouchet.elmyr.annotation.IntForgery import fr.xgouchet.elmyr.annotation.LongForgery import fr.xgouchet.elmyr.annotation.MapForgery import fr.xgouchet.elmyr.annotation.StringForgery @@ -49,14 +51,12 @@ 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.Extensions -import org.junit.jupiter.api.io.TempDir import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.EnumSource import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension import org.mockito.junit.jupiter.MockitoSettings import org.mockito.kotlin.any -import org.mockito.kotlin.argThat import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn @@ -67,7 +67,6 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import org.mockito.quality.Strictness -import java.io.File import java.util.Locale import java.util.concurrent.ExecutorService import java.util.concurrent.TimeUnit @@ -86,7 +85,7 @@ import java.util.concurrent.atomic.AtomicReference @ForgeConfiguration(Configurator::class) internal class DatadogCoreTest { - lateinit var testedCore: DatadogCore + private lateinit var testedCore: DatadogCore @Mock lateinit var mockInternalLogger: InternalLogger @@ -94,6 +93,9 @@ internal class DatadogCoreTest { @Mock lateinit var mockPersistenceExecutorService: ExecutorService + @Mock + lateinit var mockBuildSdkVersionProvider: BuildSdkVersionProvider + @Forgery lateinit var fakeConfiguration: Configuration @@ -119,7 +121,8 @@ internal class DatadogCoreTest { fakeInstanceId, fakeInstanceName, internalLoggerProvider = { mockInternalLogger }, - persistenceExecutorServiceFactory = { mockPersistenceExecutorService } + persistenceExecutorServiceFactory = { mockPersistenceExecutorService }, + buildSdkVersionProvider = mockBuildSdkVersionProvider ).apply { initialize(fakeConfiguration) } @@ -485,6 +488,36 @@ internal class DatadogCoreTest { assertThat(networkInfo).isSameAs(fakeNetworkInfo) } + @Test + fun `𝕄 provide last view event 𝕎 lastViewEvent()`( + @Forgery fakeLastViewEvent: JsonObject + ) { + // Given + testedCore.coreFeature = mock() + whenever(testedCore.coreFeature.lastViewEvent) doReturn fakeLastViewEvent + + // When + val lastViewEvent = testedCore.lastViewEvent + + // Then + assertThat(lastViewEvent).isSameAs(fakeLastViewEvent) + } + + @Test + fun `𝕄 provide last fatal ANR sent 𝕎 lastFatalAnrSent()`( + @LongForgery(min = 0L) fakeLastFatalAnrSent: Long + ) { + // Given + testedCore.coreFeature = mock() + whenever(testedCore.coreFeature.lastFatalAnrSent) doReturn fakeLastFatalAnrSent + + // When + val lastFatalAnrSent = testedCore.lastFatalAnrSent + + // Then + assertThat(lastFatalAnrSent).isEqualTo(fakeLastFatalAnrSent) + } + @Test fun `𝕄 return tracking consent 𝕎 trackingConsent()`( @Forgery fakeTrackingConsent: TrackingConsent @@ -509,58 +542,48 @@ internal class DatadogCoreTest { } @Test - fun `𝕄 persist the event into the NDK crash folder 𝕎 writeLastViewEvent(){ViewEvent+dir exists}`( - @TempDir tempStorageDir: File, + fun `𝕄 persist the event 𝕎 writeLastViewEvent(){ NDK feature registered }`( @StringForgery viewEvent: String ) { // Given val fakeViewEvent = viewEvent.toByteArray() - - val ndkReportsFolder = File( - tempStorageDir, - DatadogNdkCrashHandler.NDK_CRASH_REPORTS_FOLDER_NAME - ) - ndkReportsFolder.mkdir() + testedCore.features += Feature.NDK_CRASH_REPORTS_FEATURE_NAME to mock() val mockCoreFeature = mock() - whenever(mockCoreFeature.storageDir) doReturn tempStorageDir + testedCore.coreFeature = mockCoreFeature + + // When + testedCore.writeLastViewEvent(fakeViewEvent) - val mockEncryption = mock() - whenever(mockCoreFeature.localDataEncryption) doReturn mockEncryption - whenever(mockEncryption.encrypt(fakeViewEvent)) doReturn fakeViewEvent.reversedArray() - whenever(mockEncryption.encrypt(argThat { isEmpty() })) doAnswer { it.getArgument(0) } + // Then + verify(mockCoreFeature).writeLastViewEvent(fakeViewEvent) + } + @Test + fun `𝕄 persist the event 𝕎 writeLastViewEvent(){ R+ }`( + @StringForgery viewEvent: String, + @IntForgery(min = Build.VERSION_CODES.R) fakeSdkVersion: Int + ) { + // Given + val fakeViewEvent = viewEvent.toByteArray() + whenever(mockBuildSdkVersionProvider.version) doReturn fakeSdkVersion + val mockCoreFeature = mock() testedCore.coreFeature = mockCoreFeature // When testedCore.writeLastViewEvent(fakeViewEvent) // Then - val lastViewEventFile = File( - ndkReportsFolder, - DatadogNdkCrashHandler.RUM_VIEW_EVENT_FILE_NAME - ) - assertThat(lastViewEventFile).exists() - - val fileContent = lastViewEventFile.readBytes() - // file will have batch file format, so beginning will contain some metadata, - // we need to skip it for the comparison - val payload = fileContent.takeLast(fakeViewEvent.size).toByteArray() - assertThat(payload) - .isEqualTo(fakeViewEvent.reversedArray()) + verify(mockCoreFeature).writeLastViewEvent(fakeViewEvent) } @Test - fun `𝕄 log info when writing last view event 𝕎 writeLastViewEvent(){ ViewEvent+no crash dir }`( - @TempDir tempStorageDir: File, - @StringForgery viewEvent: String + fun `𝕄 log info when writing last view event 𝕎 writeLastViewEvent(){ below R and no NDK feature }`( + @StringForgery viewEvent: String, + @IntForgery(min = 1, max = Build.VERSION_CODES.R) fakeSdkVersion: Int ) { // Given - val ndkReportsFolder = File( - tempStorageDir, - DatadogNdkCrashHandler.NDK_CRASH_REPORTS_FOLDER_NAME - ) val mockCoreFeature = mock() - whenever(mockCoreFeature.storageDir) doReturn tempStorageDir + whenever(mockBuildSdkVersionProvider.version) doReturn fakeSdkVersion testedCore.coreFeature = mockCoreFeature reset(mockInternalLogger) @@ -568,17 +591,41 @@ internal class DatadogCoreTest { testedCore.writeLastViewEvent(viewEvent.toByteArray()) // Then - assertThat(ndkReportsFolder).doesNotExist() mockInternalLogger.verifyLog( - InternalLogger.Level.WARN, + InternalLogger.Level.INFO, InternalLogger.Target.MAINTAINER, - DatadogCore.LAST_VIEW_EVENT_DIR_MISSING_MESSAGE.format( - Locale.US, - ndkReportsFolder - ) + DatadogCore.NO_NEED_TO_WRITE_LAST_VIEW_EVENT ) } + @Test + fun `𝕄 delete last view event 𝕎 deleteLastViewEvent()`() { + // Given + val mockCoreFeature = mock() + testedCore.coreFeature = mockCoreFeature + + // When + testedCore.deleteLastViewEvent() + + // Then + verify(mockCoreFeature).deleteLastViewEvent() + } + + @Test + fun `𝕄 write last fatal ANR sent 𝕎 writeLastFatalAnrSent()`( + @LongForgery(min = 0L) fakeLastFatalAnrSent: Long + ) { + // Given + val mockCoreFeature = mock() + testedCore.coreFeature = mockCoreFeature + + // When + testedCore.writeLastFatalAnrSent(fakeLastFatalAnrSent) + + // Then + verify(mockCoreFeature).writeLastFatalAnrSent(fakeLastFatalAnrSent) + } + @Test fun `𝕄 clear data in all features 𝕎 clearAllData()`( forge: Forge @@ -591,6 +638,8 @@ internal class DatadogCoreTest { anAlphaNumericalString() to mock() } ) + val mockCoreFeature = mock() + testedCore.coreFeature = mockCoreFeature // When testedCore.clearAllData() @@ -599,6 +648,8 @@ internal class DatadogCoreTest { testedCore.features.forEach { verify(it.value).clearAllData() } + verify(mockCoreFeature).deleteLastFatalAnrSent() + verify(mockCoreFeature).deleteLastViewEvent() } @Test diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/CoreFeatureTest.kt b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/CoreFeatureTest.kt index 986781ebe4..bb445c9e78 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/CoreFeatureTest.kt +++ b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/CoreFeatureTest.kt @@ -16,11 +16,13 @@ import android.os.Build import android.os.Process import com.datadog.android.Datadog import com.datadog.android.api.InternalLogger +import com.datadog.android.api.storage.RawBatchEvent import com.datadog.android.core.configuration.Configuration import com.datadog.android.core.internal.net.info.BroadcastReceiverNetworkInfoProvider import com.datadog.android.core.internal.net.info.CallbackNetworkInfoProvider import com.datadog.android.core.internal.net.info.NoOpNetworkInfoProvider import com.datadog.android.core.internal.persistence.file.FilePersistenceConfig +import com.datadog.android.core.internal.persistence.file.batch.BatchFileReaderWriter import com.datadog.android.core.internal.privacy.ConsentProvider import com.datadog.android.core.internal.privacy.NoOpConsentProvider import com.datadog.android.core.internal.privacy.TrackingConsentProvider @@ -43,10 +45,12 @@ import com.datadog.tools.unit.assertj.containsInstanceOf import com.datadog.tools.unit.extensions.ApiLevelExtension import com.datadog.tools.unit.extensions.TestConfigurationExtension import com.datadog.tools.unit.extensions.config.TestConfiguration +import com.google.gson.JsonObject import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.AdvancedForgery import fr.xgouchet.elmyr.annotation.Forgery import fr.xgouchet.elmyr.annotation.IntForgery +import fr.xgouchet.elmyr.annotation.LongForgery import fr.xgouchet.elmyr.annotation.MapForgery import fr.xgouchet.elmyr.annotation.StringForgery import fr.xgouchet.elmyr.annotation.StringForgeryType @@ -886,7 +890,7 @@ internal class CoreFeatureTest { } @Test - fun `𝕄 initialise persitence strategy 𝕎 initialize`() { + fun `𝕄 initialise persistence strategy 𝕎 initialize`() { // Given val mockPersistenceStrategyFactory = mock() fakeConfig = fakeConfig.copy( @@ -910,6 +914,195 @@ internal class CoreFeatureTest { // endregion + @Test + fun `𝕄 return last fatal ANR sent 𝕎 lastFatalAnrSent`( + @TempDir tempDir: File, + @LongForgery(min = 0L) fakeLastFatalAnrSent: Long + ) { + // Given + testedFeature.storageDir = tempDir + File(tempDir, CoreFeature.LAST_FATAL_ANR_SENT_FILE_NAME) + .writeText(fakeLastFatalAnrSent.toString()) + + // When + val lastFatalAnrSent = testedFeature.lastFatalAnrSent + + // Then + assertThat(lastFatalAnrSent).isEqualTo(fakeLastFatalAnrSent) + } + + @Test + fun `𝕄 return null 𝕎 lastFatalAnrSent { no file }`( + @TempDir tempDir: File + ) { + // Given + testedFeature.storageDir = tempDir + + // When + val lastFatalAnrSent = testedFeature.lastFatalAnrSent + + // Then + assertThat(lastFatalAnrSent).isNull() + } + + @Test + fun `𝕄 return null 𝕎 lastFatalAnrSent { file contains not a number }`( + @TempDir tempDir: File, + @StringForgery fakeBrokenLastFatalAnrSent: String + ) { + // Given + testedFeature.storageDir = tempDir + File(tempDir, CoreFeature.LAST_FATAL_ANR_SENT_FILE_NAME) + .writeText(fakeBrokenLastFatalAnrSent) + + // When + val lastFatalAnrSent = testedFeature.lastFatalAnrSent + + // Then + assertThat(lastFatalAnrSent).isNull() + } + + @Test + fun `𝕄 delete last fatal ANR sent 𝕎 deleteLastFatalAnrSent`( + @TempDir tempDir: File, + @LongForgery fakeLastFatalAnrSent: Long + ) { + // Given + testedFeature.storageDir = tempDir + File(tempDir, CoreFeature.LAST_FATAL_ANR_SENT_FILE_NAME) + .writeText(fakeLastFatalAnrSent.toString()) + + // When + testedFeature.deleteLastFatalAnrSent() + + // Then + assertThat(File(tempDir, CoreFeature.LAST_FATAL_ANR_SENT_FILE_NAME)).doesNotExist() + } + + @Test + fun `𝕄 write last view event 𝕎 writeLastViewEvent`( + @TempDir tempDir: File, + @StringForgery viewEvent: String + ) { + // Given + val fakeViewEvent = viewEvent.toByteArray() + + testedFeature.storageDir = tempDir + + // When + testedFeature.writeLastViewEvent(fakeViewEvent) + + // Then + val lastViewEventFile = File( + tempDir, + CoreFeature.LAST_RUM_VIEW_EVENT_FILE_NAME + ) + assertThat(lastViewEventFile).exists() + + val fileContent = lastViewEventFile.readBytes() + // file will have batch file format, so beginning will contain some metadata, + // we need to skip it for the comparison + val payload = fileContent.takeLast(fakeViewEvent.size).toByteArray() + assertThat(payload).isEqualTo(fakeViewEvent) + } + + @Test + fun `𝕄 delete last view event 𝕎 deleteLastViewEvent`( + @TempDir tempDir: File, + @StringForgery fakeViewEvent: String + ) { + // Given + testedFeature.storageDir = tempDir + File(tempDir, CoreFeature.LAST_RUM_VIEW_EVENT_FILE_NAME) + .writeText(fakeViewEvent) + + // When + testedFeature.deleteLastViewEvent() + + // Then + assertThat(File(tempDir, CoreFeature.LAST_RUM_VIEW_EVENT_FILE_NAME)).doesNotExist() + } + + @Suppress("DEPRECATION") + @Test + fun `𝕄 delete last view event 𝕎 deleteLastViewEvent { legacy NDK location }`( + @TempDir tempDir: File, + @StringForgery fakeViewEvent: String + ) { + // Given + testedFeature.storageDir = tempDir + DatadogNdkCrashHandler.getLastViewEventFile(tempDir) + .apply { + parentFile?.mkdirs() + } + .writeText(fakeViewEvent) + + // When + testedFeature.deleteLastViewEvent() + + // Then + assertThat(DatadogNdkCrashHandler.getLastViewEventFile(tempDir)).doesNotExist() + } + + @Test + fun `𝕄 return null 𝕎 lastViewEvent { no last view event written }`( + @TempDir tempDir: File + ) { + // Given + testedFeature.storageDir = tempDir + + // When + val lastViewEvent = testedFeature.lastViewEvent + + // Then + assertThat(lastViewEvent).isNull() + } + + @Test + fun `𝕄 return last view event 𝕎 lastViewEvent`( + @TempDir tempDir: File, + @Forgery fakeViewEvent: JsonObject + ) { + // Given + testedFeature.storageDir = tempDir + testedFeature.writeLastViewEvent(fakeViewEvent.toString().toByteArray()) + + // When + val lastViewEvent = testedFeature.lastViewEvent + + // Then + assertThat(lastViewEvent.toString()).isEqualTo(fakeViewEvent.toString()) + // file must be deleted once view event is read + assertThat(File(tempDir, CoreFeature.LAST_RUM_VIEW_EVENT_FILE_NAME)).doesNotExist() + } + + @Test + fun `𝕄 return last view event 𝕎 lastViewEvent { check old NDK location }`( + @TempDir tempDir: File, + @Forgery fakeViewEvent: JsonObject + ) { + // Given + testedFeature.storageDir = tempDir + + @Suppress("DEPRECATION") + val legacyNdkViewEventFile = DatadogNdkCrashHandler.getLastViewEventFile(tempDir) + legacyNdkViewEventFile.parentFile?.mkdirs() + + BatchFileReaderWriter + .create(internalLogger = mock(), encryption = null) + .writeData( + legacyNdkViewEventFile, + RawBatchEvent(fakeViewEvent.toString().toByteArray()), + append = false + ) + + // When + val lastViewEvent = testedFeature.lastViewEvent + + // Then + assertThat(lastViewEvent.toString()).isEqualTo(fakeViewEvent.toString()) + } + // region shutdown @Test diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/net/info/BroadcastReceiverNetworkInfoProviderTest.kt b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/net/info/BroadcastReceiverNetworkInfoProviderTest.kt index faf9f72c95..ea048a0e95 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/net/info/BroadcastReceiverNetworkInfoProviderTest.kt +++ b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/net/info/BroadcastReceiverNetworkInfoProviderTest.kt @@ -80,7 +80,7 @@ internal class BroadcastReceiverNetworkInfoProviderTest { whenever(mockContext.getSystemService(Context.TELEPHONY_SERVICE)) .doReturn(mockTelephonyManager) whenever(mockConnectivityManager.activeNetworkInfo) doReturn mockNetworkInfo - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.BASE + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.BASE testedProvider = BroadcastReceiverNetworkInfoProvider( mockWriter, @@ -246,7 +246,7 @@ internal class BroadcastReceiverNetworkInfoProviderTest { forge: Forge ) { // GIVEN - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.P + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.P val carrierName = forge.anAlphabeticalString() val carrierId = forge.aPositiveInt(strict = true) @@ -291,7 +291,7 @@ internal class BroadcastReceiverNetworkInfoProviderTest { forge: Forge ) { // GIVEN - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.P + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.P val carrierName = forge.anAlphabeticalString() val carrierId = forge.aPositiveInt(strict = true) @@ -336,7 +336,7 @@ internal class BroadcastReceiverNetworkInfoProviderTest { forge: Forge ) { // GIVEN - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.P + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.P val carrierName = forge.anAlphabeticalString() val carrierId = forge.aPositiveInt(strict = true) @@ -381,7 +381,7 @@ internal class BroadcastReceiverNetworkInfoProviderTest { forge: Forge ) { // GIVEN - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.P + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.P val carrierName = forge.anAlphabeticalString() val carrierId = forge.aPositiveInt(strict = true) @@ -423,7 +423,7 @@ internal class BroadcastReceiverNetworkInfoProviderTest { @MethodSource("getKnownMobileTypes") fun `connected to mobile unknown API 28+`(mobileType: MobileType, forge: Forge) { // GIVEN - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.P + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.P val subtype = forge.anInt(min = 32) val carrierName = forge.anAlphabeticalString() @@ -447,7 +447,7 @@ internal class BroadcastReceiverNetworkInfoProviderTest { @MethodSource("getKnownMobileTypes") fun `connected to mobile unknown carrier`(mobileType: MobileType) { // GIVEN - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.P + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.P stubNetworkInfo( mobileType.id, diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/net/info/CallbackNetworkInfoProviderTest.kt b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/net/info/CallbackNetworkInfoProviderTest.kt index 50db796916..f26dd9441e 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/net/info/CallbackNetworkInfoProviderTest.kt +++ b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/net/info/CallbackNetworkInfoProviderTest.kt @@ -70,7 +70,7 @@ internal class CallbackNetworkInfoProviderTest { whenever(mockCapabilities.signalStrength) doReturn NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED whenever(mockCapabilities.hasTransport(any())) doReturn false - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.BASE + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.BASE testedProvider = CallbackNetworkInfoProvider(mockWriter, mockBuildSdkVersionProvider, mockInternalLogger) @@ -100,7 +100,7 @@ internal class CallbackNetworkInfoProviderTest { whenever(mockCapabilities.linkUpstreamBandwidthKbps) doReturn upSpeed whenever(mockCapabilities.linkDownstreamBandwidthKbps) doReturn downSpeed whenever(mockCapabilities.signalStrength) doReturn strength - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.Q + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.Q // WHEN testedProvider.onCapabilitiesChanged(mockNetwork, mockCapabilities) @@ -171,7 +171,7 @@ internal class CallbackNetworkInfoProviderTest { whenever(mockCapabilities.linkUpstreamBandwidthKbps) doReturn upSpeed whenever(mockCapabilities.linkDownstreamBandwidthKbps) doReturn downSpeed whenever(mockCapabilities.signalStrength) doReturn strength - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.Q + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.Q // WHEN testedProvider.onCapabilitiesChanged(mockNetwork, mockCapabilities) diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/system/DefaultAndroidInfoProviderTest.kt b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/system/DefaultAndroidInfoProviderTest.kt index a7a8d51bcf..31fea21347 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/system/DefaultAndroidInfoProviderTest.kt +++ b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/system/DefaultAndroidInfoProviderTest.kt @@ -73,7 +73,7 @@ internal class DefaultAndroidInfoProviderTest { mockUiModeManager whenever(mockContext.getSystemService(Context.TELEPHONY_SERVICE)) doReturn mockTelephonyManager - whenever(mockSdkVersionProvider.version()) doReturn + whenever(mockSdkVersionProvider.version) doReturn forge.anInt(min = Build.VERSION_CODES.BASE) whenever(mockContext.packageManager) doReturn mockPackageManager whenever(mockContext.resources) doReturn mockResources diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/ndk/internal/DatadogNdkCrashHandlerTest.kt b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/ndk/internal/DatadogNdkCrashHandlerTest.kt index 3e70d56d45..519d5cf334 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/ndk/internal/DatadogNdkCrashHandlerTest.kt +++ b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/ndk/internal/DatadogNdkCrashHandlerTest.kt @@ -12,10 +12,8 @@ import com.datadog.android.api.context.UserInfo import com.datadog.android.api.feature.Feature import com.datadog.android.api.feature.FeatureScope import com.datadog.android.api.feature.FeatureSdkCore -import com.datadog.android.api.storage.RawBatchEvent import com.datadog.android.core.internal.persistence.Deserializer import com.datadog.android.core.internal.persistence.file.FileReader -import com.datadog.android.core.internal.persistence.file.batch.BatchFileReader import com.datadog.android.log.LogAttributes import com.datadog.android.utils.forge.Configurator import com.datadog.android.utils.verifyLog @@ -75,9 +73,6 @@ internal class DatadogNdkCrashHandlerTest { @Mock lateinit var mockNdkCrashLogDeserializer: Deserializer - @Mock - lateinit var mockRumEventDeserializer: Deserializer - @Mock lateinit var mockNetworkInfoDeserializer: Deserializer @@ -97,10 +92,10 @@ internal class DatadogNdkCrashHandlerTest { lateinit var mockInternalLogger: InternalLogger @Mock - lateinit var mockRumFileReader: BatchFileReader + lateinit var mockEnvFileReader: FileReader @Mock - lateinit var mockEnvFileReader: FileReader + lateinit var mockLastRumViewEventProvider: () -> JsonObject? lateinit var fakeNdkCacheDir: File @@ -113,11 +108,6 @@ internal class DatadogNdkCrashHandlerTest { @BeforeEach fun `set up`() { fakeNdkCacheDir = File(tempDir, DatadogNdkCrashHandler.NDK_CRASH_REPORTS_FOLDER_NAME) - whenever(mockRumFileReader.readData(any())) doAnswer { - listOf( - RawBatchEvent(it.getArgument(0).readBytes()) - ) - } whenever(mockEnvFileReader.readData(any())) doAnswer { it.getArgument(0).readBytes() } @@ -134,12 +124,11 @@ internal class DatadogNdkCrashHandlerTest { tempDir, mockExecutorService, mockNdkCrashLogDeserializer, - mockRumEventDeserializer, mockNetworkInfoDeserializer, mockUserInfoDeserializer, mockInternalLogger, - mockRumFileReader, - mockEnvFileReader + mockEnvFileReader, + mockLastRumViewEventProvider ) } @@ -168,16 +157,12 @@ internal class DatadogNdkCrashHandlerTest { @Test fun `𝕄 read last RUM View event 𝕎 prepareData()`( - @StringForgery viewEventStr: String, forge: Forge ) { // Given fakeNdkCacheDir.mkdirs() - File(fakeNdkCacheDir, DatadogNdkCrashHandler.RUM_VIEW_EVENT_FILE_NAME).writeText( - viewEventStr - ) val fakeViewEvent = forge.aFakeViewEvent() - whenever(mockRumEventDeserializer.deserialize(viewEventStr)) doReturn fakeViewEvent.toJson() + whenever(mockLastRumViewEventProvider()) doReturn fakeViewEvent.toJson() // When testedHandler.prepareData() @@ -237,7 +222,6 @@ internal class DatadogNdkCrashHandlerTest { fun `𝕄 do nothing 𝕎 prepareData() {directory does not exist}`() { // When testedHandler.prepareData() - whenever(mockRumEventDeserializer.deserialize(any())) doReturn mock() whenever(mockNdkCrashLogDeserializer.deserialize(any())) doReturn mock() whenever(mockUserInfoDeserializer.deserialize(any())) doReturn mock() whenever(mockNetworkInfoDeserializer.deserialize(any())) doReturn mock() @@ -254,7 +238,6 @@ internal class DatadogNdkCrashHandlerTest { @Test fun `𝕄 clear crash data 𝕎 prepareData()`( @StringForgery crashData: String, - @StringForgery viewEvent: String, @StringForgery networkInfo: String, @StringForgery userInfo: String ) { @@ -262,7 +245,6 @@ internal class DatadogNdkCrashHandlerTest { fakeNdkCacheDir.mkdirs() File(fakeNdkCacheDir, DatadogNdkCrashHandler.CRASH_DATA_FILE_NAME).writeText(crashData) - File(fakeNdkCacheDir, DatadogNdkCrashHandler.RUM_VIEW_EVENT_FILE_NAME).writeText(viewEvent) File(fakeNdkCacheDir, DatadogNdkCrashHandler.NETWORK_INFO_FILE_NAME) .writeText(networkInfo) File(fakeNdkCacheDir, DatadogNdkCrashHandler.USER_INFO_FILE_NAME).writeText(userInfo) @@ -393,13 +375,12 @@ internal class DatadogNdkCrashHandlerTest { tempDir, mockExecutorService, mockNdkCrashLogDeserializer, - mockRumEventDeserializer, mockNetworkInfoDeserializer, mockUserInfoDeserializer, mockInternalLogger, - mockRumFileReader, mockEnvFileReader, - "ndk+il2cpp" + lastRumViewEventProvider = { JsonObject() }, + nativeCrashSourceType = "ndk+il2cpp" ) val fakeViewEvent = forge.aFakeViewEvent() @@ -565,13 +546,12 @@ internal class DatadogNdkCrashHandlerTest { tempDir, mockExecutorService, mockNdkCrashLogDeserializer, - mockRumEventDeserializer, mockNetworkInfoDeserializer, mockUserInfoDeserializer, mockInternalLogger, - mockRumFileReader, mockEnvFileReader, - "ndk+il2cpp" + lastRumViewEventProvider = { JsonObject() }, + nativeCrashSourceType = "ndk+il2cpp" ) val fakeViewEvent = forge.aFakeViewEvent() diff --git a/detekt_custom.yml b/detekt_custom.yml index 91f34ac942..a0ca3d3c37 100644 --- a/detekt_custom.yml +++ b/detekt_custom.yml @@ -97,6 +97,7 @@ datadog: treatUnknownConstructorAsThrowing: true knownThrowingCalls: # region Android + - "android.app.ActivityManager.getHistoricalProcessExitReasons(kotlin.String?, kotlin.Int, kotlin.Int):java.lang.RuntimeException" - "android.content.pm.PackageManager.getPackageInfo(kotlin.String, android.content.pm.PackageManager.PackageInfoFlags):android.content.pm.PackageManager.NameNotFoundException" - "android.content.pm.PackageManager.getPackageInfo(kotlin.String, kotlin.Int):android.content.pm.PackageManager.NameNotFoundException" - "android.content.res.Resources.getResourceEntryName(kotlin.Int):android.content.res.Resources.NotFoundException" @@ -157,6 +158,8 @@ datadog: - "java.io.InputStream.read(kotlin.ByteArray, kotlin.Int, kotlin.Int):java.io.IOException" - "java.io.InputStream.reset():java.io.IOException" - "java.io.InputStream.skip(kotlin.Long):java.io.IOException" + - "java.io.InputStream.use(kotlin.Function1):java.io.IOException" + - "java.io.InputStreamReader.readText():java.io.IOException" - "java.nio.ByteBuffer.allocate(kotlin.Int):java.lang.IllegalArgumentException" - "java.nio.ByteBuffer.array():java.nio.ReadOnlyBufferException,java.lang.UnsupportedOperationException" - "java.nio.ByteBuffer.put(kotlin.ByteArray):java.nio.BufferOverflowException,java.nio.ReadOnlyBufferException" @@ -693,8 +696,11 @@ datadog: - "java.io.File.safeCall(kotlin.Long, com.datadog.android.api.InternalLogger, kotlin.Function1)" - "java.io.File.safeCall(kotlin.String?, com.datadog.android.api.InternalLogger, kotlin.Function1)" - "java.io.File.safeCall(kotlin.collections.List?, com.datadog.android.api.InternalLogger, kotlin.Function1)" + - "java.io.File.safeCall(kotlin.Unit?, com.datadog.android.api.InternalLogger, kotlin.Function1)" + - "java.io.File.writeTextSafe(kotlin.String, java.nio.charset.Charset, com.datadog.android.api.InternalLogger)" - "java.io.InputStream.mark(kotlin.Int)" - "java.io.InputStream.markSupported()" + - "java.io.InputStream.reader(java.nio.charset.Charset)" - "java.io.StringWriter.constructor()" - "java.io.close()" # endregion @@ -810,6 +816,7 @@ datadog: - "kotlin.collections.List.contains(kotlin.String)" - "kotlin.collections.List.count()" - "kotlin.collections.List.drop(kotlin.Int)" + - "kotlin.collections.List.elementAtOrNull(kotlin.Int)" - "kotlin.collections.List.filter(kotlin.Function1)" - "kotlin.collections.List.filterIndexed(kotlin.Function2)" - "kotlin.collections.List.filterNotNull(kotlin.Function1)" @@ -1118,6 +1125,7 @@ datadog: - "kotlin.String.toMediaTypeOrNull()" - "kotlin.String.toMethod()" - "kotlin.String.toOperationType(com.datadog.android.api.InternalLogger)" + - "kotlin.String.trimStart()" - "kotlin.String.uppercase(java.util.Locale)" - "kotlin.String.withSdkName()" - "kotlin.text.String(kotlin.ByteArray)" diff --git a/features/dd-sdk-android-ndk/src/main/kotlin/com/datadog/android/ndk/internal/NdkCrashReportsFeature.kt b/features/dd-sdk-android-ndk/src/main/kotlin/com/datadog/android/ndk/internal/NdkCrashReportsFeature.kt index a788273c8e..2159ca1ed5 100644 --- a/features/dd-sdk-android-ndk/src/main/kotlin/com/datadog/android/ndk/internal/NdkCrashReportsFeature.kt +++ b/features/dd-sdk-android-ndk/src/main/kotlin/com/datadog/android/ndk/internal/NdkCrashReportsFeature.kt @@ -26,7 +26,7 @@ internal class NdkCrashReportsFeature(private val sdkCore: FeatureSdkCore) : TrackingConsentProviderCallback { private var nativeLibraryLoaded = false - override val name: String = "ndk-crash-reporting" + override val name: String = Feature.NDK_CRASH_REPORTS_FEATURE_NAME // region Feature @Suppress("ReturnCount") diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/Rum.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/Rum.kt index 965fb72c3a..9576ecbd4a 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/Rum.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/Rum.kt @@ -6,6 +6,7 @@ package com.datadog.android.rum +import android.os.Build import android.os.Handler import android.os.Looper import com.datadog.android.Datadog @@ -72,6 +73,15 @@ object Rum { sdkCore.registerFeature(rumFeature) val rumMonitor = createMonitor(sdkCore, rumFeature) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // small hack: we need to read last RUM view event file, but we don't want to do on the + // main thread, but at the same time we want to read it surely before it is updated + // by the new RUM session, so we will read it on the RUM events thread (once read we + // will switch to another worker thread, so that RUM events thread is not busy) + rumFeature.consumeLastFatalAnr(rumMonitor.executorService) + } + GlobalRumMonitor.registerIfAbsent( monitor = rumMonitor, sdkCore diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/ndk/DatadogNdkCrashEventHandler.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/DatadogLateCrashReporter.kt similarity index 54% rename from features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/ndk/DatadogNdkCrashEventHandler.kt rename to features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/DatadogLateCrashReporter.kt index 3d29d29e4d..2c8c8ebcf7 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/ndk/DatadogNdkCrashEventHandler.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/DatadogLateCrashReporter.kt @@ -4,14 +4,22 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.rum.internal.ndk +package com.datadog.android.rum.internal +import android.app.ApplicationExitInfo +import android.os.Build +import androidx.annotation.RequiresApi import com.datadog.android.api.InternalLogger import com.datadog.android.api.context.DatadogContext import com.datadog.android.api.feature.Feature -import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.api.storage.DataWriter +import com.datadog.android.core.InternalSdkCore +import com.datadog.android.core.feature.event.ThreadDump import com.datadog.android.core.internal.persistence.Deserializer +import com.datadog.android.rum.internal.anr.ANRDetectorRunnable +import com.datadog.android.rum.internal.anr.ANRException +import com.datadog.android.rum.internal.anr.AndroidTraceParser +import com.datadog.android.rum.internal.domain.RumContext import com.datadog.android.rum.internal.domain.event.RumEventDeserializer import com.datadog.android.rum.internal.domain.scope.toErrorSchemaType import com.datadog.android.rum.internal.domain.scope.tryFromSource @@ -20,17 +28,25 @@ import com.datadog.android.rum.model.ViewEvent import com.google.gson.JsonObject import java.util.concurrent.TimeUnit -internal class DatadogNdkCrashEventHandler( - private val internalLogger: InternalLogger, - private val rumEventDeserializer: Deserializer = RumEventDeserializer(internalLogger) -) : NdkCrashEventHandler { +internal class DatadogLateCrashReporter( + private val sdkCore: InternalSdkCore, + private val rumEventDeserializer: Deserializer = RumEventDeserializer( + sdkCore.internalLogger + ), + private val androidTraceParser: AndroidTraceParser = AndroidTraceParser(sdkCore.internalLogger) +) : LateCrashReporter { + + // region LateCrashEventHandler @Suppress("ComplexCondition") - override fun handleEvent(event: Map<*, *>, sdkCore: FeatureSdkCore, rumWriter: DataWriter) { + override fun handleNdkCrashEvent( + event: Map<*, *>, + rumWriter: DataWriter + ) { val rumFeature = sdkCore.getFeature(Feature.RUM_FEATURE_NAME) if (rumFeature == null) { - internalLogger.log( + sdkCore.internalLogger.log( InternalLogger.Level.INFO, InternalLogger.Target.USER, { INFO_RUM_FEATURE_NOT_REGISTERED } @@ -47,12 +63,10 @@ internal class DatadogNdkCrashEventHandler( rumEventDeserializer.deserialize(it) as? ViewEvent } - val sampleRate = lastViewEvent?.dd?.configuration?.sessionSampleRate?.toFloat() ?: 0f - if (timestamp == null || signalName == null || stacktrace == null || errorLogMessage == null || lastViewEvent == null ) { - internalLogger.log( + sdkCore.internalLogger.log( InternalLogger.Level.WARN, InternalLogger.Target.USER, { NDK_CRASH_EVENT_MISSING_MANDATORY_FIELDS } @@ -60,22 +74,20 @@ internal class DatadogNdkCrashEventHandler( return } - val now = System.currentTimeMillis() rumFeature.withWriteContext { datadogContext, eventBatchWriter -> val toSendErrorEvent = resolveErrorEventFromViewEvent( datadogContext, - sourceType, + ErrorEvent.SourceType.tryFromSource(sourceType), errorLogMessage, timestamp, stacktrace, signalName, - lastViewEvent, - sampleRate + null, + lastViewEvent ) @Suppress("ThreadSafety") // called in a worker thread context rumWriter.write(eventBatchWriter, toSendErrorEvent) - val sessionsTimeDifference = now - lastViewEvent.date - if (sessionsTimeDifference < VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD) { + if (lastViewEvent.isWithinSessionAvailability) { val updatedViewEvent = updateViewEvent(lastViewEvent) @Suppress("ThreadSafety") // called in a worker thread context rumWriter.write(eventBatchWriter, updatedViewEvent) @@ -83,21 +95,81 @@ internal class DatadogNdkCrashEventHandler( } } + @RequiresApi(Build.VERSION_CODES.R) + override fun handleAnrCrash( + anrExitInfo: ApplicationExitInfo, + lastRumViewEventJson: JsonObject, + rumWriter: DataWriter + ) { + val lastViewEvent = + rumEventDeserializer.deserialize(lastRumViewEventJson) as? ViewEvent ?: return + + val lastKnownViewStartedAt = lastViewEvent.date + if (anrExitInfo.timestamp > lastKnownViewStartedAt) { + val rumFeature = sdkCore.getFeature(Feature.RUM_FEATURE_NAME) + + if (rumFeature == null) { + sdkCore.internalLogger.log( + InternalLogger.Level.WARN, + InternalLogger.Target.USER, + { INFO_RUM_FEATURE_NOT_REGISTERED } + ) + return + } + + rumFeature.withWriteContext { datadogContext, eventBatchWriter -> + // means we are too late, last view event belongs to the ongoing session + if (lastViewEvent.session.id == datadogContext.rumSessionId) return@withWriteContext + + val lastFatalAnrSent = sdkCore.lastFatalAnrSent + if (anrExitInfo.timestamp == lastFatalAnrSent) return@withWriteContext + + val threadDumps = readThreadsDump(anrExitInfo) + if (threadDumps.isEmpty()) return@withWriteContext + + val toSendErrorEvent = resolveErrorEventFromViewEvent( + datadogContext, + ErrorEvent.SourceType.ANDROID, + ANRDetectorRunnable.ANR_MESSAGE, + anrExitInfo.timestamp, + threadDumps.mainThread?.stack.orEmpty(), + ANRException::class.java.canonicalName.orEmpty(), + threadDumps, + lastViewEvent + ) + @Suppress("ThreadSafety") // called in a worker thread context + rumWriter.write(eventBatchWriter, toSendErrorEvent) + if (lastViewEvent.isWithinSessionAvailability) { + val updatedViewEvent = updateViewEvent(lastViewEvent) + @Suppress("ThreadSafety") // called in a worker thread context + rumWriter.write(eventBatchWriter, updatedViewEvent) + } + @Suppress("ThreadSafety") // called in a worker thread context + sdkCore.writeLastFatalAnrSent(anrExitInfo.timestamp) + } + } + } + + // endregion + + // region Internal + @Suppress("LongMethod", "LongParameterList") private fun resolveErrorEventFromViewEvent( datadogContext: DatadogContext, - sourceTypeStr: String?, + sourceType: ErrorEvent.SourceType, errorLogMessage: String, timestamp: Long, stacktrace: String, - signalName: String, - viewEvent: ViewEvent, - sampleRate: Float + errorType: String, + threadDumps: List?, + viewEvent: ViewEvent ): ErrorEvent { val connectivity = viewEvent.connectivity?.let { val connectivityStatus = ErrorEvent.Status.valueOf(it.status.name) - val connectivityInterfaces = it.interfaces?.map { ErrorEvent.Interface.valueOf(it.name) } + val connectivityInterfaces = + it.interfaces?.map { ErrorEvent.Interface.valueOf(it.name) } val cellular = ErrorEvent.Cellular( it.cellular?.technology, it.cellular?.carrierName @@ -111,21 +183,6 @@ internal class DatadogNdkCrashEventHandler( user?.email != null || additionalUserProperties.isNotEmpty() val deviceInfo = datadogContext.deviceInfo - val sourceType = sourceTypeStr?.let { - @Suppress("TooGenericExceptionCaught") - try { - ErrorEvent.SourceType.fromJson(sourceTypeStr) - } catch (e: Exception) { - internalLogger.log( - InternalLogger.Level.ERROR, - InternalLogger.Target.TELEMETRY, - { "Error parsing source type from NDK crash event: $sourceTypeStr" }, - e - ) - ErrorEvent.SourceType.NDK - } - } ?: ErrorEvent.SourceType.NDK - return ErrorEvent( date = timestamp + datadogContext.time.serverTimeOffsetMs, application = ErrorEvent.Application(viewEvent.application.id), @@ -137,7 +194,7 @@ internal class DatadogNdkCrashEventHandler( source = viewEvent.source?.toJson()?.asString?.let { ErrorEvent.ErrorEventSource.tryFromSource( it, - internalLogger + sdkCore.internalLogger ) }, view = ErrorEvent.ErrorEventView( @@ -171,7 +228,7 @@ internal class DatadogNdkCrashEventHandler( ), dd = ErrorEvent.Dd( session = ErrorEvent.DdSession(plan = ErrorEvent.Plan.PLAN_1), - configuration = ErrorEvent.Configuration(sessionSampleRate = sampleRate) + configuration = ErrorEvent.Configuration(sessionSampleRate = viewEvent.sampleRate) ), context = ErrorEvent.Context(additionalProperties = additionalProperties), error = ErrorEvent.Error( @@ -179,13 +236,36 @@ internal class DatadogNdkCrashEventHandler( source = ErrorEvent.ErrorSource.SOURCE, stack = stacktrace, isCrash = true, - type = signalName, - sourceType = sourceType + type = errorType, + sourceType = sourceType, + threads = threadDumps?.map { + ErrorEvent.Thread( + it.name, + it.crashed, + it.stack, + it.state + ) + } ), version = viewEvent.version ) } + @RequiresApi(Build.VERSION_CODES.R) + private fun readThreadsDump(anrExitInfo: ApplicationExitInfo): List { + val traceInputStream = anrExitInfo.traceInputStream + if (traceInputStream == null) { + sdkCore.internalLogger.log( + InternalLogger.Level.WARN, + InternalLogger.Target.USER, + { MISSING_ANR_TRACE } + ) + return emptyList() + } + + return androidTraceParser.parse(traceInputStream) + } + private fun updateViewEvent(lastViewEvent: ViewEvent): ViewEvent { val currentCrash = lastViewEvent.view.crash val newCrash = currentCrash?.copy(count = currentCrash.count + 1) ?: ViewEvent.Crash(1) @@ -200,6 +280,43 @@ internal class DatadogNdkCrashEventHandler( ) } + private val ViewEvent.sampleRate: Float + get() = dd.configuration?.sessionSampleRate?.toFloat() ?: 0f + + private val ViewEvent.isWithinSessionAvailability: Boolean + get() { + val now = System.currentTimeMillis() + val sessionsTimeDifference = now - this.date + return sessionsTimeDifference < VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD + } + + private val List.mainThread: ThreadDump? + get() = firstOrNull { it.name == "main" } + + private fun ErrorEvent.SourceType.Companion.tryFromSource( + sourceType: String? + ): ErrorEvent.SourceType { + return if (sourceType != null) { + try { + ErrorEvent.SourceType.fromJson(sourceType) + } catch (e: NoSuchElementException) { + sdkCore.internalLogger.log( + InternalLogger.Level.ERROR, + InternalLogger.Target.TELEMETRY, + { "Error parsing source type from NDK crash event: $sourceType" }, + e + ) + ErrorEvent.SourceType.NDK + } + } else { + ErrorEvent.SourceType.NDK + } + } + + private val DatadogContext.rumSessionId: String? + get() = featuresContext[Feature.RUM_FEATURE_NAME] + .orEmpty()[RumContext.SESSION_ID] as? String + // endregion companion object { @@ -209,6 +326,8 @@ internal class DatadogNdkCrashEventHandler( "RUM feature received a NDK crash event" + " where one or more mandatory (timestamp, signalName, stacktrace," + " message, lastViewEvent) fields are either missing or have wrong type." + internal const val MISSING_ANR_TRACE = "Last known exit reason has no trace information" + + " attached, cannot report fatal ANR." internal val VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD = TimeUnit.HOURS.toMillis(4) } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/DefaultAppStartTimeProvider.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/DefaultAppStartTimeProvider.kt index af4b31acd5..f887916407 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/DefaultAppStartTimeProvider.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/DefaultAppStartTimeProvider.kt @@ -11,17 +11,16 @@ import android.os.Build import android.os.Process import android.os.SystemClock import com.datadog.android.core.internal.system.BuildSdkVersionProvider -import com.datadog.android.core.internal.system.DefaultBuildSdkVersionProvider import java.util.concurrent.TimeUnit internal class DefaultAppStartTimeProvider( - buildSdkVersionProvider: BuildSdkVersionProvider = DefaultBuildSdkVersionProvider() + buildSdkVersionProvider: BuildSdkVersionProvider = BuildSdkVersionProvider.DEFAULT ) : AppStartTimeProvider { override val appStartTimeNs: Long by lazy(LazyThreadSafetyMode.PUBLICATION) { @SuppressLint("NewApi") when { - buildSdkVersionProvider.version() >= Build.VERSION_CODES.N -> { + buildSdkVersionProvider.version >= Build.VERSION_CODES.N -> { val diffMs = SystemClock.elapsedRealtime() - Process.getStartElapsedRealtime() System.nanoTime() - TimeUnit.MILLISECONDS.toNanos(diffMs) } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/LateCrashReporter.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/LateCrashReporter.kt new file mode 100644 index 0000000000..243dc74eba --- /dev/null +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/LateCrashReporter.kt @@ -0,0 +1,25 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +package com.datadog.android.rum.internal + +import android.app.ApplicationExitInfo +import android.os.Build +import androidx.annotation.RequiresApi +import com.datadog.android.api.storage.DataWriter +import com.google.gson.JsonObject + +internal interface LateCrashReporter { + + fun handleNdkCrashEvent(event: Map<*, *>, rumWriter: DataWriter) + + @RequiresApi(Build.VERSION_CODES.R) + fun handleAnrCrash( + anrExitInfo: ApplicationExitInfo, + lastRumViewEventJson: JsonObject, + rumWriter: DataWriter + ) +} diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt index f90f9daf03..9ff55c2df2 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt @@ -6,12 +6,15 @@ package com.datadog.android.rum.internal +import android.app.ActivityManager import android.app.Application +import android.app.ApplicationExitInfo import android.content.Context import android.os.Build import android.os.Handler import android.os.Looper import androidx.annotation.AnyThread +import androidx.annotation.RequiresApi import com.datadog.android.api.InternalLogger import com.datadog.android.api.feature.Feature import com.datadog.android.api.feature.FeatureEventReceiver @@ -25,6 +28,7 @@ import com.datadog.android.core.feature.event.JvmCrash import com.datadog.android.core.internal.thread.LoggingScheduledThreadPoolExecutor import com.datadog.android.core.internal.utils.executeSafe import com.datadog.android.core.internal.utils.scheduleSafe +import com.datadog.android.core.internal.utils.submitSafe import com.datadog.android.event.EventMapper import com.datadog.android.event.MapperSerializer import com.datadog.android.event.NoOpEventMapper @@ -46,8 +50,6 @@ import com.datadog.android.rum.internal.instrumentation.UserActionTrackingStrate import com.datadog.android.rum.internal.instrumentation.gestures.DatadogGesturesTracker import com.datadog.android.rum.internal.monitor.AdvancedRumMonitor import com.datadog.android.rum.internal.monitor.DatadogRumMonitor -import com.datadog.android.rum.internal.ndk.DatadogNdkCrashEventHandler -import com.datadog.android.rum.internal.ndk.NdkCrashEventHandler import com.datadog.android.rum.internal.net.RumRequestFactory import com.datadog.android.rum.internal.storage.NoOpDataWriter import com.datadog.android.rum.internal.thread.NoOpScheduledExecutorService @@ -79,6 +81,7 @@ import com.datadog.android.rum.tracking.ViewTrackingStrategy import com.datadog.android.telemetry.internal.Telemetry import com.datadog.android.telemetry.internal.TelemetryCoreConfiguration import com.datadog.android.telemetry.model.TelemetryConfigurationEvent +import java.lang.RuntimeException import java.util.Locale import java.util.concurrent.ExecutorService import java.util.concurrent.Executors @@ -91,12 +94,12 @@ import java.util.concurrent.atomic.AtomicReference * RUM feature class, which needs to be registered with Datadog SDK instance. */ @Suppress("TooManyFunctions") -internal class RumFeature constructor( +internal class RumFeature( private val sdkCore: FeatureSdkCore, internal val applicationId: String, internal val configuration: Configuration, - private val ndkCrashEventHandlerFactory: (InternalLogger) -> NdkCrashEventHandler = { - DatadogNdkCrashEventHandler(it) + private val lateCrashReporterFactory: (InternalSdkCore) -> LateCrashReporter = { + DatadogLateCrashReporter(it) } ) : StorageBackedFeature, FeatureEventReceiver { @@ -130,7 +133,7 @@ internal class RumFeature constructor( internal lateinit var appContext: Context internal lateinit var telemetry: Telemetry - private val ndkCrashEventHandler by lazy { ndkCrashEventHandlerFactory(sdkCore.internalLogger) } + private val lateCrashEventHandler by lazy { lateCrashReporterFactory(sdkCore as InternalSdkCore) } // region Feature @@ -263,7 +266,7 @@ internal class RumFeature constructor( when (event["type"]) { NDK_CRASH_BUS_MESSAGE_TYPE -> - ndkCrashEventHandler.handleEvent(event, sdkCore, dataWriter) + lateCrashEventHandler.handleNdkCrashEvent(event, dataWriter) LOGGER_ERROR_BUS_MESSAGE_TYPE -> addLoggerError(event) LOGGER_ERROR_WITH_STACK_TRACE_MESSAGE_TYPE -> addLoggerErrorWithStacktrace(event) WEB_VIEW_INGESTED_NOTIFICATION_MESSAGE_TYPE -> { @@ -327,6 +330,43 @@ internal class RumFeature constructor( } } + @RequiresApi(Build.VERSION_CODES.R) + internal fun consumeLastFatalAnr(rumEventsExecutorService: ExecutorService) { + val activityManager = + appContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + val lastKnownAnr = try { + activityManager.getHistoricalProcessExitReasons(null, 0, 0) + // from docs: Returns: a list of ApplicationExitInfo records matching the criteria, + // sorted in the order from most recent to least recent. + .firstOrNull { it.reason == ApplicationExitInfo.REASON_ANR } + } catch (@Suppress("TooGenericExceptionCaught") e: RuntimeException) { + sdkCore.internalLogger.log( + InternalLogger.Level.ERROR, + InternalLogger.Target.MAINTAINER, + { FAILED_TO_GET_HISTORICAL_EXIT_REASONS }, + e + ) + null + } ?: return + + rumEventsExecutorService.submitSafe("Send fatal ANR", sdkCore.internalLogger) { + val lastRumViewEvent = (sdkCore as InternalSdkCore).lastViewEvent + if (lastRumViewEvent != null) { + lateCrashEventHandler.handleAnrCrash( + lastKnownAnr, + lastRumViewEvent, + dataWriter + ) + } else { + sdkCore.internalLogger.log( + InternalLogger.Level.INFO, + InternalLogger.Target.USER, + { NO_LAST_RUM_VIEW_EVENT_AVAILABLE } + ) + } + } + } + private fun registerTrackingStrategies(appContext: Context) { actionTrackingStrategy.register(sdkCore, appContext) viewTrackingStrategy.register(sdkCore, appContext) @@ -605,10 +645,10 @@ internal class RumFeature constructor( "RUM feature receive an event of unsupported type=%s." internal const val UNKNOWN_EVENT_TYPE_PROPERTY_VALUE = "RUM feature received an event with unknown value of \"type\" property=%s." - internal const val JVM_CRASH_EVENT_MISSING_MANDATORY_FIELDS = - "RUM feature received a JVM crash event" + - " where one or more mandatory (throwable, message) fields" + - " are either missing or have a wrong type." + internal const val FAILED_TO_GET_HISTORICAL_EXIT_REASONS = + "Couldn't get historical exit reasons" + internal const val NO_LAST_RUM_VIEW_EVENT_AVAILABLE = + "No last known RUM view event found, skipping fatal ANR reporting." internal const val LOG_ERROR_EVENT_MISSING_MANDATORY_FIELDS = "RUM feature received a log event" + " where mandatory message field is either missing or has a wrong type." diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/anr/AndroidTraceParser.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/anr/AndroidTraceParser.kt new file mode 100644 index 0000000000..dba025d225 --- /dev/null +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/anr/AndroidTraceParser.kt @@ -0,0 +1,124 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +package com.datadog.android.rum.internal.anr + +import com.datadog.android.api.InternalLogger +import com.datadog.android.core.feature.event.ThreadDump +import java.io.IOException +import java.io.InputStream +import java.util.Locale + +/** + * Thread dump: https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/thread_list.cc;l=255;drc=d00d24530a29b684bec9a895c1da491a6390395f + */ +internal class AndroidTraceParser( + private val internalLogger: InternalLogger +) { + + internal fun parse(traceInputStream: InputStream): List { + @Suppress("UnsafeThirdPartyFunctionCall") // not 3rd party + val trace = traceInputStream.safeReadText() + + if (trace.isBlank()) return emptyList() + + return parse(trace) + } + + @Suppress("CyclomaticComplexMethod") + private fun parse(trace: String): List { + val threadDumps = mutableListOf() + + var isInThreadStackBlock = false + val currentThreadStack = mutableListOf() + var currentThreadName: String? = null + var currentThreadState: String? = null + + @Suppress("LoopWithTooManyJumpStatements") + for (line in trace.lines()) { + // we are leaving thread information block + if (line.isBlank() && isInThreadStackBlock) { + if (currentThreadStack.isNotEmpty() && currentThreadName != null) { + threadDumps += ThreadDump( + name = currentThreadName, + state = convertThreadState(currentThreadState.orEmpty()), + stack = currentThreadStack.joinToString("\n"), + crashed = currentThreadName == "main" + ) + } + currentThreadStack.clear() + isInThreadStackBlock = false + continue + } + // we are entering thread information block + if (line.contains(" prio=") && line.contains(" tid=")) { + isInThreadStackBlock = true + val threadState = line.split(" ") + .lastOrNull() + val threadName = THREAD_NAME_REGEX.matchEntire(line) + ?.groupValues + ?.elementAtOrNull(1) + currentThreadName = threadName + currentThreadState = threadState + continue + } + if (isInThreadStackBlock && line.trimStart() + .let { it.startsWith("at ") || it.startsWith("native: ") } + ) { + // it can be also lines in the stack like: + // - waiting on <0x0dd89f49> (a okhttp3.internal.concurrent.TaskRunner) + // - locked <0x0dd89f49> (a okhttp3.internal.concurrent.TaskRunner) + // we want to skip them for now + // also we want to skip any non-stack lines in the thread info block + currentThreadStack += line + } + } + + if (threadDumps.isEmpty()) { + internalLogger.log( + InternalLogger.Level.ERROR, + targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), + { PARSING_FAILURE_MESSAGE } + ) + } + + return threadDumps + } + + private fun convertThreadState(threadState: String): String { + // https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/thread_state.h;l=30;drc=37cec725ba134174eadf63b0eb06b964ffc202fd + // some values are similar to Java's Thread.State, some are not. For the similar ones we + // need to have a conversion in order to reduce cardinality + val convertedState = when (threadState) { + "TimedWaiting" -> "Timed_Waiting" + else -> threadState + } + return convertedState.lowercase(Locale.US) + } + + private fun InputStream.safeReadText(): String { + return try { + use { + it.reader().readText() + } + } catch (e: IOException) { + internalLogger.log( + InternalLogger.Level.ERROR, + InternalLogger.Target.USER, + { TRACE_STREAM_READ_FAILURE }, + e + ) + "" + } + } + + companion object { + const val TRACE_STREAM_READ_FAILURE = "Failed to read crash trace stream." + const val PARSING_FAILURE_MESSAGE = + "Parsing tracing information for the exit reason wasn't successful, no thread dumps were parsed." + val THREAD_NAME_REGEX = Regex("^\"(.+)\".+\$") + } +} diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt index a7c7aadba7..b71c4e47cc 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt @@ -72,7 +72,7 @@ internal class DatadogRumMonitor( frameRateVitalMonitor: VitalMonitor, sessionListener: RumSessionListener, private val appStartTimeProvider: AppStartTimeProvider = DefaultAppStartTimeProvider(), - private val executorService: ExecutorService = Executors.newSingleThreadExecutor() + internal val executorService: ExecutorService = Executors.newSingleThreadExecutor() ) : RumMonitor, AdvancedRumMonitor { internal var rootScope: RumScope = RumApplicationScope( diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/ndk/NdkCrashEventHandler.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/ndk/NdkCrashEventHandler.kt deleted file mode 100644 index e0a0c1b1d2..0000000000 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/ndk/NdkCrashEventHandler.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2016-Present Datadog, Inc. - */ - -package com.datadog.android.rum.internal.ndk - -import com.datadog.android.api.feature.FeatureSdkCore -import com.datadog.android.api.storage.DataWriter - -internal interface NdkCrashEventHandler { - fun handleEvent(event: Map<*, *>, sdkCore: FeatureSdkCore, rumWriter: DataWriter) -} diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/tracking/OreoFragmentLifecycleCallbacks.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/tracking/OreoFragmentLifecycleCallbacks.kt index 15003cc256..c6107e26e8 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/tracking/OreoFragmentLifecycleCallbacks.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/tracking/OreoFragmentLifecycleCallbacks.kt @@ -13,7 +13,6 @@ import com.datadog.android.api.InternalLogger import com.datadog.android.api.SdkCore import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.core.internal.system.BuildSdkVersionProvider -import com.datadog.android.core.internal.system.DefaultBuildSdkVersionProvider import com.datadog.android.core.internal.thread.LoggingScheduledThreadPoolExecutor import com.datadog.android.core.internal.utils.scheduleSafe import com.datadog.android.rum.RumMonitor @@ -31,7 +30,7 @@ internal class OreoFragmentLifecycleCallbacks( private val componentPredicate: ComponentPredicate, private val rumFeature: RumFeature, private val rumMonitor: RumMonitor, - private val buildSdkVersionProvider: BuildSdkVersionProvider = DefaultBuildSdkVersionProvider() + private val buildSdkVersionProvider: BuildSdkVersionProvider = BuildSdkVersionProvider.DEFAULT ) : FragmentLifecycleCallbacks, FragmentManager.FragmentLifecycleCallbacks() { private lateinit var sdkCore: FeatureSdkCore @@ -50,13 +49,13 @@ internal class OreoFragmentLifecycleCallbacks( override fun register(activity: Activity, sdkCore: SdkCore) { this.sdkCore = sdkCore as FeatureSdkCore - if (buildSdkVersionProvider.version() >= Build.VERSION_CODES.O) { + if (buildSdkVersionProvider.version >= Build.VERSION_CODES.O) { activity.fragmentManager.registerFragmentLifecycleCallbacks(this, true) } } override fun unregister(activity: Activity) { - if (buildSdkVersionProvider.version() >= Build.VERSION_CODES.O) { + if (buildSdkVersionProvider.version >= Build.VERSION_CODES.O) { activity.fragmentManager.unregisterFragmentLifecycleCallbacks(this) } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/vitals/JankStatsActivityLifecycleListener.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/vitals/JankStatsActivityLifecycleListener.kt index adef38e782..c3c87ae481 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/vitals/JankStatsActivityLifecycleListener.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/vitals/JankStatsActivityLifecycleListener.kt @@ -24,7 +24,6 @@ import androidx.metrics.performance.FrameData import androidx.metrics.performance.JankStats import com.datadog.android.api.InternalLogger import com.datadog.android.core.internal.system.BuildSdkVersionProvider -import com.datadog.android.core.internal.system.DefaultBuildSdkVersionProvider import java.lang.ref.WeakReference import java.util.WeakHashMap import java.util.concurrent.TimeUnit @@ -37,8 +36,7 @@ internal class JankStatsActivityLifecycleListener( private val internalLogger: InternalLogger, private val jankStatsProvider: JankStatsProvider = JankStatsProvider.DEFAULT, private var screenRefreshRate: Double = 60.0, - private var buildSdkVersionProvider: BuildSdkVersionProvider = DefaultBuildSdkVersionProvider() - + private var buildSdkVersionProvider: BuildSdkVersionProvider = BuildSdkVersionProvider.DEFAULT ) : ActivityLifecycleCallbacks, JankStats.OnFrameListener { internal val activeWindowsListener = WeakHashMap() @@ -132,7 +130,7 @@ internal class JankStatsActivityLifecycleListener( if (activeActivities[activity.window].isNullOrEmpty()) { activeWindowsListener.remove(activity.window) activeActivities.remove(activity.window) - if (buildSdkVersionProvider.version() >= Build.VERSION_CODES.S) { + if (buildSdkVersionProvider.version >= Build.VERSION_CODES.S) { unregisterMetricListener(activity.window) } } @@ -147,9 +145,9 @@ internal class JankStatsActivityLifecycleListener( if (durationNs > 0.0) { var frameRate = (ONE_SECOND_NS / durationNs) - if (buildSdkVersionProvider.version() >= Build.VERSION_CODES.S) { + if (buildSdkVersionProvider.version >= Build.VERSION_CODES.S) { screenRefreshRate = ONE_SECOND_NS / frameDeadline - } else if (buildSdkVersionProvider.version() == Build.VERSION_CODES.R) { + } else if (buildSdkVersionProvider.version == Build.VERSION_CODES.R) { screenRefreshRate = display?.refreshRate?.toDouble() ?: SIXTY_FPS } @@ -205,9 +203,9 @@ internal class JankStatsActivityLifecycleListener( @SuppressLint("NewApi") @MainThread private fun trackWindowMetrics(isKnownWindow: Boolean, window: Window, activity: Activity) { - if (buildSdkVersionProvider.version() >= Build.VERSION_CODES.S && !isKnownWindow) { + if (buildSdkVersionProvider.version >= Build.VERSION_CODES.S && !isKnownWindow) { registerMetricListener(window) - } else if (display == null && buildSdkVersionProvider.version() == Build.VERSION_CODES.R) { + } else if (display == null && buildSdkVersionProvider.version == Build.VERSION_CODES.R) { // Fallback - Android 30 allows apps to not run at a fixed 60hz, but didn't yet have // Frame Metrics callbacks available val displayManager = activity.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/tracking/FragmentViewTrackingStrategy.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/tracking/FragmentViewTrackingStrategy.kt index 0c6b156f49..303aeecbc2 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/tracking/FragmentViewTrackingStrategy.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/tracking/FragmentViewTrackingStrategy.kt @@ -6,12 +6,14 @@ package com.datadog.android.rum.tracking +import android.annotation.SuppressLint import android.app.Activity import android.os.Build import androidx.annotation.MainThread import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import com.datadog.android.api.feature.Feature +import com.datadog.android.core.internal.system.BuildSdkVersionProvider import com.datadog.android.rum.GlobalRumMonitor import com.datadog.android.rum.internal.RumFeature import com.datadog.android.rum.internal.tracking.AndroidXFragmentLifecycleCallbacks @@ -26,25 +28,42 @@ import com.datadog.android.rum.internal.tracking.OreoFragmentLifecycleCallbacks * * **Note**: This version of the [FragmentViewTrackingStrategy] is compatible with * the AndroidX Compat Library. - * @param trackArguments whether we track Fragment arguments - * @param supportFragmentComponentPredicate to accept the Androidx Fragments - * that will be taken into account as valid RUM View events. - * @param defaultFragmentComponentPredicate to accept the default Android Fragments - * that will be taken into account as valid RUM View events. */ @Suppress("DEPRECATION") +@SuppressLint("NewApi") class FragmentViewTrackingStrategy -@JvmOverloads -constructor( +internal constructor( internal val trackArguments: Boolean, - internal val supportFragmentComponentPredicate: ComponentPredicate = - AcceptAllSupportFragments(), - internal val defaultFragmentComponentPredicate: ComponentPredicate = - AcceptAllDefaultFragment() + internal val supportFragmentComponentPredicate: ComponentPredicate, + internal val defaultFragmentComponentPredicate: ComponentPredicate, + internal val buildSdkVersionProvider: BuildSdkVersionProvider ) : ActivityLifecycleTrackingStrategy(), ViewTrackingStrategy { + /** + * Creates instance of [FragmentViewTrackingStrategy]. + * + * @param trackArguments whether we track Fragment arguments + * @param supportFragmentComponentPredicate to accept the Androidx Fragments + * that will be taken into account as valid RUM View events. + * @param defaultFragmentComponentPredicate to accept the default Android Fragments + * that will be taken into account as valid RUM View events. + */ + @JvmOverloads + constructor( + trackArguments: Boolean, + supportFragmentComponentPredicate: ComponentPredicate = + AcceptAllSupportFragments(), + defaultFragmentComponentPredicate: ComponentPredicate = + AcceptAllDefaultFragment() + ) : this( + trackArguments, + supportFragmentComponentPredicate, + defaultFragmentComponentPredicate, + BuildSdkVersionProvider.DEFAULT + ) + private val androidXLifecycleCallbacks: FragmentLifecycleCallbacks by lazy { val rumFeature = withSdkCore { @@ -64,6 +83,7 @@ constructor( NoOpFragmentLifecycleCallbacks() } } + private val oreoLifecycleCallbacks: FragmentLifecycleCallbacks by lazy { val rumFeature = withSdkCore { @@ -71,7 +91,7 @@ constructor( } val rumMonitor = withSdkCore { GlobalRumMonitor.get(it) } if ( - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && + buildSdkVersionProvider.version >= Build.VERSION_CODES.O && rumFeature != null && rumMonitor != null ) { OreoFragmentLifecycleCallbacks( @@ -80,7 +100,8 @@ constructor( }, componentPredicate = defaultFragmentComponentPredicate, rumMonitor = rumMonitor, - rumFeature = rumFeature + rumFeature = rumFeature, + buildSdkVersionProvider = buildSdkVersionProvider ) } else { NoOpFragmentLifecycleCallbacks() diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/ndk/DatadogNdkCrashEventHandlerTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/DatadogLateCrashReporterTest.kt similarity index 50% rename from features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/ndk/DatadogNdkCrashEventHandlerTest.kt rename to features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/DatadogLateCrashReporterTest.kt index e20ec4e0a0..64e595256f 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/ndk/DatadogNdkCrashEventHandlerTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/DatadogLateCrashReporterTest.kt @@ -4,20 +4,26 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.rum.internal.ndk +package com.datadog.android.rum.internal +import android.app.ApplicationExitInfo import com.datadog.android.api.InternalLogger import com.datadog.android.api.context.DatadogContext import com.datadog.android.api.context.UserInfo import com.datadog.android.api.feature.Feature import com.datadog.android.api.feature.FeatureScope -import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.api.storage.DataWriter import com.datadog.android.api.storage.EventBatchWriter +import com.datadog.android.core.InternalSdkCore +import com.datadog.android.core.feature.event.ThreadDump import com.datadog.android.core.internal.persistence.Deserializer import com.datadog.android.rum.RumErrorSource import com.datadog.android.rum.assertj.ErrorEventAssert import com.datadog.android.rum.assertj.ViewEventAssert +import com.datadog.android.rum.internal.anr.ANRDetectorRunnable +import com.datadog.android.rum.internal.anr.ANRException +import com.datadog.android.rum.internal.anr.AndroidTraceParser +import com.datadog.android.rum.internal.domain.RumContext import com.datadog.android.rum.internal.domain.scope.toErrorSchemaType import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.ViewEvent @@ -37,6 +43,7 @@ import org.junit.jupiter.api.extension.Extensions import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.EnumSource import org.mockito.Mock +import org.mockito.Mockito.mock import org.mockito.junit.jupiter.MockitoExtension import org.mockito.junit.jupiter.MockitoSettings import org.mockito.kotlin.any @@ -56,12 +63,12 @@ import org.mockito.quality.Strictness ) @MockitoSettings(strictness = Strictness.LENIENT) @ForgeConfiguration(Configurator::class) -internal class DatadogNdkCrashEventHandlerTest { +internal class DatadogLateCrashReporterTest { - private lateinit var testedHandler: NdkCrashEventHandler + private lateinit var testedHandler: LateCrashReporter @Mock - lateinit var mockSdkCore: FeatureSdkCore + lateinit var mockSdkCore: InternalSdkCore @Mock lateinit var mockRumFeatureScope: FeatureScope @@ -75,6 +82,9 @@ internal class DatadogNdkCrashEventHandlerTest { @Mock lateinit var mockEventBatchWriter: EventBatchWriter + @Mock + lateinit var mockAndroidTraceParser: AndroidTraceParser + @Mock lateinit var mockInternalLogger: InternalLogger @@ -83,20 +93,25 @@ internal class DatadogNdkCrashEventHandlerTest { @BeforeEach fun `set up`() { + whenever(mockSdkCore.internalLogger) doReturn mockInternalLogger whenever(mockSdkCore.getFeature(Feature.RUM_FEATURE_NAME)) doReturn mockRumFeatureScope + whenever(mockRumFeatureScope.withWriteContext(any(), any())) doAnswer { val callback = it.getArgument<(DatadogContext, EventBatchWriter) -> Unit>(1) callback.invoke(fakeDatadogContext, mockEventBatchWriter) } - testedHandler = DatadogNdkCrashEventHandler( + testedHandler = DatadogLateCrashReporter( + sdkCore = mockSdkCore, rumEventDeserializer = mockRumEventDeserializer, - internalLogger = mockInternalLogger + androidTraceParser = mockAndroidTraceParser ) } + // region handleNdkCrashEvent + @Test - fun `𝕄 send RUM view+error 𝕎 handleEvent()`( + fun `𝕄 send RUM view+error 𝕎 handleNdkCrashEvent()`( @StringForgery crashMessage: String, @LongForgery(min = 1) fakeTimestamp: Long, @StringForgery fakeSignalName: String, @@ -117,7 +132,7 @@ internal class DatadogNdkCrashEventHandlerTest { val fakeViewEvent = viewEvent.copy( date = System.currentTimeMillis() - forge.aLong( min = 0L, - max = DatadogNdkCrashEventHandler.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 ), usr = ViewEvent.Usr( id = fakeUserInfo.id, @@ -140,7 +155,7 @@ internal class DatadogNdkCrashEventHandlerTest { ) // When - testedHandler.handleEvent(fakeEvent, mockSdkCore, mockRumWriter) + testedHandler.handleNdkCrashEvent(fakeEvent, mockRumWriter) // Then argumentCaptor { @@ -191,7 +206,7 @@ internal class DatadogNdkCrashEventHandlerTest { } @Test - fun `𝕄 send RUM view+error 𝕎 handleEvent() {source_type set}`( + fun `𝕄 send RUM view+error 𝕎 handleNdkCrashEvent() {source_type set}`( @StringForgery crashMessage: String, @LongForgery(min = 1) fakeTimestamp: Long, @StringForgery fakeSignalName: String, @@ -212,7 +227,7 @@ internal class DatadogNdkCrashEventHandlerTest { val fakeViewEvent = viewEvent.copy( date = System.currentTimeMillis() - forge.aLong( min = 0L, - max = DatadogNdkCrashEventHandler.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 ), usr = ViewEvent.Usr( id = fakeUserInfo.id, @@ -236,7 +251,7 @@ internal class DatadogNdkCrashEventHandlerTest { ) // When - testedHandler.handleEvent(fakeEvent, mockSdkCore, mockRumWriter) + testedHandler.handleNdkCrashEvent(fakeEvent, mockRumWriter) // Then argumentCaptor { @@ -287,7 +302,7 @@ internal class DatadogNdkCrashEventHandlerTest { } @Test - fun `𝕄 send RUM view+error 𝕎 handleEvent() {invalid source_type set}`( + fun `𝕄 send RUM view+error 𝕎 handleNdkCrashEvent() {invalid source_type set}`( @StringForgery crashMessage: String, @LongForgery(min = 1) fakeTimestamp: Long, @StringForgery fakeSignalName: String, @@ -308,7 +323,7 @@ internal class DatadogNdkCrashEventHandlerTest { val fakeViewEvent = viewEvent.copy( date = System.currentTimeMillis() - forge.aLong( min = 0L, - max = DatadogNdkCrashEventHandler.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 ), usr = ViewEvent.Usr( id = fakeUserInfo.id, @@ -332,7 +347,7 @@ internal class DatadogNdkCrashEventHandlerTest { ) // When - testedHandler.handleEvent(fakeEvent, mockSdkCore, mockRumWriter) + testedHandler.handleNdkCrashEvent(fakeEvent, mockRumWriter) // Then argumentCaptor { @@ -344,7 +359,7 @@ internal class DatadogNdkCrashEventHandlerTest { } @Test - fun `𝕄 send RUM view+error 𝕎 handleEvent() {view without usr}`( + fun `𝕄 send RUM view+error 𝕎 handleNdkCrashEvent() {view without usr}`( @StringForgery crashMessage: String, @LongForgery(min = 1) fakeTimestamp: Long, @StringForgery fakeSignalName: String, @@ -364,7 +379,7 @@ internal class DatadogNdkCrashEventHandlerTest { val fakeViewEvent = viewEvent.copy( date = System.currentTimeMillis() - forge.aLong( min = 0L, - max = DatadogNdkCrashEventHandler.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 ), usr = null ) @@ -381,7 +396,7 @@ internal class DatadogNdkCrashEventHandlerTest { .doReturn(fakeViewEvent) // When - testedHandler.handleEvent(fakeEvent, mockSdkCore, mockRumWriter) + testedHandler.handleNdkCrashEvent(fakeEvent, mockRumWriter) // Then argumentCaptor { @@ -425,7 +440,7 @@ internal class DatadogNdkCrashEventHandlerTest { } @Test - fun `𝕄 send only RUM error 𝕎 handleEvent() {view is too old}`( + fun `𝕄 send only RUM error 𝕎 handleNdkCrashEvent() {view is too old}`( @StringForgery crashMessage: String, @LongForgery(min = 1) fakeTimestamp: Long, @StringForgery fakeSignalName: String, @@ -444,7 +459,7 @@ internal class DatadogNdkCrashEventHandlerTest { ) val fakeViewEvent = viewEvent.copy( date = System.currentTimeMillis() - forge.aLong( - min = DatadogNdkCrashEventHandler.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD + 1 + min = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD + 1 ), usr = ViewEvent.Usr( id = fakeUserInfo.id, @@ -472,7 +487,7 @@ internal class DatadogNdkCrashEventHandlerTest { ) // When - testedHandler.handleEvent(fakeEvent, mockSdkCore, mockRumWriter) + testedHandler.handleNdkCrashEvent(fakeEvent, mockRumWriter) // Then argumentCaptor { @@ -519,7 +534,7 @@ internal class DatadogNdkCrashEventHandlerTest { } @Test - fun `𝕄 not send RUM event 𝕎 handleEvent() { RUM feature is not registered }`( + fun `𝕄 not send RUM event 𝕎 handleNdkCrashEvent() { RUM feature is not registered }`( @StringForgery crashMessage: String, @LongForgery(min = 1) fakeTimestamp: Long, @StringForgery fakeSignalName: String, @@ -538,19 +553,19 @@ internal class DatadogNdkCrashEventHandlerTest { ) // When - testedHandler.handleEvent(fakeEvent, mockSdkCore, mockRumWriter) + testedHandler.handleNdkCrashEvent(fakeEvent, mockRumWriter) // Then verifyNoInteractions(mockRumWriter, mockEventBatchWriter) mockInternalLogger.verifyLog( InternalLogger.Level.INFO, InternalLogger.Target.USER, - DatadogNdkCrashEventHandler.INFO_RUM_FEATURE_NOT_REGISTERED + DatadogLateCrashReporter.INFO_RUM_FEATURE_NOT_REGISTERED ) } @Test - fun `𝕄 not send RUM event 𝕎 handleEvent() { corrupted event, view json deserialization fails }`( + fun `𝕄 not send RUM event 𝕎 handleNdkCrashEvent() { corrupted event, view json deserialization fails }`( @StringForgery crashMessage: String, @LongForgery(min = 1) fakeTimestamp: Long, @StringForgery fakeSignalName: String, @@ -568,20 +583,20 @@ internal class DatadogNdkCrashEventHandlerTest { whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn null // When - testedHandler.handleEvent(fakeEvent, mockSdkCore, mockRumWriter) + testedHandler.handleNdkCrashEvent(fakeEvent, mockRumWriter) // Then verifyNoInteractions(mockRumWriter, mockEventBatchWriter) mockInternalLogger.verifyLog( InternalLogger.Level.WARN, InternalLogger.Target.USER, - DatadogNdkCrashEventHandler.NDK_CRASH_EVENT_MISSING_MANDATORY_FIELDS + DatadogLateCrashReporter.NDK_CRASH_EVENT_MISSING_MANDATORY_FIELDS ) } @ParameterizedTest @EnumSource(ValueMissingType::class) - fun `𝕄 not send RUM event 𝕎 handleEvent() { corrupted event }`( + fun `𝕄 not send RUM event 𝕎 handleNdkCrashEvent() { corrupted event }`( missingType: ValueMissingType, @StringForgery crashMessage: String, @LongForgery(min = 1) fakeTimestamp: Long, @@ -607,15 +622,497 @@ internal class DatadogNdkCrashEventHandlerTest { } // When - testedHandler.handleEvent(fakeEvent, mockSdkCore, mockRumWriter) + testedHandler.handleNdkCrashEvent(fakeEvent, mockRumWriter) // Then verifyNoInteractions(mockRumWriter, mockEventBatchWriter) mockInternalLogger.verifyLog( InternalLogger.Level.WARN, InternalLogger.Target.USER, - DatadogNdkCrashEventHandler.NDK_CRASH_EVENT_MISSING_MANDATORY_FIELDS + DatadogLateCrashReporter.NDK_CRASH_EVENT_MISSING_MANDATORY_FIELDS + ) + } + + //endregion + + // region handleAnrCrash + + @Test + fun `𝕄 send RUM view+error 𝕎 handleAnrCrash()`( + @LongForgery(min = 1) fakeTimestamp: Long, + @Forgery viewEvent: ViewEvent, + @Forgery fakeUserInfo: UserInfo, + forge: Forge + ) { + // Given + val fakeServerOffset = + forge.aLong(min = -fakeTimestamp, max = Long.MAX_VALUE - fakeTimestamp) + fakeDatadogContext = fakeDatadogContext.copy( + time = fakeDatadogContext.time.copy( + serverTimeOffsetMs = fakeServerOffset + ) + ) + + val fakeViewEvent = viewEvent.copy( + date = System.currentTimeMillis() - forge.aLong( + min = 0L, + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + ), + usr = ViewEvent.Usr( + id = fakeUserInfo.id, + name = fakeUserInfo.name, + email = fakeUserInfo.email, + additionalProperties = fakeUserInfo.additionalProperties.toMutableMap() + ) + ) + val fakeViewEventJson = fakeViewEvent.toJson().asJsonObject + + whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn fakeViewEvent + + val fakeThreadsDump = forge.anrCrashThreadDump() + whenever(mockAndroidTraceParser.parse(any())) doReturn fakeThreadsDump + val mockAnrExitInfo = mock().apply { + whenever(traceInputStream) doReturn mock() + whenever(timestamp) doReturn fakeTimestamp + } + + // When + testedHandler.handleAnrCrash(mockAnrExitInfo, fakeViewEventJson, mockRumWriter) + + // Then + argumentCaptor { + verify(mockRumWriter, times(2)).write(eq(mockEventBatchWriter), capture()) + + ErrorEventAssert.assertThat(firstValue as ErrorEvent) + .hasApplicationId(fakeViewEvent.application.id) + .hasSessionId(fakeViewEvent.session.id) + .hasView( + fakeViewEvent.view.id, + fakeViewEvent.view.name, + fakeViewEvent.view.url + ) + .hasMessage(ANRDetectorRunnable.ANR_MESSAGE) + .hasStackTrace(fakeThreadsDump.first { it.name == "main" }.stack) + .isCrash(true) + .hasErrorSource(RumErrorSource.SOURCE) + .hasErrorSourceType(ErrorEvent.SourceType.ANDROID) + .hasTimestamp(fakeTimestamp + fakeServerOffset) + .hasUserInfo( + UserInfo( + fakeViewEvent.usr?.id, + fakeViewEvent.usr?.name, + fakeViewEvent.usr?.email, + fakeViewEvent.usr?.additionalProperties.orEmpty() + ) + ) + .hasErrorType(ANRException::class.java.canonicalName) + .hasLiteSessionPlan() + .hasDeviceInfo( + fakeDatadogContext.deviceInfo.deviceName, + fakeDatadogContext.deviceInfo.deviceModel, + fakeDatadogContext.deviceInfo.deviceBrand, + fakeDatadogContext.deviceInfo.deviceType.toErrorSchemaType(), + fakeDatadogContext.deviceInfo.architecture + ) + .hasOsInfo( + fakeDatadogContext.deviceInfo.osName, + fakeDatadogContext.deviceInfo.osVersion, + fakeDatadogContext.deviceInfo.osMajorVersion + ) + .hasThreads(fakeThreadsDump) + + ViewEventAssert.assertThat(secondValue as ViewEvent) + .hasVersion(fakeViewEvent.dd.documentVersion + 1) + .hasCrashCount((fakeViewEvent.view.crash?.count ?: 0) + 1) + .isActive(false) + } + + verify(mockSdkCore).writeLastFatalAnrSent(fakeTimestamp) + } + + @Test + fun `𝕄 send RUM view+error 𝕎 handleAnrCrash() { view without user }`( + @LongForgery(min = 1) fakeTimestamp: Long, + @Forgery viewEvent: ViewEvent, + forge: Forge + ) { + // Given + val fakeServerOffset = + forge.aLong(min = -fakeTimestamp, max = Long.MAX_VALUE - fakeTimestamp) + fakeDatadogContext = fakeDatadogContext.copy( + time = fakeDatadogContext.time.copy( + serverTimeOffsetMs = fakeServerOffset + ) + ) + + val fakeViewEvent = viewEvent.copy( + date = System.currentTimeMillis() - forge.aLong( + min = 0L, + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + ), + usr = null + ) + val fakeViewEventJson = fakeViewEvent.toJson().asJsonObject + + whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn fakeViewEvent + + val fakeThreadsDump = forge.anrCrashThreadDump() + whenever(mockAndroidTraceParser.parse(any())) doReturn fakeThreadsDump + val mockAnrExitInfo = mock().apply { + whenever(traceInputStream) doReturn mock() + whenever(timestamp) doReturn fakeTimestamp + } + + // When + testedHandler.handleAnrCrash(mockAnrExitInfo, fakeViewEventJson, mockRumWriter) + + // Then + argumentCaptor { + verify(mockRumWriter, times(2)).write(eq(mockEventBatchWriter), capture()) + + ErrorEventAssert.assertThat(firstValue as ErrorEvent) + .hasApplicationId(fakeViewEvent.application.id) + .hasSessionId(fakeViewEvent.session.id) + .hasView( + fakeViewEvent.view.id, + fakeViewEvent.view.name, + fakeViewEvent.view.url + ) + .hasMessage(ANRDetectorRunnable.ANR_MESSAGE) + .hasStackTrace(fakeThreadsDump.first { it.name == "main" }.stack) + .isCrash(true) + .hasErrorSource(RumErrorSource.SOURCE) + .hasErrorSourceType(ErrorEvent.SourceType.ANDROID) + .hasTimestamp(fakeTimestamp + fakeServerOffset) + .hasNoUserInfo() + .hasErrorType(ANRException::class.java.canonicalName) + .hasLiteSessionPlan() + .hasDeviceInfo( + fakeDatadogContext.deviceInfo.deviceName, + fakeDatadogContext.deviceInfo.deviceModel, + fakeDatadogContext.deviceInfo.deviceBrand, + fakeDatadogContext.deviceInfo.deviceType.toErrorSchemaType(), + fakeDatadogContext.deviceInfo.architecture + ) + .hasOsInfo( + fakeDatadogContext.deviceInfo.osName, + fakeDatadogContext.deviceInfo.osVersion, + fakeDatadogContext.deviceInfo.osMajorVersion + ) + .hasThreads(fakeThreadsDump) + + ViewEventAssert.assertThat(secondValue as ViewEvent) + .hasVersion(fakeViewEvent.dd.documentVersion + 1) + .hasCrashCount((fakeViewEvent.view.crash?.count ?: 0) + 1) + .isActive(false) + } + + verify(mockSdkCore).writeLastFatalAnrSent(fakeTimestamp) + } + + @Test + fun `𝕄 send only RUM error 𝕎 handleAnrCrash() { view is too old }`( + @LongForgery(min = 1) fakeTimestamp: Long, + @Forgery viewEvent: ViewEvent, + @Forgery fakeUserInfo: UserInfo, + forge: Forge + ) { + // Given + val fakeServerOffset = + forge.aLong(min = -fakeTimestamp, max = Long.MAX_VALUE - fakeTimestamp) + fakeDatadogContext = fakeDatadogContext.copy( + time = fakeDatadogContext.time.copy( + serverTimeOffsetMs = fakeServerOffset + ) + ) + + val fakeViewEvent = viewEvent.copy( + date = System.currentTimeMillis() - forge.aLong( + min = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD + 1 + ), + usr = ViewEvent.Usr( + id = fakeUserInfo.id, + name = fakeUserInfo.name, + email = fakeUserInfo.email, + additionalProperties = fakeUserInfo.additionalProperties.toMutableMap() + ) ) + val fakeViewEventJson = fakeViewEvent.toJson().asJsonObject + + whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn fakeViewEvent + + val fakeThreadsDump = forge.anrCrashThreadDump() + whenever(mockAndroidTraceParser.parse(any())) doReturn fakeThreadsDump + val mockAnrExitInfo = mock().apply { + whenever(traceInputStream) doReturn mock() + whenever(timestamp) doReturn fakeTimestamp + } + + // When + testedHandler.handleAnrCrash(mockAnrExitInfo, fakeViewEventJson, mockRumWriter) + + // Then + argumentCaptor { + verify(mockRumWriter, times(1)).write(eq(mockEventBatchWriter), capture()) + + ErrorEventAssert.assertThat(firstValue as ErrorEvent) + .hasApplicationId(fakeViewEvent.application.id) + .hasSessionId(fakeViewEvent.session.id) + .hasView( + fakeViewEvent.view.id, + fakeViewEvent.view.name, + fakeViewEvent.view.url + ) + .hasMessage(ANRDetectorRunnable.ANR_MESSAGE) + .hasStackTrace(fakeThreadsDump.first { it.name == "main" }.stack) + .isCrash(true) + .hasErrorSource(RumErrorSource.SOURCE) + .hasErrorSourceType(ErrorEvent.SourceType.ANDROID) + .hasTimestamp(fakeTimestamp + fakeServerOffset) + .hasUserInfo( + UserInfo( + fakeViewEvent.usr?.id, + fakeViewEvent.usr?.name, + fakeViewEvent.usr?.email, + fakeViewEvent.usr?.additionalProperties.orEmpty() + ) + ) + .hasErrorType(ANRException::class.java.canonicalName) + .hasLiteSessionPlan() + .hasDeviceInfo( + fakeDatadogContext.deviceInfo.deviceName, + fakeDatadogContext.deviceInfo.deviceModel, + fakeDatadogContext.deviceInfo.deviceBrand, + fakeDatadogContext.deviceInfo.deviceType.toErrorSchemaType(), + fakeDatadogContext.deviceInfo.architecture + ) + .hasOsInfo( + fakeDatadogContext.deviceInfo.osName, + fakeDatadogContext.deviceInfo.osVersion, + fakeDatadogContext.deviceInfo.osMajorVersion + ) + .hasThreads(fakeThreadsDump) + } + + verify(mockSdkCore).writeLastFatalAnrSent(fakeTimestamp) + } + + @Test + fun `𝕄 log warning and not send anything 𝕎 handleAnrCrash() { RUM feature not registered }`( + @LongForgery(min = 1) fakeTimestamp: Long, + @Forgery viewEvent: ViewEvent, + forge: Forge + ) { + // Given + val fakeServerOffset = + forge.aLong(min = -fakeTimestamp, max = Long.MAX_VALUE - fakeTimestamp) + fakeDatadogContext = fakeDatadogContext.copy( + time = fakeDatadogContext.time.copy( + serverTimeOffsetMs = fakeServerOffset + ) + ) + + val fakeViewEvent = viewEvent.copy( + date = System.currentTimeMillis() - forge.aLong( + min = 0L, + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + ) + ) + val fakeViewEventJson = fakeViewEvent.toJson().asJsonObject + + whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn fakeViewEvent + + val mockAnrExitInfo = mock().apply { + whenever(traceInputStream) doReturn mock() + whenever(timestamp) doReturn fakeTimestamp + } + + whenever(mockSdkCore.getFeature(Feature.RUM_FEATURE_NAME)) doReturn null + + // When + testedHandler.handleAnrCrash(mockAnrExitInfo, fakeViewEventJson, mockRumWriter) + + // Then + verifyNoInteractions(mockRumWriter) + mockInternalLogger.verifyLog( + InternalLogger.Level.WARN, + InternalLogger.Target.USER, + DatadogLateCrashReporter.INFO_RUM_FEATURE_NOT_REGISTERED + ) + } + + @Test + fun `𝕄 not send anything 𝕎 handleAnrCrash() { view deserialization fails }`( + @LongForgery(min = 1) fakeTimestamp: Long, + @Forgery viewEvent: ViewEvent + ) { + // Given + val fakeViewEventJson = viewEvent.toJson().asJsonObject + + whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn null + + val mockAnrExitInfo = mock().apply { + whenever(traceInputStream) doReturn mock() + whenever(timestamp) doReturn fakeTimestamp + } + + // When + testedHandler.handleAnrCrash(mockAnrExitInfo, fakeViewEventJson, mockRumWriter) + + // Then + verifyNoInteractions(mockRumWriter, mockAndroidTraceParser) + } + + @Test + fun `𝕄 not send anything 𝕎 handleAnrCrash() { Crash timestamp is before last RUM view }`( + @Forgery viewEvent: ViewEvent, + forge: Forge + ) { + // Given + val fakeViewEvent = viewEvent.copy( + date = System.currentTimeMillis() - forge.aLong( + min = 0L, + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + ) + ) + val fakeViewEventJson = fakeViewEvent.toJson().asJsonObject + + whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn fakeViewEvent + + val mockAnrExitInfo = mock().apply { + whenever(traceInputStream) doReturn mock() + whenever(timestamp) doReturn fakeViewEvent.date - 1 + } + + // When + testedHandler.handleAnrCrash(mockAnrExitInfo, fakeViewEventJson, mockRumWriter) + + // Then + verifyNoInteractions(mockRumWriter, mockInternalLogger) + } + + @Test + fun `𝕄 not send anything 𝕎 handleAnrCrash() { last view event belongs to the current session }`( + @LongForgery(min = 1) fakeTimestamp: Long, + @Forgery viewEvent: ViewEvent, + forge: Forge + ) { + // Given + val fakeServerOffset = + forge.aLong(min = -fakeTimestamp, max = Long.MAX_VALUE - fakeTimestamp) + fakeDatadogContext = fakeDatadogContext.copy( + time = fakeDatadogContext.time.copy( + serverTimeOffsetMs = fakeServerOffset + ), + featuresContext = mapOf( + Feature.RUM_FEATURE_NAME to mapOf(RumContext.SESSION_ID to viewEvent.session.id) + ) + ) + + val fakeViewEvent = viewEvent.copy( + date = System.currentTimeMillis() - forge.aLong( + min = 0L, + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + ) + ) + val fakeViewEventJson = fakeViewEvent.toJson().asJsonObject + + whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn fakeViewEvent + + val mockAnrExitInfo = mock().apply { + whenever(traceInputStream) doReturn mock() + whenever(timestamp) doReturn fakeTimestamp + } + + // When + testedHandler.handleAnrCrash(mockAnrExitInfo, fakeViewEventJson, mockRumWriter) + + // Then + verifyNoInteractions(mockRumWriter) + } + + @Test + fun `𝕄 not send anything 𝕎 handleAnrCrash() { ANR was already sent }`( + @LongForgery(min = 1) fakeTimestamp: Long, + @Forgery viewEvent: ViewEvent, + forge: Forge + ) { + // Given + val fakeServerOffset = + forge.aLong(min = -fakeTimestamp, max = Long.MAX_VALUE - fakeTimestamp) + fakeDatadogContext = fakeDatadogContext.copy( + time = fakeDatadogContext.time.copy( + serverTimeOffsetMs = fakeServerOffset + ) + ) + + val fakeViewEvent = viewEvent.copy( + date = System.currentTimeMillis() - forge.aLong( + min = 0L, + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + ) + ) + val fakeViewEventJson = fakeViewEvent.toJson().asJsonObject + + whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn fakeViewEvent + + val mockAnrExitInfo = mock().apply { + whenever(traceInputStream) doReturn mock() + whenever(timestamp) doReturn fakeTimestamp + } + whenever(mockSdkCore.lastFatalAnrSent) doReturn fakeTimestamp + + // When + testedHandler.handleAnrCrash(mockAnrExitInfo, fakeViewEventJson, mockRumWriter) + + // Then + verifyNoInteractions(mockRumWriter) + } + + @Test + fun `𝕄 not send anything 𝕎 handleAnrCrash() { empty threads dump }`( + @LongForgery(min = 1) fakeTimestamp: Long, + @Forgery viewEvent: ViewEvent, + forge: Forge + ) { + // Given + val fakeServerOffset = + forge.aLong(min = -fakeTimestamp, max = Long.MAX_VALUE - fakeTimestamp) + fakeDatadogContext = fakeDatadogContext.copy( + time = fakeDatadogContext.time.copy( + serverTimeOffsetMs = fakeServerOffset + ) + ) + + val fakeViewEvent = viewEvent.copy( + date = System.currentTimeMillis() - forge.aLong( + min = 0L, + max = DatadogLateCrashReporter.VIEW_EVENT_AVAILABILITY_TIME_THRESHOLD - 1000 + ) + ) + val fakeViewEventJson = fakeViewEvent.toJson().asJsonObject + + whenever(mockRumEventDeserializer.deserialize(fakeViewEventJson)) doReturn fakeViewEvent + + val mockAnrExitInfo = mock().apply { + whenever(traceInputStream) doReturn mock() + whenever(timestamp) doReturn fakeTimestamp + } + whenever(mockAndroidTraceParser.parse(any())) doReturn emptyList() + + // When + testedHandler.handleAnrCrash(mockAnrExitInfo, fakeViewEventJson, mockRumWriter) + + // Then + verifyNoInteractions(mockRumWriter) + } + + // endregion + + private fun Forge.anrCrashThreadDump(): List { + val otherThreads = aList { getForgery() }.map { it.copy(crashed = false) } + val mainThread = getForgery().copy(name = "main", crashed = true) + return shuffle(otherThreads + mainThread) } enum class ValueMissingType { diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/DefaultAppStartTimeProviderTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/DefaultAppStartTimeProviderTest.kt index 3e58e6cdf6..8273db488e 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/DefaultAppStartTimeProviderTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/DefaultAppStartTimeProviderTest.kt @@ -32,7 +32,7 @@ class DefaultAppStartTimeProviderTest { ) { // GIVEN val mockBuildSdkVersionProvider: BuildSdkVersionProvider = mock() - whenever(mockBuildSdkVersionProvider.version()) doReturn apiVersion + whenever(mockBuildSdkVersionProvider.version) doReturn apiVersion val diffMs = SystemClock.elapsedRealtime() - Process.getStartElapsedRealtime() val startTimeNs = System.nanoTime() - TimeUnit.MILLISECONDS.toNanos(diffMs) @@ -51,7 +51,7 @@ class DefaultAppStartTimeProviderTest { ) { // GIVEN val mockBuildSdkVersionProvider: BuildSdkVersionProvider = mock() - whenever(mockBuildSdkVersionProvider.version()) doReturn apiVersion + whenever(mockBuildSdkVersionProvider.version) doReturn apiVersion val startTimeNs = RumFeature.startupTimeNs // WHEN diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt index 0abe55a85a..f5ebe95bbd 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt @@ -6,7 +6,10 @@ package com.datadog.android.rum.internal +import android.app.ActivityManager import android.app.Application +import android.app.ApplicationExitInfo +import android.content.Context import android.os.Build import com.datadog.android.api.InternalLogger import com.datadog.android.core.InternalSdkCore @@ -22,7 +25,6 @@ import com.datadog.android.rum.configuration.VitalsUpdateFrequency import com.datadog.android.rum.internal.domain.RumDataWriter import com.datadog.android.rum.internal.domain.event.RumEventMapper import com.datadog.android.rum.internal.monitor.AdvancedRumMonitor -import com.datadog.android.rum.internal.ndk.NdkCrashEventHandler import com.datadog.android.rum.internal.storage.NoOpDataWriter import com.datadog.android.rum.internal.thread.NoOpScheduledExecutorService import com.datadog.android.rum.internal.tracking.NoOpUserActionTrackingStrategy @@ -48,6 +50,7 @@ import com.datadog.tools.unit.extensions.ApiLevelExtension import com.datadog.tools.unit.extensions.TestConfigurationExtension import com.datadog.tools.unit.extensions.config.TestConfiguration import com.datadog.tools.unit.forge.aThrowable +import com.datadog.tools.unit.forge.anException import com.datadog.tools.unit.forge.exhaustiveAttributes import com.datadog.tools.unit.getFieldValue import com.google.gson.JsonObject @@ -70,7 +73,10 @@ import org.junit.jupiter.params.provider.EnumSource import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.kotlin.any +import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn +import org.mockito.kotlin.doThrow import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions @@ -79,6 +85,7 @@ import org.mockito.kotlin.whenever import org.mockito.quality.Strictness import java.util.Locale import java.util.UUID +import java.util.concurrent.ExecutorService import java.util.concurrent.ScheduledThreadPoolExecutor @Extensions( @@ -109,7 +116,7 @@ internal class RumFeatureTest { lateinit var mockInternalLogger: InternalLogger @Mock - lateinit var mockNdkCrashEventHandler: NdkCrashEventHandler + lateinit var mockLateCrashReporter: LateCrashReporter @BeforeEach fun `set up`() { @@ -119,7 +126,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) GlobalRumMonitor.registerIfAbsent(mockRumMonitor, mockSdkCore) } @@ -197,7 +204,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -217,7 +224,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -244,7 +251,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -266,7 +273,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -290,7 +297,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -313,7 +320,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -342,7 +349,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -373,7 +380,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration.copy(viewTrackingStrategy = null), - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -392,7 +399,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -411,7 +418,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -429,7 +436,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -468,7 +475,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -498,7 +505,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -602,7 +609,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -623,7 +630,7 @@ internal class RumFeatureTest { mockSdkCore, fakeApplicationId.toString(), fakeConfiguration, - ndkCrashEventHandlerFactory = { mockNdkCrashEventHandler } + lateCrashReporterFactory = { mockLateCrashReporter } ) // When @@ -831,10 +838,9 @@ internal class RumFeatureTest { testedFeature.onReceive(event) // Then - verify(mockNdkCrashEventHandler) - .handleEvent( + verify(mockLateCrashReporter) + .handleNdkCrashEvent( event, - mockSdkCore, testedFeature.dataWriter ) @@ -844,6 +850,123 @@ internal class RumFeatureTest { ) } + @Test + fun `𝕄 consume last fatal ANR crash 𝕎 consumeLastFatalAnr()`( + @Forgery fakeViewEventJson: JsonObject, + forge: Forge + ) { + // Given + val appExitInfo = forge.anApplicationExitInfoList(mustInclude = ApplicationExitInfo.REASON_ANR) + + val mockActivityManager = mock() + whenever( + mockActivityManager.getHistoricalProcessExitReasons(null, 0, 0) + ) doReturn appExitInfo + whenever( + appContext.mockInstance.getSystemService(Context.ACTIVITY_SERVICE) + ) doReturn mockActivityManager + val mockExecutor = mockSameThreadExecutorService() + whenever(mockSdkCore.lastViewEvent) doReturn fakeViewEventJson + testedFeature.onInitialize(appContext.mockInstance) + + // When + testedFeature.consumeLastFatalAnr(mockExecutor) + + // Then + verify(mockLateCrashReporter) + .handleAnrCrash( + appExitInfo.first { it.reason == ApplicationExitInfo.REASON_ANR }, + fakeViewEventJson, + testedFeature.dataWriter + ) + } + + @Test + fun `𝕄 not consume last fatal ANR crash 𝕎 consumeLastFatalAnr() { no last view event }`( + forge: Forge + ) { + // Given + val appExitInfo = forge.anApplicationExitInfoList(mustInclude = ApplicationExitInfo.REASON_ANR) + + val mockActivityManager = mock() + whenever( + mockActivityManager.getHistoricalProcessExitReasons(null, 0, 0) + ) doReturn appExitInfo + whenever( + appContext.mockInstance.getSystemService(Context.ACTIVITY_SERVICE) + ) doReturn mockActivityManager + val mockExecutor = mockSameThreadExecutorService() + whenever(mockSdkCore.lastViewEvent) doReturn null + testedFeature.onInitialize(appContext.mockInstance) + + // When + testedFeature.consumeLastFatalAnr(mockExecutor) + + // Then + verifyNoInteractions(mockLateCrashReporter) + mockInternalLogger.verifyLog( + InternalLogger.Level.INFO, + InternalLogger.Target.USER, + RumFeature.NO_LAST_RUM_VIEW_EVENT_AVAILABLE + ) + } + + @Test + fun `𝕄 not consume last fatal ANR crash 𝕎 consumeLastFatalAnr() { no known ANR exit }`( + @Forgery fakeViewEventJson: JsonObject, + forge: Forge + ) { + // Given + val appExitInfo = forge.anApplicationExitInfoList() + .filter { it.reason != ApplicationExitInfo.REASON_ANR } + + val mockActivityManager = mock() + whenever( + mockActivityManager.getHistoricalProcessExitReasons(null, 0, 0) + ) doReturn appExitInfo + whenever( + appContext.mockInstance.getSystemService(Context.ACTIVITY_SERVICE) + ) doReturn mockActivityManager + val mockExecutor = mockSameThreadExecutorService() + whenever(mockSdkCore.lastViewEvent) doReturn fakeViewEventJson + testedFeature.onInitialize(appContext.mockInstance) + + // When + testedFeature.consumeLastFatalAnr(mockExecutor) + + // Then + verifyNoInteractions(mockLateCrashReporter, mockInternalLogger) + } + + @Test + fun `𝕄 log error 𝕎 consumeLastFatalAnr() { error getting historical exit reasons }`( + forge: Forge + ) { + // Given + val mockActivityManager = mock() + val exceptionThrown = forge.anException() + whenever( + mockActivityManager.getHistoricalProcessExitReasons(null, 0, 0) + ) doThrow exceptionThrown + whenever( + appContext.mockInstance.getSystemService(Context.ACTIVITY_SERVICE) + ) doReturn mockActivityManager + val mockExecutor = mockSameThreadExecutorService() + testedFeature.onInitialize(appContext.mockInstance) + + // When + testedFeature.consumeLastFatalAnr(mockExecutor) + + // Then + verifyNoInteractions(mockLateCrashReporter) + mockInternalLogger.verifyLog( + InternalLogger.Level.ERROR, + InternalLogger.Target.MAINTAINER, + RumFeature.FAILED_TO_GET_HISTORICAL_EXIT_REASONS, + exceptionThrown + ) + } + // region FeatureEventReceiver#onReceive + logger error @Test @@ -1241,6 +1364,54 @@ internal class RumFeatureTest { // endregion + private fun Forge.anApplicationExitInfoList( + mustInclude: Int? = null + ): List { + val appExitInfos = aList { + mock().apply { + whenever(reason) doReturn anApplicationExitInfoReason() + } + }.toMutableList() + if (mustInclude != null && !appExitInfos.any { it.reason == mustInclude }) { + appExitInfos[anElementFrom(appExitInfos.indices.toList())] = + mock().apply { + whenever(reason) doReturn mustInclude + } + } + return appExitInfos + } + + private fun Forge.anApplicationExitInfoReason(): Int { + return anElementFrom( + ApplicationExitInfo.REASON_UNKNOWN, + ApplicationExitInfo.REASON_EXIT_SELF, + ApplicationExitInfo.REASON_SIGNALED, + ApplicationExitInfo.REASON_LOW_MEMORY, + ApplicationExitInfo.REASON_CRASH, + ApplicationExitInfo.REASON_CRASH_NATIVE, + ApplicationExitInfo.REASON_ANR, + ApplicationExitInfo.REASON_INITIALIZATION_FAILURE, + ApplicationExitInfo.REASON_PERMISSION_CHANGE, + ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE, + ApplicationExitInfo.REASON_USER_REQUESTED, + ApplicationExitInfo.REASON_USER_STOPPED, + ApplicationExitInfo.REASON_DEPENDENCY_DIED, + ApplicationExitInfo.REASON_OTHER, + ApplicationExitInfo.REASON_FREEZER, + ApplicationExitInfo.REASON_PACKAGE_STATE_CHANGE, + ApplicationExitInfo.REASON_PACKAGE_UPDATED + ) + } + + private fun mockSameThreadExecutorService(): ExecutorService { + return mock().apply { + whenever(submit(any())) doAnswer { + it.getArgument(0).run() + mock() + } + } + } + companion object { val appContext = ApplicationContextTestConfiguration(Application::class.java) private val mainLooper = MainLooperTestConfiguration() diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/anr/AndroidTraceParserTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/anr/AndroidTraceParserTest.kt new file mode 100644 index 0000000000..ea7f2632e8 --- /dev/null +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/anr/AndroidTraceParserTest.kt @@ -0,0 +1,304 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +package com.datadog.android.rum.internal.anr + +import com.datadog.android.api.InternalLogger +import com.datadog.android.rum.utils.forge.Configurator +import com.datadog.android.rum.utils.verifyLog +import fr.xgouchet.elmyr.annotation.StringForgery +import fr.xgouchet.elmyr.junit5.ForgeConfiguration +import fr.xgouchet.elmyr.junit5.ForgeExtension +import org.assertj.core.api.Assertions.assertThat +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.Extensions +import org.mockito.Mock +import org.mockito.Mockito.mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.kotlin.doThrow +import org.mockito.kotlin.whenever +import org.mockito.quality.Strictness +import java.io.IOException +import java.io.InputStream + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class) +) +@MockitoSettings(strictness = Strictness.LENIENT) +@ForgeConfiguration(Configurator::class) +internal class AndroidTraceParserTest { + + @Mock + lateinit var mockInternalLogger: InternalLogger + + private lateinit var testedParser: AndroidTraceParser + + @BeforeEach + fun `set up`() { + testedParser = AndroidTraceParser(mockInternalLogger) + } + + @Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") + @Test + fun `𝕄 return threads dump 𝕎 parse()`() { + // Given + val traceStream = javaClass.classLoader.getResourceAsStream("anr_crash_trace.txt") + + // When + val threadsDump = testedParser.parse(traceStream) + + // Then + assertThat(threadsDump).isNotEmpty + assertThat(threadsDump.filter { it.crashed }).hasSize(1) + assertThat(threadsDump).allMatch { it.stack.isNotEmpty() } + + assertThat(threadsDump.filter { it.name == "main" }).hasSize(1) + val mainThread = threadsDump.first { it.name == "main" } + assertThat(mainThread.stack).isEqualTo(MAIN_THREAD_STACK) + assertThat(mainThread.state).isEqualTo("runnable") + assertThat(mainThread.crashed).isTrue() + + assertThat(threadsDump.filter { it.name == "OkHttp browser-intake-datadoghq.com" }) + .hasSize(1) + val mixedJavaNativeThread = + threadsDump.first { it.name == "OkHttp browser-intake-datadoghq.com" } + assertThat(mixedJavaNativeThread.stack).isEqualTo(JAVA_AND_NDK_THREAD_STACK) + assertThat(mixedJavaNativeThread.state).isEqualTo("native") + assertThat(mixedJavaNativeThread.crashed).isFalse() + } + + @Test + fun `𝕄 return empty list 𝕎 parse() { malformed trace }`( + @StringForgery fakeTrace: String + ) { + // When + val threadsDump = testedParser.parse(fakeTrace.byteInputStream()) + + // Then + assertThat(threadsDump).isEmpty() + + mockInternalLogger.verifyLog( + InternalLogger.Level.ERROR, + targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), + message = AndroidTraceParser.PARSING_FAILURE_MESSAGE + ) + } + + @Test + fun `𝕄 return empty list 𝕎 parse() { error reading stream }`() { + // When + val mockStream = mock().apply { + whenever(read()) doThrow IOException() + } + val threadsDump = testedParser.parse(mockStream) + + // Then + assertThat(threadsDump).isEmpty() + + mockInternalLogger.verifyLog( + InternalLogger.Level.ERROR, + InternalLogger.Target.USER, + AndroidTraceParser.TRACE_STREAM_READ_FAILURE, + throwableClass = IOException::class.java + ) + } + + companion object { + const val MAIN_THREAD_STACK = + """ at android.graphics.Paint.getNativeInstance(Paint.java:743) + at android.graphics.BaseRecordingCanvas.drawRect(BaseRecordingCanvas.java:364) + at com.datadog.android.sample.vitals.BadView.onDraw(BadView.kt:72) + at android.view.View.draw(View.java:23889) + at android.view.View.updateDisplayListIfDirty(View.java:22756) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:694) + at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:700) + at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:798) + at android.view.ViewRootImpl.draw(ViewRootImpl.java:4939) + at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4643) + at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3822) + at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2465) + at android.view.ViewRootImpl${'$'}TraversalRunnable.run(ViewRootImpl.java:9305) + at android.view.Choreographer${'$'}CallbackRecord.run(Choreographer.java:1339) + at android.view.Choreographer${'$'}CallbackRecord.run(Choreographer.java:1348) + at android.view.Choreographer.doCallbacks(Choreographer.java:952) + at android.view.Choreographer.doFrame(Choreographer.java:882) + at android.view.Choreographer${'$'}FrameDisplayEventReceiver.run(Choreographer.java:1322) + at android.os.Handler.handleCallback(Handler.java:958) + at android.os.Handler.dispatchMessage(Handler.java:99) + at android.os.Looper.loopOnce(Looper.java:205) + at android.os.Looper.loop(Looper.java:294) + at android.app.ActivityThread.main(ActivityThread.java:8177) + at java.lang.reflect.Method.invoke(Native method) + at com.android.internal.os.RuntimeInit${'$'}MethodAndArgsCaller.run(RuntimeInit.java:552) + at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)""" + + const val JAVA_AND_NDK_THREAD_STACK = + """ native: #00 pc 00062e1c /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 0022cfac /apex/com.android.art/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks+140) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #02 pc 0039978c /apex/com.android.art/lib64/libart.so (art::::CheckJNI::SetPrimitiveArrayRegion +1352) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #03 pc 0002de34 /apex/com.android.art/lib64/libopenjdk.so (SocketInputStream_socketRead0+260) (BuildId: fc4c0ac2dde70b1afe348b962a85a634) + native: #04 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 003ae360 /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge+320) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 00398584 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1488) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 0050cf2c /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+12964) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #09 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #10 pc 00145c98 /apex/com.android.art/javalib/core-oj.jar (java.net.SocketInputStream.socketRead) + native: #11 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 00398d78 /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge+100) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 00398520 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1388) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #14 pc 0050cf2c /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+12964) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #15 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 00145b14 /apex/com.android.art/javalib/core-oj.jar (java.net.SocketInputStream.read) + native: #17 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #19 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #20 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 00145aec /apex/com.android.art/javalib/core-oj.jar (java.net.SocketInputStream.read) + native: #22 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #24 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #25 pc 0058acb0 /apex/com.android.art/lib64/libart.so (nterp_helper+4016) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 0001818e /apex/com.android.conscrypt/javalib/conscrypt.jar (com.android.org.conscrypt.ConscryptEngineSocket${'$'}SSLInputStream.readFromSocket+50) + native: #27 pc 0058ac54 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #28 pc 0001800e /apex/com.android.conscrypt/javalib/conscrypt.jar (com.android.org.conscrypt.ConscryptEngineSocket${'$'}SSLInputStream.processDataFromSocket+350) + native: #29 pc 0058ac54 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #30 pc 000181d2 /apex/com.android.conscrypt/javalib/conscrypt.jar (com.android.org.conscrypt.ConscryptEngineSocket${'$'}SSLInputStream.readUntilDataAvailable+2) + native: #31 pc 0058ac54 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #32 pc 0001812c /apex/com.android.conscrypt/javalib/conscrypt.jar (com.android.org.conscrypt.ConscryptEngineSocket${'$'}SSLInputStream.read+16) + native: #33 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #34 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #35 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #36 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #37 pc 0008a120 (okio.InputStreamSource.read) + native: #38 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #39 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #40 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #41 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #42 pc 0007f0f0 (okio.AsyncTimeout${'$'}source${'$'}1.read) + native: #43 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #44 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #45 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #46 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #47 pc 0008f1a4 (okio.RealBufferedSource.request) + native: #48 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #49 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #50 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #51 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #52 pc 000903ec (okio.RealBufferedSource.require) + native: #53 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #54 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #55 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #56 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #57 pc 00071904 (okhttp3.internal.http2.Http2Reader.nextFrame) + native: #58 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #59 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #60 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #61 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #62 pc 0006f0a8 (okhttp3.internal.http2.Http2Connection${'$'}ReaderRunnable.invoke) + native: #63 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #64 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #65 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #66 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #67 pc 0006eacc (okhttp3.internal.http2.Http2Connection${'$'}ReaderRunnable.invoke) + native: #68 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #69 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #70 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #71 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #72 pc 00062510 (okhttp3.internal.concurrent.TaskQueue${'$'}execute${'$'}1.runOnce) + native: #73 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #74 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #75 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #76 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #77 pc 00063868 (okhttp3.internal.concurrent.TaskRunner.runTask) + native: #78 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #79 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #80 pc 0050a5d4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+2380) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #81 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #82 pc 000634d8 (okhttp3.internal.concurrent.TaskRunner.access${'$'}runTask) + native: #83 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #84 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #85 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #86 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #87 pc 00062fd0 (okhttp3.internal.concurrent.TaskRunner${'$'}runnable${'$'}1.run) + native: #88 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #89 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #90 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #91 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #92 pc 002488d8 /apex/com.android.art/javalib/core-oj.jar (java.util.concurrent.ThreadPoolExecutor.runWorker) + native: #93 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #94 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #95 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #96 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #97 pc 00247774 /apex/com.android.art/javalib/core-oj.jar (java.util.concurrent.ThreadPoolExecutor${'$'}Worker.run) + native: #98 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #99 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #100 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #101 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #102 pc 0000308c [anon:dalvik-/apex/com.android.art/javalib/core-oj.jar-transformed] (java.lang.Thread.run) + native: #103 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #104 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #105 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #106 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #107 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #108 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #109 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #110 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at java.net.SocketInputStream.socketRead0(Native method) + at java.net.SocketInputStream.socketRead(SocketInputStream.java:118) + at java.net.SocketInputStream.read(SocketInputStream.java:173) + at java.net.SocketInputStream.read(SocketInputStream.java:143) + at com.android.org.conscrypt.ConscryptEngineSocket${'$'}SSLInputStream.readFromSocket(ConscryptEngineSocket.java:983) + at com.android.org.conscrypt.ConscryptEngineSocket${'$'}SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:947) + at com.android.org.conscrypt.ConscryptEngineSocket${'$'}SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:862) + at com.android.org.conscrypt.ConscryptEngineSocket${'$'}SSLInputStream.read(ConscryptEngineSocket.java:835) + at okio.InputStreamSource.read(JvmOkio.kt:94) + at okio.AsyncTimeout${'$'}source${'$'}1.read(AsyncTimeout.kt:125) + at okio.RealBufferedSource.request(RealBufferedSource.kt:206) + at okio.RealBufferedSource.require(RealBufferedSource.kt:199) + at okhttp3.internal.http2.Http2Reader.nextFrame(Http2Reader.kt:89) + at okhttp3.internal.http2.Http2Connection${'$'}ReaderRunnable.invoke(Http2Connection.kt:618) + at okhttp3.internal.http2.Http2Connection${'$'}ReaderRunnable.invoke(Http2Connection.kt:609) + at okhttp3.internal.concurrent.TaskQueue${'$'}execute${'$'}1.runOnce(TaskQueue.kt:98) + at okhttp3.internal.concurrent.TaskRunner.runTask(TaskRunner.kt:116) + at okhttp3.internal.concurrent.TaskRunner.access${'$'}runTask(TaskRunner.kt:42) + at okhttp3.internal.concurrent.TaskRunner${'$'}runnable${'$'}1.run(TaskRunner.kt:65) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) + at java.util.concurrent.ThreadPoolExecutor${'$'}Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012)""" + } +} diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/tracking/OreoFragmentLifecycleCallbacksTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/tracking/OreoFragmentLifecycleCallbacksTest.kt index e4b4a98ce8..4327535d68 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/tracking/OreoFragmentLifecycleCallbacksTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/tracking/OreoFragmentLifecycleCallbacksTest.kt @@ -102,7 +102,7 @@ internal class OreoFragmentLifecycleCallbacksTest { whenever(mockActivity.fragmentManager).thenReturn(mockFragmentManager) whenever(mockActivity.window).thenReturn(mockWindow) - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.BASE + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.BASE whenever(mockSdkCore.internalLogger) doReturn mockInternalLogger @@ -312,7 +312,7 @@ internal class OreoFragmentLifecycleCallbacksTest { @Test fun `it will register the callback to fragment manager on O`() { // Given - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.O + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.O // When testedLifecycleCallbacks.register(mockActivity, mockSdkCore) @@ -327,7 +327,7 @@ internal class OreoFragmentLifecycleCallbacksTest { @Test fun `it will unregister the callback from fragment manager on O`() { // Given - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.O + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.O // When testedLifecycleCallbacks.unregister(mockActivity) @@ -339,7 +339,7 @@ internal class OreoFragmentLifecycleCallbacksTest { @Test fun `it will do nothing when calling register on M`() { // Given - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.M + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.M // When testedLifecycleCallbacks.register(mockActivity, mockSdkCore) @@ -351,7 +351,7 @@ internal class OreoFragmentLifecycleCallbacksTest { @Test fun `it will do nothing when calling unregister on M`() { // Given - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.M + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.M // When testedLifecycleCallbacks.unregister(mockActivity) diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/vitals/JankStatsActivityLifecycleListenerTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/vitals/JankStatsActivityLifecycleListenerTest.kt index 9812855925..225086fc49 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/vitals/JankStatsActivityLifecycleListenerTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/vitals/JankStatsActivityLifecycleListenerTest.kt @@ -262,7 +262,7 @@ internal class JankStatsActivityLifecycleListenerTest { // Given whenever(mockDecorView.isHardwareAccelerated) doReturn true val mockBuildSdkVersionProvider: BuildSdkVersionProvider = mock() - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.S + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.S testedJankListener = JankStatsActivityLifecycleListener( mockObserver, mockInternalLogger, @@ -376,7 +376,7 @@ internal class JankStatsActivityLifecycleListenerTest { val frameData = FrameData(timestampNs, frameDurationNs, isJank, emptyList()) val mockBuildSdkVersionProvider: BuildSdkVersionProvider = mock() - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.S + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.S val variableRefreshRateListener = JankStatsActivityLifecycleListener( mockObserver, @@ -412,7 +412,7 @@ internal class JankStatsActivityLifecycleListenerTest { val frameData = FrameData(timestampNs, frameDurationNs, isJank, emptyList()) val mockBuildSdkVersionProvider: BuildSdkVersionProvider = mock() - whenever(mockBuildSdkVersionProvider.version()) doReturn Build.VERSION_CODES.R + whenever(mockBuildSdkVersionProvider.version) doReturn Build.VERSION_CODES.R val mockDisplay: Display = mock() whenever(mockDisplay.refreshRate) doReturn displayRefreshRate.toFloat() diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/tracking/FragmentViewTrackingStrategyTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/tracking/FragmentViewTrackingStrategyTest.kt index 2e94f7995b..8b752315ae 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/tracking/FragmentViewTrackingStrategyTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/tracking/FragmentViewTrackingStrategyTest.kt @@ -17,6 +17,7 @@ import androidx.fragment.app.FragmentManager import com.datadog.android.api.InternalLogger import com.datadog.android.api.feature.Feature import com.datadog.android.api.feature.FeatureScope +import com.datadog.android.core.internal.system.BuildSdkVersionProvider import com.datadog.android.rum.internal.RumFeature import com.datadog.android.rum.internal.tracking.OreoFragmentLifecycleCallbacks import com.datadog.android.rum.utils.config.GlobalRumMonitorTestConfiguration @@ -24,11 +25,10 @@ import com.datadog.android.rum.utils.forge.Configurator import com.datadog.android.rum.utils.resolveViewUrl import com.datadog.tools.unit.ObjectTest import com.datadog.tools.unit.annotations.TestConfigurationsProvider -import com.datadog.tools.unit.annotations.TestTargetApi -import com.datadog.tools.unit.extensions.ApiLevelExtension import com.datadog.tools.unit.extensions.TestConfigurationExtension import com.datadog.tools.unit.extensions.config.TestConfiguration import fr.xgouchet.elmyr.Forge +import fr.xgouchet.elmyr.annotation.IntForgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat @@ -54,7 +54,6 @@ import org.mockito.quality.Strictness @Extensions( ExtendWith(ForgeExtension::class), ExtendWith(MockitoExtension::class), - ExtendWith(ApiLevelExtension::class), ExtendWith(TestConfigurationExtension::class) ) @MockitoSettings(strictness = Strictness.LENIENT) @@ -85,6 +84,9 @@ internal class FragmentViewTrackingStrategyTest : ObjectTest() val mockFragment: android.app.Fragment = mockDeprecatedFragmentWithArguments(forge) @@ -462,9 +484,11 @@ internal class FragmentViewTrackingStrategyTest : ObjectTest() val baseArgumentCaptor = diff --git a/features/dd-sdk-android-rum/src/test/resources/anr_crash_trace.txt b/features/dd-sdk-android-rum/src/test/resources/anr_crash_trace.txt new file mode 100644 index 0000000000..cab0d90ad6 --- /dev/null +++ b/features/dd-sdk-android-rum/src/test/resources/anr_crash_trace.txt @@ -0,0 +1,1551 @@ +Subject: Input dispatching timed out (f130cca com.datadog.android.sample/com.datadog.android.sample.NavActivity (server) is not responding. Waited 5000ms for MotionEvent) +RssHwmKb: 249844 +RssKb: 211120 +RssAnonKb: 119340 +RssShmemKb: 980 +VmSwapKb: 19256 + + +--- CriticalEventLog --- +capacity: 20 +timestamp_ms: 1707821024474 +window_ms: 300000 + +----- dumping pid: 10348 at 24653821 + +----- pid 10348 at 2024-02-13 11:43:44.465960343+0100 ----- +Cmd line: com.datadog.android.sample +Build fingerprint: 'google/sdk_gphone64_arm64/emu64a:14/UE1A.230829.036.A1/11228894:user/release-keys' +ABI: 'arm64' +Build type: optimized +suspend all histogram: Sum: 242us 99% C.I. 0.096us-59us Avg: 8.344us Max: 59us +DALVIK THREADS (46): +"main" prio=5 tid=1 Runnable + | group="main" sCount=0 ucsCount=0 flags=0 obj=0x73286cd8 self=0xb40000735e697f50 + | sysTid=10348 nice=-10 cgrp=top-app sched=0/0 handle=0x7553fa54f8 + | state=R schedstat=( 7032405053 179598104 2356 ) utm=330 stm=372 core=2 HZ=100 + | stack=0x7fc7ed6000-0x7fc7ed8000 stackSize=8188KB + | held mutexes= "mutator lock"(shared held) + at android.graphics.Paint.getNativeInstance(Paint.java:743) + at android.graphics.BaseRecordingCanvas.drawRect(BaseRecordingCanvas.java:364) + at com.datadog.android.sample.vitals.BadView.onDraw(BadView.kt:72) + at android.view.View.draw(View.java:23889) + at android.view.View.updateDisplayListIfDirty(View.java:22756) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540) + at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513) + at android.view.View.updateDisplayListIfDirty(View.java:22712) + at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:694) + at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:700) + at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:798) + at android.view.ViewRootImpl.draw(ViewRootImpl.java:4939) + at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4643) + at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3822) + at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2465) + at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9305) + at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1339) + at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348) + at android.view.Choreographer.doCallbacks(Choreographer.java:952) + at android.view.Choreographer.doFrame(Choreographer.java:882) + at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322) + at android.os.Handler.handleCallback(Handler.java:958) + at android.os.Handler.dispatchMessage(Handler.java:99) + at android.os.Looper.loopOnce(Looper.java:205) + at android.os.Looper.loop(Looper.java:294) + at android.app.ActivityThread.main(ActivityThread.java:8177) + at java.lang.reflect.Method.invoke(Native method) + at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) + at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) + +"FinalizerDaemon" daemon prio=5 tid=10 Waiting + | group="system" sCount=1 ucsCount=0 flags=1 obj=0x144403a8 self=0xb40000735e6c1ad0 + | sysTid=10360 nice=4 cgrp=top-app sched=0/0 handle=0x721e96ccb0 + | state=S schedstat=( 3002750 1584833 11 ) utm=0 stm=0 core=1 HZ=100 + | stack=0x721e869000-0x721e86b000 stackSize=1039KB + | held mutexes= + at java.lang.Object.wait(Native method) + - waiting on <0x07ba1f11> (a java.lang.Object) + at java.lang.Object.wait(Object.java:386) + at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:210) + - locked <0x07ba1f11> (a java.lang.Object) + at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:231) + at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:309) + at java.lang.Daemons$Daemon.run(Daemons.java:145) + at java.lang.Thread.run(Thread.java:1012) + +"FinalizerWatchdogDaemon" daemon prio=5 tid=11 Sleeping + | group="system" sCount=1 ucsCount=0 flags=1 obj=0x14440420 self=0xb40000735e6c5270 + | sysTid=10361 nice=4 cgrp=top-app sched=0/0 handle=0x721e862cb0 + | state=S schedstat=( 378081 740709 12 ) utm=0 stm=0 core=3 HZ=100 + | stack=0x721e75f000-0x721e761000 stackSize=1039KB + | held mutexes= + at java.lang.Thread.sleep(Native method) + - sleeping on <0x07dc9876> (a java.lang.Object) + at java.lang.Thread.sleep(Thread.java:450) + - locked <0x07dc9876> (a java.lang.Object) + at java.lang.Thread.sleep(Thread.java:355) + at java.lang.Daemons$FinalizerWatchdogDaemon.sleepForNanos(Daemons.java:481) + at java.lang.Daemons$FinalizerWatchdogDaemon.waitForProgress(Daemons.java:544) + at java.lang.Daemons$FinalizerWatchdogDaemon.runInternal(Daemons.java:412) + at java.lang.Daemons$Daemon.run(Daemons.java:145) + at java.lang.Thread.run(Thread.java:1012) + +"ReferenceQueueDaemon" daemon prio=5 tid=13 Waiting + | group="system" sCount=1 ucsCount=0 flags=1 obj=0x14440498 self=0xb40000735e6c6e40 + | sysTid=10359 nice=4 cgrp=top-app sched=0/0 handle=0x721ea76cb0 + | state=S schedstat=( 10028082 254917 20 ) utm=1 stm=0 core=2 HZ=100 + | stack=0x721e973000-0x721e975000 stackSize=1039KB + | held mutexes= + at java.lang.Object.wait(Native method) + - waiting on <0x00a50e77> (a java.lang.Class) + at java.lang.Object.wait(Object.java:386) + at java.lang.Object.wait(Object.java:524) + at java.lang.Daemons$ReferenceQueueDaemon.runInternal(Daemons.java:239) + - locked <0x00a50e77> (a java.lang.Class) + at java.lang.Daemons$Daemon.run(Daemons.java:145) + at java.lang.Thread.run(Thread.java:1012) + +"pool-2-thread-1" prio=5 tid=24 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14441158 self=0xb40000735e6e0f70 + | sysTid=10380 nice=0 cgrp=top-app sched=0/0 handle=0x720cfd0cb0 + | state=S schedstat=( 332059624 5326249 74 ) utm=32 stm=0 core=3 HZ=100 + | stack=0x720cecd000-0x720cecf000 stackSize=1039KB + | held mutexes= + at java.lang.Object.wait(Native method) + - waiting on <0x07b99ae4> (a okhttp3.internal.http2.Http2Stream) + at java.lang.Object.wait(Object.java:386) + at java.lang.Object.wait(Object.java:524) + at okhttp3.internal.http2.Http2Stream.waitForIo$okhttp(Http2Stream.kt:714) + at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.kt:140) + - locked <0x07b99ae4> (a okhttp3.internal.http2.Http2Stream) + at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.kt:97) + at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:110) + at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:93) + at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) + at com.datadog.android.core.internal.data.upload.CurlInterceptor.intercept(CurlInterceptor.kt:44) + at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) + at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34) + at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) + at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95) + at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) + at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) + at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) + at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) + at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) + at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201) + at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154) + at com.datadog.android.core.internal.data.upload.DataOkHttpUploader.executeUploadRequest(DataOkHttpUploader.kt:105) + at com.datadog.android.core.internal.data.upload.DataOkHttpUploader.upload(DataOkHttpUploader.kt:54) + at com.datadog.android.core.internal.data.upload.DataUploadRunnable.consumeBatch(DataUploadRunnable.kt:129) + at com.datadog.android.core.internal.data.upload.DataUploadRunnable.handleNextBatch(DataUploadRunnable.kt:88) + at com.datadog.android.core.internal.data.upload.DataUploadRunnable.run(DataUploadRunnable.kt:54) + at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:487) + at java.util.concurrent.FutureTask.run(FutureTask.java:264) + at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:307) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"pool-5-thread-1" prio=5 tid=26 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14441408 self=0xb40000735e6df3a0 + | sysTid=10382 nice=0 cgrp=top-app sched=0/0 handle=0x720cdbccb0 + | state=S schedstat=( 19850161 2682874 99 ) utm=1 stm=0 core=0 HZ=100 + | stack=0x720ccb9000-0x720ccbb000 stackSize=1039KB + | held mutexes= + at java.lang.Object.wait(Native method) + - waiting on <0x07909b4d> (a com.datadog.android.rum.internal.anr.ANRDetectorRunnable$CallbackRunnable) + at java.lang.Object.wait(Object.java:386) + at java.lang.Object.wait(Object.java:524) + at com.datadog.android.rum.internal.anr.ANRDetectorRunnable.run(ANRDetectorRunnable.kt:52) + - locked <0x07909b4d> (a com.datadog.android.rum.internal.anr.ANRDetectorRunnable$CallbackRunnable) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"Picasso-refQueue" daemon prio=5 tid=32 TimedWaiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14441c28 self=0xb40000735e6ed220 + | sysTid=10388 nice=10 cgrp=top-app sched=0/0 handle=0x720c661cb0 + | state=S schedstat=( 2393126 1195709 31 ) utm=0 stm=0 core=1 HZ=100 + | stack=0x720c55e000-0x720c560000 stackSize=1039KB + | held mutexes= + at java.lang.Object.wait(Native method) + - waiting on <0x0271c602> (a java.lang.Object) + at java.lang.Object.wait(Object.java:386) + at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:210) + - locked <0x0271c602> (a java.lang.Object) + at com.squareup.picasso.Picasso$CleanupThread.run(Picasso.java:631) + +"Okio Watchdog" daemon prio=5 tid=45 TimedWaiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14442a00 self=0xb40000735e72f300 + | sysTid=10426 nice=0 cgrp=top-app sched=0/0 handle=0x71ef2d1cb0 + | state=S schedstat=( 485499 326083 13 ) utm=0 stm=0 core=0 HZ=100 + | stack=0x71ef1ce000-0x71ef1d0000 stackSize=1039KB + | held mutexes= + at java.lang.Object.wait(Native method) + - waiting on <0x0c521b13> (a java.lang.Class) + at okio.AsyncTimeout$Companion.awaitTimeout$okio(AsyncTimeout.kt:318) + at okio.AsyncTimeout$Watchdog.run(AsyncTimeout.kt:183) + - locked <0x0c521b13> (a java.lang.Class) + +"OkHttp browser-intake-datadoghq.com" daemon prio=5 tid=46 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14442f10 self=0xb40000735e734670 + | sysTid=10430 nice=0 cgrp=top-app sched=0/0 handle=0x71ee1c7cb0 + | state=S schedstat=( 29256791 578875 14 ) utm=2 stm=0 core=2 HZ=100 + | stack=0x71ee0c4000-0x71ee0c6000 stackSize=1039KB + | held mutexes= + native: #00 pc 00062e1c /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 0022cfac /apex/com.android.art/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks+140) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #02 pc 0039978c /apex/com.android.art/lib64/libart.so (art::::CheckJNI::SetPrimitiveArrayRegion +1352) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #03 pc 0002de34 /apex/com.android.art/lib64/libopenjdk.so (SocketInputStream_socketRead0+260) (BuildId: fc4c0ac2dde70b1afe348b962a85a634) + native: #04 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 003ae360 /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge+320) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 00398584 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1488) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 0050cf2c /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+12964) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #09 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #10 pc 00145c98 /apex/com.android.art/javalib/core-oj.jar (java.net.SocketInputStream.socketRead) + native: #11 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 00398d78 /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge+100) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 00398520 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1388) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #14 pc 0050cf2c /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+12964) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #15 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 00145b14 /apex/com.android.art/javalib/core-oj.jar (java.net.SocketInputStream.read) + native: #17 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #19 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #20 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 00145aec /apex/com.android.art/javalib/core-oj.jar (java.net.SocketInputStream.read) + native: #22 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #24 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #25 pc 0058acb0 /apex/com.android.art/lib64/libart.so (nterp_helper+4016) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 0001818e /apex/com.android.conscrypt/javalib/conscrypt.jar (com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket+50) + native: #27 pc 0058ac54 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #28 pc 0001800e /apex/com.android.conscrypt/javalib/conscrypt.jar (com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket+350) + native: #29 pc 0058ac54 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #30 pc 000181d2 /apex/com.android.conscrypt/javalib/conscrypt.jar (com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable+2) + native: #31 pc 0058ac54 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #32 pc 0001812c /apex/com.android.conscrypt/javalib/conscrypt.jar (com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read+16) + native: #33 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #34 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #35 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #36 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #37 pc 0008a120 (okio.InputStreamSource.read) + native: #38 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #39 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #40 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #41 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #42 pc 0007f0f0 (okio.AsyncTimeout$source$1.read) + native: #43 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #44 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #45 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #46 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #47 pc 0008f1a4 (okio.RealBufferedSource.request) + native: #48 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #49 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #50 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #51 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #52 pc 000903ec (okio.RealBufferedSource.require) + native: #53 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #54 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #55 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #56 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #57 pc 00071904 (okhttp3.internal.http2.Http2Reader.nextFrame) + native: #58 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #59 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #60 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #61 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #62 pc 0006f0a8 (okhttp3.internal.http2.Http2Connection$ReaderRunnable.invoke) + native: #63 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #64 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #65 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #66 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #67 pc 0006eacc (okhttp3.internal.http2.Http2Connection$ReaderRunnable.invoke) + native: #68 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #69 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #70 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #71 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #72 pc 00062510 (okhttp3.internal.concurrent.TaskQueue$execute$1.runOnce) + native: #73 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #74 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #75 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #76 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #77 pc 00063868 (okhttp3.internal.concurrent.TaskRunner.runTask) + native: #78 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #79 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #80 pc 0050a5d4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+2380) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #81 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #82 pc 000634d8 (okhttp3.internal.concurrent.TaskRunner.access$runTask) + native: #83 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #84 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #85 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #86 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #87 pc 00062fd0 (okhttp3.internal.concurrent.TaskRunner$runnable$1.run) + native: #88 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #89 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #90 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #91 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #92 pc 002488d8 /apex/com.android.art/javalib/core-oj.jar (java.util.concurrent.ThreadPoolExecutor.runWorker) + native: #93 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #94 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #95 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #96 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #97 pc 00247774 /apex/com.android.art/javalib/core-oj.jar (java.util.concurrent.ThreadPoolExecutor$Worker.run) + native: #98 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #99 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #100 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #101 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #102 pc 0000308c [anon:dalvik-/apex/com.android.art/javalib/core-oj.jar-transformed] (java.lang.Thread.run) + native: #103 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #104 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #105 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #106 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #107 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #108 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #109 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #110 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at java.net.SocketInputStream.socketRead0(Native method) + at java.net.SocketInputStream.socketRead(SocketInputStream.java:118) + at java.net.SocketInputStream.read(SocketInputStream.java:173) + at java.net.SocketInputStream.read(SocketInputStream.java:143) + at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:983) + at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:947) + at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:862) + at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:835) + - locked <0x06e78150> (a java.lang.Object) + at okio.InputStreamSource.read(JvmOkio.kt:94) + at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:125) + at okio.RealBufferedSource.request(RealBufferedSource.kt:206) + at okio.RealBufferedSource.require(RealBufferedSource.kt:199) + at okhttp3.internal.http2.Http2Reader.nextFrame(Http2Reader.kt:89) + at okhttp3.internal.http2.Http2Connection$ReaderRunnable.invoke(Http2Connection.kt:618) + at okhttp3.internal.http2.Http2Connection$ReaderRunnable.invoke(Http2Connection.kt:609) + at okhttp3.internal.concurrent.TaskQueue$execute$1.runOnce(TaskQueue.kt:98) + at okhttp3.internal.concurrent.TaskRunner.runTask(TaskRunner.kt:116) + at okhttp3.internal.concurrent.TaskRunner.access$runTask(TaskRunner.kt:42) + at okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.kt:65) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"OkHttp TaskRunner" daemon prio=5 tid=47 TimedWaiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14445c08 self=0xb40000735e732aa0 + | sysTid=10431 nice=0 cgrp=top-app sched=0/0 handle=0x71edbfbcb0 + | state=S schedstat=( 1779620 0 10 ) utm=0 stm=0 core=2 HZ=100 + | stack=0x71edaf8000-0x71edafa000 stackSize=1039KB + | held mutexes= + at java.lang.Object.wait(Native method) + - waiting on <0x0dd89f49> (a okhttp3.internal.concurrent.TaskRunner) + at okhttp3.internal.concurrent.TaskRunner$RealBackend.coordinatorWait(TaskRunner.kt:294) + at okhttp3.internal.concurrent.TaskRunner.awaitTaskToRun(TaskRunner.kt:218) + at okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.kt:59) + - locked <0x0dd89f49> (a okhttp3.internal.concurrent.TaskRunner) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"pool-14-thread-1" prio=5 tid=2 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x13400180 self=0xb40000735e779ef0 + | sysTid=10443 nice=0 cgrp=top-app sched=0/0 handle=0x72746fdcb0 + | state=S schedstat=( 287793 0 2 ) utm=0 stm=0 core=2 HZ=100 + | stack=0x72745fa000-0x72745fc000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1176) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"Signal Catcher" daemon prio=10 tid=6 Runnable + | group="system" sCount=0 ucsCount=0 flags=0 obj=0x14440240 self=0xb40000735e699b20 + | sysTid=10354 nice=-20 cgrp=top-app sched=0/0 handle=0x72747fbcb0 + | state=R schedstat=( 659960 1547584 9 ) utm=0 stm=0 core=1 HZ=100 + | stack=0x7274704000-0x7274706000 stackSize=991KB + | held mutexes= "mutator lock"(shared held) + native: #00 pc 00438384 /apex/com.android.art/lib64/libart.so (art::DumpNativeStack+108) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #01 pc 00474f5c /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack const+828) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #02 pc 00474624 /apex/com.android.art/lib64/libart.so (art::DumpCheckpoint::Run+208) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #03 pc 0035036c /apex/com.android.art/lib64/libart.so (art::ThreadList::RunCheckpoint+452) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 007c6674 /apex/com.android.art/lib64/libart.so (art::ThreadList::Dump+1716) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 007c5c30 /apex/com.android.art/lib64/libart.so (art::ThreadList::DumpForSigQuit+744) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 00798f1c /apex/com.android.art/lib64/libart.so (art::Runtime::DumpForSigQuit+56) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 007a9934 /apex/com.android.art/lib64/libart.so (art::SignalCatcher::HandleSigQuit+1320) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 0049e234 /apex/com.android.art/lib64/libart.so (art::SignalCatcher::Run+312) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #09 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #10 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"perfetto_hprof_listener" prio=10 tid=7 Native (still starting up) + | group="" sCount=1 ucsCount=0 flags=1 obj=0x0 self=0xb40000735e692be0 + | sysTid=10355 nice=-20 cgrp=top-app sched=0/0 handle=0x726f6fdcb0 + | state=S schedstat=( 306709 1558083 6 ) utm=0 stm=0 core=1 HZ=100 + | stack=0x726f606000-0x726f608000 stackSize=991KB + | held mutexes= + native: #00 pc 000b7374 /apex/com.android.runtime/lib64/bionic/libc.so (read+4) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 00025360 /apex/com.android.art/lib64/libperfetto_hprof.so (void* std::__1::__thread_proxy >, ArtPlugin_Initialize::$_7> >+316) (BuildId: 45b5dfbcea5fc746bc003aa7e18dbb74) + native: #02 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #03 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"ADB-JDWP Connection Control Thread" daemon prio=0 tid=8 WaitingInMainDebuggerLoop + | group="system" sCount=1 ucsCount=0 flags=1 obj=0x144402b8 self=0xb40000735e6bff00 + | sysTid=10356 nice=-20 cgrp=top-app sched=0/0 handle=0x726f5ffcb0 + | state=S schedstat=( 5197542 5215168 7 ) utm=0 stm=0 core=3 HZ=100 + | stack=0x726f508000-0x726f50a000 stackSize=991KB + | held mutexes= + native: #00 pc 000b8758 /apex/com.android.runtime/lib64/bionic/libc.so (__ppoll+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 00072ed0 /apex/com.android.runtime/lib64/bionic/libc.so (poll+92) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #02 pc 0000a75c /apex/com.android.art/lib64/libadbconnection.so (adbconnection::AdbConnectionState::RunPollLoop+724) (BuildId: 18d4f4b1c63b7f9ca4644652b670af77) + native: #03 pc 00008ecc /apex/com.android.art/lib64/libadbconnection.so (adbconnection::CallbackFunction+1456) (BuildId: 18d4f4b1c63b7f9ca4644652b670af77) + native: #04 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #05 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"Jit thread pool worker thread 0" daemon prio=5 tid=9 Native + | group="system" sCount=1 ucsCount=0 flags=1 obj=0x14440330 self=0xb40000735e6c36a0 + | sysTid=10357 nice=9 cgrp=top-app sched=0/0 handle=0x721fc86cb0 + | state=S schedstat=( 27520623 13802000 99 ) utm=1 stm=0 core=3 HZ=100 + | stack=0x721fb87000-0x721fb89000 stackSize=1023KB + | held mutexes= + native: #00 pc 00062e1c /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 0022cfac /apex/com.android.art/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks+140) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #02 pc 003f4b1c /apex/com.android.art/lib64/libart.so (art::jit::JitCompileTask::Run+716) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #03 pc 00577524 /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Run+100) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 00577424 /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Callback+164) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #06 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"HeapTaskDaemon" daemon prio=5 tid=12 WaitingForTaskProcessor + | group="system" sCount=1 ucsCount=0 flags=1 obj=0x14445fb0 self=0xb40000735e6be330 + | sysTid=10358 nice=4 cgrp=top-app sched=0/0 handle=0x721fb80cb0 + | state=S schedstat=( 28869749 3710666 31 ) utm=2 stm=0 core=3 HZ=100 + | stack=0x721fa7d000-0x721fa7f000 stackSize=1039KB + | held mutexes= + native: #00 pc 00062e1c /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 0022cfac /apex/com.android.art/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks+140) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #02 pc 00393af8 /apex/com.android.art/lib64/libart.so (art::gc::TaskProcessor::GetTask+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #03 pc 00393818 /apex/com.android.art/lib64/libart.so (art::gc::TaskProcessor::RunAllTasks+52) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #09 pc 0002bb10 /apex/com.android.art/javalib/core-libart.jar (java.lang.Daemons$HeapTaskDaemon.runInternal) + native: #10 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #11 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #14 pc 0002ae3c /apex/com.android.art/javalib/core-libart.jar (java.lang.Daemons$Daemon.run) + native: #15 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #17 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #19 pc 0010ee0c /apex/com.android.art/javalib/core-oj.jar (java.lang.Thread.run) + native: #20 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #22 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #24 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #25 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #27 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at dalvik.system.VMRuntime.runHeapTasks(Native method) + at java.lang.Daemons$HeapTaskDaemon.runInternal(Daemons.java:687) + at java.lang.Daemons$Daemon.run(Daemons.java:145) + at java.lang.Thread.run(Thread.java:1012) + +"binder:10348_1" prio=5 tid=14 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14440510 self=0xb40000735e6cc1b0 + | sysTid=10362 nice=0 cgrp=top-app sched=0/0 handle=0x721a65acb0 + | state=S schedstat=( 231459 1057125 26 ) utm=0 stm=0 core=3 HZ=100 + | stack=0x721a563000-0x721a565000 stackSize=991KB + | held mutexes= + native: #00 pc 000b7698 /apex/com.android.runtime/lib64/bionic/libc.so (__ioctl+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 00070668 /apex/com.android.runtime/lib64/bionic/libc.so (ioctl+156) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #02 pc 00096b1c /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool+348) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #03 pc 000969ac /system/lib64/libbinder.so (android::PoolThread::threadLoop+24) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #04 pc 00010e28 /system/lib64/libutils.so (android::Thread::_threadLoop+584) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #05 pc 000edb18 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell+140) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #06 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #07 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"binder:10348_2" prio=5 tid=15 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14440588 self=0xb40000735e6ca5e0 + | sysTid=10363 nice=0 cgrp=top-app sched=0/0 handle=0x721955ccb0 + | state=S schedstat=( 43525252 35343205 730 ) utm=2 stm=2 core=1 HZ=100 + | stack=0x7219465000-0x7219467000 stackSize=991KB + | held mutexes= + native: #00 pc 000b7698 /apex/com.android.runtime/lib64/bionic/libc.so (__ioctl+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 00070668 /apex/com.android.runtime/lib64/bionic/libc.so (ioctl+156) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #02 pc 00096b1c /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool+348) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #03 pc 000969ac /system/lib64/libbinder.so (android::PoolThread::threadLoop+24) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #04 pc 00010e28 /system/lib64/libutils.so (android::Thread::_threadLoop+584) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #05 pc 000edb18 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell+140) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #06 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #07 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"binder:10348_3" prio=5 tid=16 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14440600 self=0xb40000735e6cdd80 + | sysTid=10365 nice=0 cgrp=top-app sched=0/0 handle=0x721845ecb0 + | state=S schedstat=( 31163076 31567625 621 ) utm=1 stm=1 core=0 HZ=100 + | stack=0x7218367000-0x7218369000 stackSize=991KB + | held mutexes= + native: #00 pc 00062e1c /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 0022cfac /apex/com.android.art/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks+140) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #02 pc 0040e260 /apex/com.android.art/lib64/libart.so (art::::CheckJNI::CallMethodV +3040) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #03 pc 00526c9c /apex/com.android.art/lib64/libart.so (art::::CheckJNI::CallStaticBooleanMethodV +76) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 004df88c /system/lib64/libhwui.so (_JNIEnv::CallStaticBooleanMethod+120) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #05 pc 004df7b0 /system/lib64/libhwui.so (android::HardwareRendererObserver::notify+216) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #06 pc 005f9444 /system/lib64/libhwui.so (android::uirenderer::renderthread::CanvasContext::onSurfaceStatsAvailable+3052) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #07 pc 00027c5c /system/lib64/libandroid.so (std::__1::__function::__func, void >::operator+220) (BuildId: ee15305f0ca03707d21e5e9e9ab687bc) + native: #08 pc 000e67d8 /system/lib64/libgui.so (android::TransactionCompletedListener::onTransactionCompleted+5884) (BuildId: 67cb3d0bd5575f4f3fc95aac325f4723) + native: #09 pc 00128348 /system/lib64/libgui.so (android::BnTransactionCompletedListener::onTransact+1168) (BuildId: 67cb3d0bd5575f4f3fc95aac325f4723) + native: #10 pc 00074580 /system/lib64/libbinder.so (android::BBinder::transact+248) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #11 pc 00073100 /system/lib64/libbinder.so (android::IPCThreadState::executeCommand+500) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #12 pc 00096c04 /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool+580) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #13 pc 000969ac /system/lib64/libbinder.so (android::PoolThread::threadLoop+24) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #14 pc 00010e28 /system/lib64/libutils.so (android::Thread::_threadLoop+584) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #15 pc 000edb18 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell+140) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #16 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #17 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"Profile Saver" daemon prio=5 tid=17 Native + | group="system" sCount=1 ucsCount=0 flags=1 obj=0x14440678 self=0xb40000735e6d4cc0 + | sysTid=10368 nice=9 cgrp=top-app sched=0/0 handle=0x7216ab2cb0 + | state=S schedstat=( 16237665 160667 4 ) utm=1 stm=0 core=3 HZ=100 + | stack=0x72169bb000-0x72169bd000 stackSize=991KB + | held mutexes= + native: #00 pc 00062e20 /apex/com.android.runtime/lib64/bionic/libc.so (syscall+32) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 002bba38 /apex/com.android.art/lib64/libart.so (art::ConditionVariable::TimedWait+252) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #02 pc 00400bb0 /apex/com.android.art/lib64/libart.so (art::ProfileSaver::Run+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #03 pc 003fd0b4 /apex/com.android.art/lib64/libart.so (art::ProfileSaver::RunProfileSaverThread+152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #05 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"WM.task-1" prio=5 tid=18 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x144406f0 self=0xb40000735e6c8a10 + | sysTid=10369 nice=0 cgrp=top-app sched=0/0 handle=0x721583ecb0 + | state=S schedstat=( 18512332 3658292 71 ) utm=1 stm=0 core=3 HZ=100 + | stack=0x721573b000-0x721573d000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"StethoListener-main" prio=5 tid=19 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14440860 self=0xb40000735e6d30f0 + | sysTid=10370 nice=0 cgrp=top-app sched=0/0 handle=0x7215734cb0 + | state=S schedstat=( 590831 0 1 ) utm=0 stm=0 core=0 HZ=100 + | stack=0x7215631000-0x7215633000 stackSize=1039KB + | held mutexes= + native: #00 pc 000b8174 /apex/com.android.runtime/lib64/bionic/libc.so (__accept4+4) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 0001168c /system/lib64/libnetd_client.so ((anonymous namespace)::netdClientAccept4 +72) (BuildId: 4164d0544a756c9eb008bd07dc00f744) + native: #02 pc 000665a4 /apex/com.android.runtime/lib64/bionic/libc.so (accept4+44) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #03 pc 000247ec /apex/com.android.art/lib64/libjavacore.so (Linux_accept+172) (BuildId: 058a3af6bcbdbcdce4bfe922408e624f) + native: #04 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #09 pc 000376ac /apex/com.android.art/javalib/core-libart.jar (libcore.io.ForwardingOs.accept) + native: #10 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #11 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #14 pc 00036390 /apex/com.android.art/javalib/core-libart.jar (libcore.io.BlockGuardOs.accept) + native: #15 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #17 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #19 pc 000376ac /apex/com.android.art/javalib/core-libart.jar (libcore.io.ForwardingOs.accept) + native: #20 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #22 pc 0050aca4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+4124) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #24 pc 000200d8 /apex/com.android.art/javalib/core-libart.jar (android.system.Os.accept) + native: #25 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #27 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #28 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #29 pc 000200bc /apex/com.android.art/javalib/core-libart.jar (android.system.Os.accept) + native: #30 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #31 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #32 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #33 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #34 pc 0049c340 /system/framework/framework.jar (android.net.LocalSocketImpl.accept) + native: #35 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #36 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #37 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #38 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #39 pc 0049b960 /system/framework/framework.jar (android.net.LocalServerSocket.accept) + native: #40 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #41 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #42 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #43 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #44 pc 00fd3b10 (com.facebook.stetho.server.LocalSocketServer.listenOnAddress) + native: #45 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #46 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #47 pc 0050a5d4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+2380) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #48 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #49 pc 00fd3c50 (com.facebook.stetho.server.LocalSocketServer.run) + native: #50 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #51 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #52 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #53 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #54 pc 00fd407c (com.facebook.stetho.server.ServerManager$1.run) + native: #55 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #56 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #57 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #58 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #59 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #60 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #61 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #62 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at libcore.io.Linux.accept(Native method) + at libcore.io.ForwardingOs.accept(ForwardingOs.java:91) + at libcore.io.BlockGuardOs.accept(BlockGuardOs.java:66) + at libcore.io.ForwardingOs.accept(ForwardingOs.java:91) + at android.system.Os.accept(Os.java:57) + at android.system.Os.accept(Os.java:51) + at android.net.LocalSocketImpl.accept(LocalSocketImpl.java:303) + at android.net.LocalServerSocket.accept(LocalServerSocket.java:93) + at com.facebook.stetho.server.LocalSocketServer.listenOnAddress(LocalSocketServer.java:83) + at com.facebook.stetho.server.LocalSocketServer.run(LocalSocketServer.java:72) + at com.facebook.stetho.server.ServerManager$1.run(ServerManager.java:38) + +"pool-3-thread-1" prio=5 tid=20 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14440ce0 self=0xb40000735e6cf950 + | sysTid=10372 nice=0 cgrp=top-app sched=0/0 handle=0x721562acb0 + | state=S schedstat=( 229639950 18737958 144 ) utm=22 stm=0 core=1 HZ=100 + | stack=0x7215527000-0x7215529000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:485) + at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:673) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"WM.task-2" prio=5 tid=21 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14440fb0 self=0xb40000735e6d8460 + | sysTid=10378 nice=0 cgrp=top-app sched=0/0 handle=0x7215520cb0 + | state=S schedstat=( 1378207 69208 6 ) utm=0 stm=0 core=0 HZ=100 + | stack=0x721541d000-0x721541f000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"kronos-android" prio=5 tid=22 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14440e40 self=0xb40000735e6da030 + | sysTid=10374 nice=0 cgrp=top-app sched=0/0 handle=0x720c0dacb0 + | state=S schedstat=( 1912543 16205166 15 ) utm=0 stm=0 core=3 HZ=100 + | stack=0x720bfd7000-0x720bfd9000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"ConnectivityThread" prio=5 tid=23 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14441078 self=0xb40000735e6d6890 + | sysTid=10379 nice=0 cgrp=top-app sched=0/0 handle=0x720d0dacb0 + | state=S schedstat=( 6605873 4697374 18 ) utm=0 stm=0 core=1 HZ=100 + | stack=0x720cfd7000-0x720cfd9000 stackSize=1039KB + | held mutexes= + native: #00 pc 000b8658 /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000101d8 /system/lib64/libutils.so (android::Looper::pollOnce+204) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #02 pc 00183604 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce+44) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #03 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 0050a5d4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+2380) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 001fce24 /system/framework/framework.jar (android.os.MessageQueue.next) + native: #09 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #10 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #11 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 001fbe08 /system/framework/framework.jar (android.os.Looper.loopOnce) + native: #14 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #15 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #17 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 001fc57c /system/framework/framework.jar (android.os.Looper.loop) + native: #19 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #20 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #22 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 001d603c /system/framework/framework.jar (android.os.HandlerThread.run) + native: #24 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #25 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #27 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #28 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #29 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #30 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #31 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at android.os.MessageQueue.nativePollOnce(Native method) + at android.os.MessageQueue.next(MessageQueue.java:335) + at android.os.Looper.loopOnce(Looper.java:162) + at android.os.Looper.loop(Looper.java:294) + at android.os.HandlerThread.run(HandlerThread.java:67) + +"pool-4-thread-1" prio=5 tid=25 TimedWaiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x144412b0 self=0xb40000735e6dd7d0 + | sysTid=10381 nice=0 cgrp=top-app sched=0/0 handle=0x720cec6cb0 + | state=S schedstat=( 372866928 12209419 127 ) utm=30 stm=6 core=0 HZ=100 + | stack=0x720cdc3000-0x720cdc5000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1188) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"pool-6-thread-1" prio=5 tid=27 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14441640 self=0xb40000735e6e4710 + | sysTid=10383 nice=0 cgrp=top-app sched=0/0 handle=0x720ccb2cb0 + | state=S schedstat=( 15303209 631542 25 ) utm=1 stm=0 core=3 HZ=100 + | stack=0x720cbaf000-0x720cbb1000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"queued-work-looper" prio=5 tid=28 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x144417b0 self=0xb40000735e6e2b40 + | sysTid=10384 nice=-2 cgrp=top-app sched=0/0 handle=0x720ca89cb0 + | state=S schedstat=( 2264584 425458 12 ) utm=0 stm=0 core=3 HZ=100 + | stack=0x720c986000-0x720c988000 stackSize=1039KB + | held mutexes= + native: #00 pc 000b8658 /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000101d8 /system/lib64/libutils.so (android::Looper::pollOnce+204) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #02 pc 00183604 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce+44) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #03 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 0050a5d4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+2380) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 001fce24 /system/framework/framework.jar (android.os.MessageQueue.next) + native: #09 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #10 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #11 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 001fbe08 /system/framework/framework.jar (android.os.Looper.loopOnce) + native: #14 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #15 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #17 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 001fc57c /system/framework/framework.jar (android.os.Looper.loop) + native: #19 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #20 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #22 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 001d603c /system/framework/framework.jar (android.os.HandlerThread.run) + native: #24 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #25 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #27 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #28 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #29 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #30 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #31 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at android.os.MessageQueue.nativePollOnce(Native method) + at android.os.MessageQueue.next(MessageQueue.java:335) + at android.os.Looper.loopOnce(Looper.java:162) + at android.os.Looper.loop(Looper.java:294) + at android.os.HandlerThread.run(HandlerThread.java:67) + +"dd-task-scheduler" daemon prio=5 tid=29 TimedWaiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14441890 self=0xb40000735e6e9a80 + | sysTid=10385 nice=0 cgrp=top-app sched=0/0 handle=0x720c97fcb0 + | state=S schedstat=( 11528039 1260626 33 ) utm=0 stm=0 core=3 HZ=100 + | stack=0x720c87c000-0x720c87e000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1188) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"Picasso-Stats" prio=5 tid=30 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x144419e8 self=0xb40000735e6e7eb0 + | sysTid=10386 nice=10 cgrp=top-app sched=0/0 handle=0x720c875cb0 + | state=S schedstat=( 3405417 2243503 33 ) utm=0 stm=0 core=0 HZ=100 + | stack=0x720c772000-0x720c774000 stackSize=1039KB + | held mutexes= + native: #00 pc 000b8658 /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000101d8 /system/lib64/libutils.so (android::Looper::pollOnce+204) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #02 pc 00183604 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce+44) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #03 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 0050a5d4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+2380) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 001fce24 /system/framework/framework.jar (android.os.MessageQueue.next) + native: #09 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #10 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #11 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 001fbe08 /system/framework/framework.jar (android.os.Looper.loopOnce) + native: #14 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #15 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #17 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 001fc57c /system/framework/framework.jar (android.os.Looper.loop) + native: #19 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #20 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #22 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 001d603c /system/framework/framework.jar (android.os.HandlerThread.run) + native: #24 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #25 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #27 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #28 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #29 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #30 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #31 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at android.os.MessageQueue.nativePollOnce(Native method) + at android.os.MessageQueue.next(MessageQueue.java:335) + at android.os.Looper.loopOnce(Looper.java:162) + at android.os.Looper.loop(Looper.java:294) + at android.os.HandlerThread.run(HandlerThread.java:67) + +"Picasso-Dispatcher" prio=5 tid=31 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14441b08 self=0xb40000735e6e62e0 + | sysTid=10387 nice=10 cgrp=top-app sched=0/0 handle=0x720c76bcb0 + | state=S schedstat=( 5238751 2717625 34 ) utm=0 stm=0 core=1 HZ=100 + | stack=0x720c668000-0x720c66a000 stackSize=1039KB + | held mutexes= + native: #00 pc 000b8658 /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000101d8 /system/lib64/libutils.so (android::Looper::pollOnce+204) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #02 pc 00183604 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce+44) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #03 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 0050a5d4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+2380) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 001fce24 /system/framework/framework.jar (android.os.MessageQueue.next) + native: #09 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #10 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #11 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 001fbe08 /system/framework/framework.jar (android.os.Looper.loopOnce) + native: #14 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #15 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #17 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 001fc57c /system/framework/framework.jar (android.os.Looper.loop) + native: #19 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #20 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #22 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 001d603c /system/framework/framework.jar (android.os.HandlerThread.run) + native: #24 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #25 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #27 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #28 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #29 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #30 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #31 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at android.os.MessageQueue.nativePollOnce(Native method) + at android.os.MessageQueue.next(MessageQueue.java:335) + at android.os.Looper.loopOnce(Looper.java:162) + at android.os.Looper.loop(Looper.java:294) + at android.os.HandlerThread.run(HandlerThread.java:67) + +"pool-12-thread-1" prio=5 tid=33 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14441eb0 self=0xb40000735e6eedf0 + | sysTid=10389 nice=0 cgrp=top-app sched=0/0 handle=0x720c557cb0 + | state=S schedstat=( 6886462 2484623 12 ) utm=0 stm=0 core=0 HZ=100 + | stack=0x720c454000-0x720c456000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:485) + at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:673) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"kronos-android" prio=5 tid=34 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14442010 self=0xb40000735e6f09c0 + | sysTid=10390 nice=0 cgrp=top-app sched=0/0 handle=0x720c44dcb0 + | state=S schedstat=( 1726499 1478293 8 ) utm=0 stm=0 core=1 HZ=100 + | stack=0x720c34a000-0x720c34c000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"pool-11-thread-1" prio=5 tid=35 TimedWaiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14442180 self=0xb40000735e6eb650 + | sysTid=10391 nice=0 cgrp=top-app sched=0/0 handle=0x720c343cb0 + | state=S schedstat=( 13715793 2833625 15 ) utm=1 stm=0 core=1 HZ=100 + | stack=0x720c240000-0x720c242000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1188) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"RenderThread" daemon prio=7 tid=36 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x144422d8 self=0xb40000735e6f5d30 + | sysTid=10392 nice=-10 cgrp=top-app sched=0/0 handle=0x720c239cb0 + | state=S schedstat=( 824844538 44759803 1293 ) utm=35 stm=47 core=0 HZ=100 + | stack=0x720c142000-0x720c144000 stackSize=991KB + | held mutexes= + native: #00 pc 00062e1c /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000677c8 /apex/com.android.runtime/lib64/bionic/libc.so (__futex_wait_ex+144) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #02 pc 000cc8f8 /apex/com.android.runtime/lib64/bionic/libc.so (NonPI::MutexLockWithTimeout+344) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #03 pc 00050094 /system/lib64/libc++.so (std::__1::mutex::lock+8) (BuildId: 12d4c26c3edc0fb330898d775b3910f5) + native: #04 pc 00202a54 /system/lib64/libhwui.so (android::uirenderer::renderthread::CanvasContext::draw+676) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #05 pc 003e9bd0 /system/lib64/libhwui.so (android::uirenderer::renderthread::CanvasContext::prepareAndDraw+352) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #06 pc 0057808c /system/lib64/libhwui.so (std::__1::__function::__func, void >::operator +164) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #07 pc 002aab44 /system/lib64/libhwui.so (android::uirenderer::renderthread::RenderThread::threadLoop+716) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #08 pc 00010e28 /system/lib64/libutils.so (android::Thread::_threadLoop+584) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #09 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #10 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"WM.task-3" prio=5 tid=37 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14442350 self=0xb40000735e6f2590 + | sysTid=10395 nice=0 cgrp=top-app sched=0/0 handle=0x71fbfd0cb0 + | state=S schedstat=( 6513959 93000 5 ) utm=0 stm=0 core=1 HZ=100 + | stack=0x71fbecd000-0x71fbecf000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"FrameMetricsAggregator" prio=5 tid=38 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14442418 self=0xb40000735e6fcc70 + | sysTid=10396 nice=0 cgrp=top-app sched=0/0 handle=0x71f86fbcb0 + | state=S schedstat=( 53389021 13510080 486 ) utm=5 stm=0 core=0 HZ=100 + | stack=0x71f85f8000-0x71f85fa000 stackSize=1039KB + | held mutexes= + native: #00 pc 000b8658 /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000101d8 /system/lib64/libutils.so (android::Looper::pollOnce+204) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #02 pc 00183604 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce+44) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #03 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 0050a5d4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+2380) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 001fce24 /system/framework/framework.jar (android.os.MessageQueue.next) + native: #09 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #10 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #11 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 001fbe08 /system/framework/framework.jar (android.os.Looper.loopOnce) + native: #14 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #15 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #17 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 001fc57c /system/framework/framework.jar (android.os.Looper.loop) + native: #19 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #20 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #22 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 001d603c /system/framework/framework.jar (android.os.HandlerThread.run) + native: #24 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #25 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #27 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #28 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #29 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #30 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #31 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at android.os.MessageQueue.nativePollOnce(Native method) + at android.os.MessageQueue.next(MessageQueue.java:335) + at android.os.Looper.loopOnce(Looper.java:162) + at android.os.Looper.loop(Looper.java:294) + at android.os.HandlerThread.run(HandlerThread.java:67) + +"SurfaceSyncGroupTimer" prio=5 tid=39 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x144424f8 self=0xb40000735e701fe0 + | sysTid=10397 nice=0 cgrp=top-app sched=0/0 handle=0x71f75f1cb0 + | state=S schedstat=( 231958 0 3 ) utm=0 stm=0 core=0 HZ=100 + | stack=0x71f74ee000-0x71f74f0000 stackSize=1039KB + | held mutexes= + native: #00 pc 000b8658 /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000101d8 /system/lib64/libutils.so (android::Looper::pollOnce+204) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #02 pc 00183604 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce+44) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #03 pc 00377030 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #04 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #05 pc 004906b4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+1248) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #06 pc 0050a5d4 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+2380) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #07 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #08 pc 001fce24 /system/framework/framework.jar (android.os.MessageQueue.next) + native: #09 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #10 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #11 pc 00509f94 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+780) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #12 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #13 pc 001fbe08 /system/framework/framework.jar (android.os.Looper.loopOnce) + native: #14 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #15 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #16 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #17 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #18 pc 001fc57c /system/framework/framework.jar (android.os.Looper.loop) + native: #19 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #20 pc 0049120c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall+4152) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #21 pc 0050a2f8 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp+1648) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #22 pc 003797d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #23 pc 001d603c /system/framework/framework.jar (android.os.HandlerThread.run) + native: #24 pc 0037cde0 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +356) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #25 pc 0037c560 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+672) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #26 pc 00377168 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #27 pc 003605a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #28 pc 0034b8a4 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke+144) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #29 pc 004f3e30 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback+1888) (BuildId: b10f5696fea1b32039b162aef3850ed3) + native: #30 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #31 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + at android.os.MessageQueue.nativePollOnce(Native method) + at android.os.MessageQueue.next(MessageQueue.java:335) + at android.os.Looper.loopOnce(Looper.java:162) + at android.os.Looper.loop(Looper.java:294) + at android.os.HandlerThread.run(HandlerThread.java:67) + +"hwuiTask0" daemon prio=6 tid=40 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x144425d8 self=0xb40000735e70aaf0 + | sysTid=10399 nice=-2 cgrp=top-app sched=0/0 handle=0x71f73e9cb0 + | state=S schedstat=( 171873 18000 3 ) utm=0 stm=0 core=0 HZ=100 + | stack=0x71f72f2000-0x71f72f4000 stackSize=991KB + | held mutexes= + native: #00 pc 00062e1c /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000677c8 /apex/com.android.runtime/lib64/bionic/libc.so (__futex_wait_ex+144) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #02 pc 000ca970 /apex/com.android.runtime/lib64/bionic/libc.so (pthread_cond_wait+76) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #03 pc 00052fd0 /system/lib64/libc++.so (std::__1::condition_variable::wait+20) (BuildId: 12d4c26c3edc0fb330898d775b3910f5) + native: #04 pc 0049650c /system/lib64/libhwui.so (android::uirenderer::CommonPool::workerLoop+108) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #05 pc 004963f8 /system/lib64/libhwui.so (void std::__1::__thread_execute >, android::uirenderer::CommonPool::CommonPool::$_0> +184) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #06 pc 0049633c /system/lib64/libhwui.so (void* std::__1::__thread_proxy >, android::uirenderer::CommonPool::CommonPool::$_0> > +40) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #07 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #08 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"hwuiTask1" daemon prio=6 tid=41 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14442650 self=0xb40000735e708f20 + | sysTid=10400 nice=-2 cgrp=top-app sched=0/0 handle=0x71f5d6bcb0 + | state=S schedstat=( 128958 0 2 ) utm=0 stm=0 core=1 HZ=100 + | stack=0x71f5c74000-0x71f5c76000 stackSize=991KB + | held mutexes= + native: #00 pc 00062e1c /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000677c8 /apex/com.android.runtime/lib64/bionic/libc.so (__futex_wait_ex+144) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #02 pc 000ca970 /apex/com.android.runtime/lib64/bionic/libc.so (pthread_cond_wait+76) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #03 pc 00052fd0 /system/lib64/libc++.so (std::__1::condition_variable::wait+20) (BuildId: 12d4c26c3edc0fb330898d775b3910f5) + native: #04 pc 0049650c /system/lib64/libhwui.so (android::uirenderer::CommonPool::workerLoop+108) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #05 pc 004963f8 /system/lib64/libhwui.so (void std::__1::__thread_execute >, android::uirenderer::CommonPool::CommonPool::$_0> +184) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #06 pc 0049633c /system/lib64/libhwui.so (void* std::__1::__thread_proxy >, android::uirenderer::CommonPool::CommonPool::$_0> > +40) (BuildId: 1178351e2ee9668d0f2e2865813d9ee6) + native: #07 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #08 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"binder:10348_4" prio=5 tid=42 Native + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x144426c8 self=0xb40000735e718970 + | sysTid=10401 nice=0 cgrp=top-app sched=0/0 handle=0x71f5c6dcb0 + | state=S schedstat=( 191376 0 4 ) utm=0 stm=0 core=3 HZ=100 + | stack=0x71f5b76000-0x71f5b78000 stackSize=991KB + | held mutexes= + native: #00 pc 000b7698 /apex/com.android.runtime/lib64/bionic/libc.so (__ioctl+8) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 00070668 /apex/com.android.runtime/lib64/bionic/libc.so (ioctl+156) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #02 pc 00096b1c /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool+348) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #03 pc 000969ac /system/lib64/libbinder.so (android::PoolThread::threadLoop+24) (BuildId: 3efdb374ddb1486eab125c1dab846104) + native: #04 pc 00010e28 /system/lib64/libutils.so (android::Thread::_threadLoop+584) (BuildId: 4ad4af87e8ab16b872cdbdaf84188131) + native: #05 pc 000edb18 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell+140) (BuildId: c741d6d101847b558f8cdb0633f23335) + native: #06 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #07 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + (no managed stack frames) + +"pool-8-thread-1" prio=5 tid=43 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14442740 self=0xb40000735e71dce0 + | sysTid=10404 nice=0 cgrp=top-app sched=0/0 handle=0x71f14e5cb0 + | state=S schedstat=( 274001799 23559289 205 ) utm=27 stm=0 core=0 HZ=100 + | stack=0x71f13e2000-0x71f13e4000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:485) + at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:673) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"pool-7-thread-1" prio=5 tid=44 Waiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x144428a0 self=0xb40000735e723050 + | sysTid=10405 nice=0 cgrp=top-app sched=0/0 handle=0x71f03dbcb0 + | state=S schedstat=( 104415831 8148874 206 ) utm=10 stm=0 core=3 HZ=100 + | stack=0x71f02d8000-0x71f02da000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3466) + at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3437) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623) + at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:485) + at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:673) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1071) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"OkHttp TaskRunner" daemon prio=5 tid=48 TimedWaiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14445df8 self=0xb40000735e737e10 + | sysTid=10432 nice=0 cgrp=top-app sched=0/0 handle=0x71eb5fbcb0 + | state=S schedstat=( 727001 0 2 ) utm=0 stm=0 core=3 HZ=100 + | stack=0x71eb4f8000-0x71eb4fa000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252) + at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:401) + at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:903) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"OkHttp TaskRunner" daemon prio=5 tid=49 TimedWaiting + | group="main" sCount=1 ucsCount=0 flags=1 obj=0x14445ee8 self=0xb40000735e736240 + | sysTid=10433 nice=0 cgrp=top-app sched=0/0 handle=0x71ea4f1cb0 + | state=S schedstat=( 117250 299500 1 ) utm=0 stm=0 core=0 HZ=100 + | stack=0x71ea3ee000-0x71ea3f0000 stackSize=1039KB + | held mutexes= + at jdk.internal.misc.Unsafe.park(Native method) + - waiting on an unknown object + at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252) + at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:401) + at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:903) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) + at java.lang.Thread.run(Thread.java:1012) + +"binder:10348_3" prio=5 (not attached) + | sysTid=10402 nice=0 cgrp=top-app + | state=S schedstat=( 1133847 9776449 480 ) utm=0 stm=0 core=1 HZ=100 + native: #00 pc 00062e1c /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #01 pc 000677c8 /apex/com.android.runtime/lib64/bionic/libc.so (__futex_wait_ex+144) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #02 pc 000ca970 /apex/com.android.runtime/lib64/bionic/libc.so (pthread_cond_wait+76) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #03 pc 00052fd0 /system/lib64/libc++.so (std::__1::condition_variable::wait+20) (BuildId: 12d4c26c3edc0fb330898d775b3910f5) + native: #04 pc 0010d4f4 /system/lib64/libgui.so (android::AsyncWorker::run+112) (BuildId: 67cb3d0bd5575f4f3fc95aac325f4723) + native: #05 pc 000ed3a8 /system/lib64/libgui.so (void* std::__1::__thread_proxy >, void , android::AsyncWorker*> >+72) (BuildId: 67cb3d0bd5575f4f3fc95aac325f4723) + native: #06 pc 000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start+208) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + native: #07 pc 0006821c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a87908b48b368e6282bcc9f34bcfc28c) + +Zygote loaded classes=24859 post zygote classes=5561 +Dumping registered class loaders +#0 dalvik.system.PathClassLoader: [], parent #1 +#1 java.lang.BootClassLoader: [], no parent +#2 dalvik.system.PathClassLoader: [/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes27.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes16.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes7.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes19.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes5.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes10.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes28.dex:/data/data/com.datadog.android.sample/code_cache/.overlay/base.apk/classes12.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes26.dex:/data/data/com.datadog.android.sample/code_cache/.overlay/base.apk/classes14.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes30.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes29.dex:/data/data/com.datadog.android.sample/code_cache/.overlay/base.apk/classes23.dex:/data/data/com.datadog.android.sample/code_cache/.overlay/base.apk/classes13.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes3.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes6.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes2.dex:/data/data/com.datadog.android.sample/code_cache/.overlay/base.apk/classes9.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes24.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes17.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes4.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes22.dex:/data/data/com.datadog.android.sample/code_cache/.overlay/base.apk/classes8.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes20.dex:/data/data/com.datadog.android.sample/code_cache/.overlay/base.apk/classes15.dex:/data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/base.apk!classes11.dex], parent #1 +Done dumping class loaders +Classes initialized: 0 in 0 +Intern table: 45803 strong; 1045 weak +JNI: CheckJNI is on; globals=408 (plus 147 weak) +Libraries: /data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/lib/arm64/libdatadog-native-lib.so /data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/lib/arm64/libdatadog-native-sample-lib.so /data/app/~~4Hdpw4yH6PultdkbudOeDw==/com.datadog.android.sample-ivPL6XVQGCUDQXXkvycxDw==/lib/arm64/librealmc.so libandroid.so libaudioeffect_jni.so libcompiler_rt.so libframework-connectivity-jni.so libframework-connectivity-tiramisu-jni.so libicu_jni.so libjavacore.so libjavacrypto.so libjnigraphics.so libmedia_jni.so libopenjdk.so librs_jni.so librtp_jni.so libsoundpool.so libstats_jni.so libwebviewchromium_loader.so (19) +Heap: 32% free, 8401KB/12MB; 214361 objects +Image spaces: +/system/framework/arm64/boot.art +/system/framework/arm64/boot-core-libart.art +/system/framework/arm64/boot-okhttp.art +/system/framework/arm64/boot-bouncycastle.art +/system/framework/arm64/boot-apache-xml.art +/system/framework/arm64/boot-framework.art +/system/framework/arm64/boot-framework-graphics.art +/system/framework/arm64/boot-ext.art +/system/framework/arm64/boot-telephony-common.art +/system/framework/arm64/boot-voip-common.art +/system/framework/arm64/boot-ims-common.art +/system/framework/arm64/boot-core-icu4j.art +/system/framework/arm64/boot-framework-adservices.art +Dumping cumulative Gc timings +Start Dumping Averages for 1 iterations for concurrent copying +MarkingPhase: Sum: 7.269ms Avg: 7.269ms +Process mark stacks and References: Sum: 6.725ms Avg: 6.725ms +VisitConcurrentRoots: Sum: 4.812ms Avg: 4.812ms +ScanImmuneSpaces: Sum: 1.578ms Avg: 1.578ms +ClearFromSpace: Sum: 509us Avg: 509us +CaptureThreadRootsForMarking: Sum: 496us Avg: 496us +GrayAllDirtyImmuneObjects: Sum: 352us Avg: 352us +SweepLargeObjects: Sum: 238us Avg: 238us +EnqueueFinalizerReferences: Sum: 182us Avg: 182us +InitializePhase: Sum: 181us Avg: 181us +FlipOtherThreads: Sum: 150us Avg: 150us +SweepSystemWeaks: Sum: 130us Avg: 130us +MarkZygoteLargeObjects: Sum: 107us Avg: 107us +CopyingPhase: Sum: 88us Avg: 88us +ScanCardsForSpace: Sum: 82us Avg: 82us +ProcessReferences: Sum: 74us Avg: 74us +ForwardSoftReferences: Sum: 56us Avg: 56us +RecordFree: Sum: 30us Avg: 30us +VisitNonThreadRoots: Sum: 19us Avg: 19us +MarkStackAsLive: Sum: 17us Avg: 17us +(Paused)GrayAllNewlyDirtyImmuneObjects: Sum: 14us Avg: 14us +(Paused)ClearCards: Sum: 13us Avg: 13us +SweepAllocSpace: Sum: 9us Avg: 9us +SwapBitmaps: Sum: 8us Avg: 8us +ThreadListFlip: Sum: 7us Avg: 7us +ResumeRunnableThreads: Sum: 4us Avg: 4us +EmptyRBMarkBitStack: Sum: 3us Avg: 3us +ReclaimPhase: Sum: 2us Avg: 2us +(Paused)SetFromSpace: Sum: 1us Avg: 1us +(Paused)FlipCallback: Sum: 1us Avg: 1us +UnBindBitmaps: Sum: 1us Avg: 1us +Sweep: Sum: 1us Avg: 1us +FlipThreadRoots: Sum: 0 Avg: 0 +ResumeOtherThreads: Sum: 0 Avg: 0 +Done Dumping Averages +concurrent copying paused: Sum: 55us 99% C.I. 12us-43us Avg: 27.500us Max: 43us +concurrent copying freed-bytes: Avg: 14MB Max: 14MB Min: 14MB +Freed-bytes histogram: 14080:1 +concurrent copying total time: 23.159ms mean time: 23.159ms +concurrent copying freed: 221856 objects with total size 14MB +concurrent copying throughput: 9.64591e+06/s / 613MB/s per cpu-time: 672604000/s / 641MB/s +concurrent copying tracing throughput: 180MB/s per cpu-time: 189MB/s +Average major GC reclaim bytes ratio 1.59517 over 1 GC cycles +Average major GC copied live bytes ratio 0.674099 over 6 major GCs +Cumulative bytes moved 31923792 +Cumulative objects moved 646089 +Peak regions allocated 98 (24MB) / 768 (192MB) +Total madvise time 1.311ms +Start Dumping Averages for 1 iterations for young concurrent copying +CopyingPhase: Sum: 4.110ms Avg: 4.110ms +VisitConcurrentRoots: Sum: 1.229ms Avg: 1.229ms +ScanImmuneSpaces: Sum: 905us Avg: 905us +ScanCardsForSpace: Sum: 869us Avg: 869us +Process mark stacks and References: Sum: 861us Avg: 861us +InitializePhase: Sum: 311us Avg: 311us +SweepArray: Sum: 110us Avg: 110us +ClearFromSpace: Sum: 107us Avg: 107us +FlipOtherThreads: Sum: 79us Avg: 79us +GrayAllDirtyImmuneObjects: Sum: 73us Avg: 73us +EnqueueFinalizerReferences: Sum: 71us Avg: 71us +SweepSystemWeaks: Sum: 60us Avg: 60us +ThreadListFlip: Sum: 57us Avg: 57us +ProcessReferences: Sum: 32us Avg: 32us +ResumeRunnableThreads: Sum: 15us Avg: 15us +(Paused)ClearCards: Sum: 11us Avg: 11us +ForwardSoftReferences: Sum: 9us Avg: 9us +(Paused)GrayAllNewlyDirtyImmuneObjects: Sum: 7us Avg: 7us +RecordFree: Sum: 6us Avg: 6us +EmptyRBMarkBitStack: Sum: 5us Avg: 5us +VisitNonThreadRoots: Sum: 4us Avg: 4us +SwapBitmaps: Sum: 3us Avg: 3us +ResetStack: Sum: 2us Avg: 2us +ReclaimPhase: Sum: 2us Avg: 2us +MarkZygoteLargeObjects: Sum: 2us Avg: 2us +(Paused)SetFromSpace: Sum: 1us Avg: 1us +UnBindBitmaps: Sum: 1us Avg: 1us +FlipThreadRoots: Sum: 0 Avg: 0 +ResumeOtherThreads: Sum: 0 Avg: 0 +FreeList: Sum: 0 Avg: 0 +(Paused)FlipCallback: Sum: 0 Avg: 0 +Done Dumping Averages +young concurrent copying paused: Sum: 101us 99% C.I. 7us-94us Avg: 50.500us Max: 94us +young concurrent copying freed-bytes: Avg: 5765KB Max: 5765KB Min: 5765KB +Freed-bytes histogram: 5760:1 +young concurrent copying total time: 8.942ms mean time: 8.942ms +young concurrent copying freed: 81642 objects with total size 5765KB +young concurrent copying throughput: 1.02052e+07/s / 703MB/s per cpu-time: 1475870000/s / 1407MB/s +young concurrent copying tracing throughput: 137MB/s per cpu-time: 275MB/s +Average minor GC reclaim bytes ratio 0.574598 over 1 GC cycles +Average minor GC copied live bytes ratio 0.275709 over 2 minor GCs +Cumulative bytes moved 2303440 +Cumulative objects moved 50875 +Peak regions allocated 98 (24MB) / 768 (192MB) +Total time spent in GC: 32.101ms +Mean GC size throughput: 614MB/s per cpu-time: 728MB/s +Mean GC object throughput: 9.45447e+06 objects/s +Total number of allocations 517859 +Total bytes allocated 27MB +Total bytes freed 19MB +Free memory 4127KB +Free memory until GC 4127KB +Free memory until OOME 183MB +Total memory 12MB +Max memory 192MB +Zygote space size 6252KB +Total mutator paused time: 156us +Total time waiting for GC to complete: 1.917us +Total GC count: 2 +Total GC time: 32.101ms +Total blocking GC count: 0 +Total blocking GC time: 0 +Total pre-OOME GC count: 0 +Histogram of GC count per 10000 ms: 0:1,1:1 +Histogram of blocking GC count per 10000 ms: 0:2 +Native bytes total: 40103759 registered: 1245599 +Total native bytes at last GC: 24504363 +/system/framework/oat/arm64/android.hidl.manager-V1.0-java.odex: verify +/system/framework/oat/arm64/android.hidl.base-V1.0-java.odex: verify +/system_ext/framework/oat/arm64/androidx.window.sidecar.odex: verify +/system/framework/oat/arm64/android.test.base.odex: verify +/system_ext/framework/oat/arm64/androidx.window.extensions.odex: verify +Current JIT code cache size (used / resident): 67KB / 72KB +Current JIT data cache size (used / resident): 44KB / 72KB +Zygote JIT code cache size (at point of fork): 1KB / 32KB +Zygote JIT data cache size (at point of fork): 1KB / 32KB +Current JIT mini-debug-info size: 15KB +Current JIT capacity: 256KB +Current number of JIT JNI stub entries: 5 +Current number of JIT code cache entries: 66 +Total number of JIT baseline compilations: 64 +Total number of JIT optimized compilations: 16 +Total number of JIT compilations for on stack replacement: 2 +Total number of JIT code cache collections: 2 +Memory used for stack maps: Avg: 233B Max: 4096B Min: 16B +Memory used for compiled code: Avg: 952B Max: 12KB Min: 164B +Memory used for profiling info: Avg: 170B Max: 1896B Min: 24B +Start Dumping Averages for 86 iterations for JIT timings +Compiling baseline: Sum: 21.688ms Avg: 252.186us +Compiling optimized: Sum: 5.850ms Avg: 68.023us +Code cache collection: Sum: 3.235ms Avg: 37.616us +TrimMaps: Sum: 881us Avg: 10.244us +Compiling OSR: Sum: 541us Avg: 6.290us +Done Dumping Averages +Memory used for compilation: Avg: 56KB Max: 812KB Min: 5400B +ProfileSaver total_bytes_written=0 +ProfileSaver total_number_of_writes=0 +ProfileSaver total_number_of_code_cache_queries=0 +ProfileSaver total_number_of_skipped_writes=0 +ProfileSaver total_number_of_failed_writes=0 +ProfileSaver total_ms_of_sleep=4629 +ProfileSaver total_ms_of_work=0 +ProfileSaver total_number_of_hot_spikes=1 +ProfileSaver total_number_of_wake_ups=2 + +*** ART internal metrics *** + Metadata: + timestamp_since_start_ms: 30667 + Metrics: + ClassLoadingTotalTime: count = 77422 + ClassVerificationTotalTime: count = 302725 + ClassVerificationCount: count = 2680 + WorldStopTimeDuringGCAvg: count = 78 + YoungGcCount: count = 1 + FullGcCount: count = 1 + TotalBytesAllocated: count = 26795048 + TotalGcCollectionTime: count = 32 + YoungGcThroughputAvg: count = 418 + FullGcThroughputAvg: count = 501 + YoungGcTracingThroughputAvg: count = 120 + FullGcTracingThroughputAvg: count = 178 + JitMethodCompileTotalTime: count = 33920 + JitMethodCompileCount: count = 82 + YoungGcCollectionTime: range = 0...60000, buckets: 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + FullGcCollectionTime: range = 0...60000, buckets: 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + YoungGcThroughput: range = 0...10000, buckets: 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + FullGcThroughput: range = 0...10000, buckets: 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + YoungGcTracingThroughput: range = 0...10000, buckets: 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + FullGcTracingThroughput: range = 0...10000, buckets: 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + GcWorldStopTime: count = 156 + GcWorldStopCount: count = 2 + YoungGcScannedBytes: count = 1154156 + YoungGcFreedBytes: count = 4392056 + YoungGcDuration: count = 9 + FullGcScannedBytes: count = 4362496 + FullGcFreedBytes: count = 12626408 + FullGcDuration: count = 23 + GcWorldStopTimeDelta: count = 156 + GcWorldStopCountDelta: count = 2 + YoungGcScannedBytesDelta: count = 1154156 + YoungGcFreedBytesDelta: count = 4392056 + YoungGcDurationDelta: count = 9 + FullGcScannedBytesDelta: count = 4362496 + FullGcFreedBytesDelta: count = 12626408 + FullGcDurationDelta: count = 23 + JitMethodCompileTotalTimeDelta: count = 33920 + JitMethodCompileCountDelta: count = 82 + ClassVerificationTotalTimeDelta: count = 302725 + ClassVerificationCountDelta: count = 2680 + ClassLoadingTotalTimeDelta: count = 76928 + TotalBytesAllocatedDelta: count = 26795048 + TotalGcCollectionTimeDelta: count = 32 + YoungGcCountDelta: count = 1 + FullGcCountDelta: count = 1 +*** Done dumping ART internal metrics *** + +----- end 10348 ----- + +----- Waiting Channels: pid 10348 at 2024-02-13 11:43:44.465482634+0100 ----- +Cmd line: com.datadog.android.sample + +sysTid=10348 0 +sysTid=10354 do_sigtimedwait +sysTid=10355 pipe_read +sysTid=10356 do_sys_poll +sysTid=10357 futex_wait +sysTid=10358 futex_wait +sysTid=10359 futex_wait +sysTid=10360 futex_wait +sysTid=10361 futex_wait +sysTid=10362 binder_ioctl_write_read +sysTid=10363 binder_ioctl_write_read +sysTid=10365 binder_ioctl_write_read +sysTid=10368 futex_wait +sysTid=10369 futex_wait +sysTid=10370 __skb_wait_for_more_packets +sysTid=10372 futex_wait +sysTid=10374 futex_wait +sysTid=10378 futex_wait +sysTid=10379 do_epoll_wait +sysTid=10380 futex_wait +sysTid=10381 futex_wait +sysTid=10382 futex_wait +sysTid=10383 futex_wait +sysTid=10384 do_epoll_wait +sysTid=10385 futex_wait +sysTid=10386 do_epoll_wait +sysTid=10387 do_epoll_wait +sysTid=10388 futex_wait +sysTid=10389 futex_wait +sysTid=10390 futex_wait +sysTid=10391 futex_wait +sysTid=10392 0 +sysTid=10395 futex_wait +sysTid=10396 do_epoll_wait +sysTid=10397 do_epoll_wait +sysTid=10399 futex_wait +sysTid=10400 futex_wait +sysTid=10401 binder_ioctl_write_read +sysTid=10402 futex_wait +sysTid=10404 futex_wait +sysTid=10405 futex_wait +sysTid=10426 futex_wait +sysTid=10430 wait_woken +sysTid=10431 futex_wait +sysTid=10432 futex_wait +sysTid=10433 futex_wait +sysTid=10443 futex_wait + +----- end 10348 ----- + +