diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5ce3f1b459..80f60cd888 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ include: # SETUP variables: - CURRENT_CI_IMAGE: "10" + CURRENT_CI_IMAGE: "11" CI_IMAGE_DOCKER: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/dd-sdk-android:$CURRENT_CI_IMAGE GIT_DEPTH: 5 @@ -19,7 +19,7 @@ variables: EMULATOR_NAME: "android_emulator" ANDROID_ARCH: "arm64-v8a" - ANDROID_API: "34" + ANDROID_API: "35" ANDROID_SDK_VERSION: "commandlinetools-mac-11076708_latest" stages: @@ -249,7 +249,7 @@ test-pyramid:core-it-latest-api: stage: test-pyramid timeout: 1h variables: - ANDROID_API: "34" + ANDROID_API: "35" ANDROID_EMULATOR_IMAGE: "system-images;android-$ANDROID_API;google_apis;${ANDROID_ARCH}" ANDROID_PLATFORM: "platforms;android-$ANDROID_API" ANDROID_BUILD_TOOLS: "build-tools;$ANDROID_API.0.0" @@ -353,7 +353,7 @@ test-pyramid:legacy-integration-instrumented-latest-api: stage: test-pyramid timeout: 1h variables: - ANDROID_API: "34" + ANDROID_API: "35" ANDROID_EMULATOR_IMAGE: "system-images;android-$ANDROID_API;google_apis;${ANDROID_ARCH}" ANDROID_PLATFORM: "platforms;android-$ANDROID_API" ANDROID_BUILD_TOOLS: "build-tools;$ANDROID_API.0.0" diff --git a/Dockerfile.gitlab b/Dockerfile.gitlab index f0ab16f0a7..361972df62 100644 --- a/Dockerfile.gitlab +++ b/Dockerfile.gitlab @@ -26,8 +26,8 @@ RUN set -x \ && rm -rf /var/lib/apt/lists/* ENV GRADLE_VERSION 8.9 -ENV ANDROID_COMPILE_SDK 34 -ENV ANDROID_BUILD_TOOLS 34.0.0 +ENV ANDROID_COMPILE_SDK 35 +ENV ANDROID_BUILD_TOOLS 35.0.0 ENV ANDROID_SDK_TOOLS 11076708 ENV NDK_VERSION 25.1.8937393 ENV CMAKE_VERSION 3.22.1 diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt index 8bef196d37..955a821ebb 100644 --- a/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt @@ -15,10 +15,10 @@ import org.gradle.api.Project object AndroidConfig { - const val TARGET_SDK = 34 + const val TARGET_SDK = 35 const val MIN_SDK = 21 const val MIN_SDK_FOR_WEAR = 23 - const val BUILD_TOOLS_VERSION = "34.0.0" + const val BUILD_TOOLS_VERSION = "35.0.0" val VERSION = Version(2, 14, 0, Version.Type.Snapshot) } diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/persistence/file/datastore/DataStoreFileReaderTest.kt b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/persistence/file/datastore/DataStoreFileReaderTest.kt index aac558bf7e..3e7b9c71f9 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/persistence/file/datastore/DataStoreFileReaderTest.kt +++ b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/persistence/file/datastore/DataStoreFileReaderTest.kt @@ -142,7 +142,7 @@ internal class DataStoreFileReaderTest { @Test fun `M log error W read() { invalid number of blocks }`() { // Given - blocksReturned.removeLast() + blocksReturned.removeAt(blocksReturned.lastIndex) val foundBlocks = blocksReturned.size val expectedBlocks = TLVBlockType.values().size @@ -213,7 +213,7 @@ internal class DataStoreFileReaderTest { @Test fun `M return onFailure W read() { invalid number of blocks }`() { // Given - blocksReturned.removeLast() + blocksReturned.removeAt(blocksReturned.lastIndex) val expectedMessage = INVALID_NUMBER_OF_BLOCKS_ERROR.format(Locale.US, blocksReturned.size, TLVBlockType.values().size) val mockCallback = mock>() diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPool.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPool.kt index 3894e73d5f..b071489414 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPool.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPool.kt @@ -118,7 +118,7 @@ internal class BitmapPool( cacheUtils.handleTrimMemory(level, cache) } - internal fun getBitmapByProperties(width: Int, height: Int, config: Config): Bitmap? { + internal fun getBitmapByProperties(width: Int, height: Int, config: Config?): Bitmap? { val key = bitmapPoolHelper.generateKey(width, height, config) return get(key) } diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPoolHelper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPoolHelper.kt index 63d0b91100..7c2da4df53 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPoolHelper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPoolHelper.kt @@ -15,10 +15,10 @@ internal class BitmapPoolHelper( internal fun generateKey(bitmap: Bitmap) = generateKey(bitmap.width, bitmap.height, bitmap.config) - internal fun generateKey(width: Int, height: Int, config: Bitmap.Config) = + internal fun generateKey(width: Int, height: Int, config: Bitmap.Config?) = "$width-$height-$config" - internal fun safeCall(call: () -> R): R? = + internal fun safeCall(call: () -> R): R? = invocationUtils.safeCallWithErrorLogging( call = { call() }, failureMessage = BITMAP_OPERATION_FAILED diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/CacheUtils.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/CacheUtils.kt index 0fdff54672..03945c3624 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/CacheUtils.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/CacheUtils.kt @@ -12,6 +12,10 @@ import androidx.collection.LruCache internal class CacheUtils( private val invocationUtils: InvocationUtils = InvocationUtils() ) { + + // some of this memory level are not being triggered after API 34. We still need to keep them for now + // for lower versions + @Suppress("DEPRECATION") internal fun handleTrimMemory(level: Int, cache: LruCache) { @Suppress("MagicNumber") val onLowMemorySizeBytes = cache.maxSize() / 2 // 50% diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/processor/NodeFlattenerTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/processor/NodeFlattenerTest.kt index e786c2ef1a..9c311cc15e 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/processor/NodeFlattenerTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/processor/NodeFlattenerTest.kt @@ -141,7 +141,7 @@ internal class NodeFlattenerTest { private fun generateTreeFromList(list: List): Node { val mutableList = list.toMutableList() - val root = mutableList.removeFirst().toNode() + val root = mutableList.removeAt(0).toNode() val middle = mutableList.size / 2 // add left // we need to create a new list as Kotlin .subList re - uses the old list @@ -155,7 +155,7 @@ internal class NodeFlattenerTest { if (leafs.isEmpty()) { return } - val leafToAdd = leafs.removeFirst().toNode() + val leafToAdd = leafs.removeAt(0).toNode() parent.addChild(leafToAdd) val middle = leafs.size / 2 // add left diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPoolTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPoolTest.kt index 8e574d1428..b805baa636 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPoolTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/BitmapPoolTest.kt @@ -154,7 +154,8 @@ internal class BitmapPoolTest { testedCache.put(mockBitmap) // Then - val actualBitmap = testedCache.getBitmapByProperties(mockBitmap.width, mockBitmap.height, mockBitmap.config) + val actualBitmap = + testedCache.getBitmapByProperties(mockBitmap.width, mockBitmap.height, mockBitmap.config) assertThat(actualBitmap).isEqualTo(mockBitmap) } diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/BitmapPoolHelperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/BitmapPoolHelperTest.kt new file mode 100644 index 0000000000..046d5cee07 --- /dev/null +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/BitmapPoolHelperTest.kt @@ -0,0 +1,76 @@ +/* + * 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.sessionreplay.internal.utils + +import android.graphics.Bitmap +import com.datadog.android.sessionreplay.forge.ForgeConfigurator +import com.datadog.android.sessionreplay.internal.recorder.resources.BitmapPoolHelper +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 +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.junit.jupiter.MockitoExtension +import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.kotlin.whenever +import org.mockito.quality.Strictness + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class) +) +@MockitoSettings(strictness = Strictness.LENIENT) +@ForgeConfiguration(ForgeConfigurator::class) +internal class BitmapPoolHelperTest { + + lateinit var testedHelper: BitmapPoolHelper + + @Mock + lateinit var mockBitmap: Bitmap + + @IntForgery + var fakeWidth: Int = 0 + + @IntForgery + var fakeHeight: Int = 0 + private lateinit var fakeConfig: Bitmap.Config + + @BeforeEach + fun `set up`(forge: Forge) { + fakeConfig = forge.aValueFrom(Bitmap.Config::class.java) + testedHelper = BitmapPoolHelper() + whenever(mockBitmap.width).thenReturn(fakeWidth) + whenever(mockBitmap.height).thenReturn(fakeHeight) + whenever(mockBitmap.config).thenReturn(fakeConfig) + } + + @Test + fun `M generate bitmap key W generateKey`() { + // When + val key = testedHelper.generateKey(mockBitmap) + + // Then + assertThat(key).isEqualTo("$fakeWidth-$fakeHeight-$fakeConfig") + } + + @Test + fun `M generate bitmap key W generateKey { config is null }`() { + // Given + whenever(mockBitmap.config).thenReturn(null) + + // When + val key = testedHelper.generateKey(mockBitmap) + + // Then + assertThat(key).isEqualTo("$fakeWidth-$fakeHeight-null") + } +}