diff --git a/CHANGELOG.md b/CHANGELOG.md index 2111066..4f0a4ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.2.1 (TBD) + +- Fixed `enableLogging` not being forwarded from `SdkConfig` to + `DeviceDataCollector`, which caused collector-level error logs to be silently + suppressed even when logging was explicitly enabled. + ## 0.2.0 (2026-02-27) - **Breaking:** `collectAndSend()` now returns `Result` instead diff --git a/CLAUDE.md b/CLAUDE.md index 7d57dbb..9bd72e7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -237,7 +237,14 @@ The SDK includes consumer ProGuard rules in `consumer-rules.pro`: ## Environment Setup -**Required:** +**Quick setup with mise (recommended for headless environments):** + +```bash +mise install # Installs Java 21, Android SDK cmdline-tools, etc. +mise run setup # Accepts licenses, installs platform packages, creates local.properties +``` + +**Manual setup:** 1. Java 21 (Android Studio JDK) configured in `gradle.properties`: @@ -245,7 +252,7 @@ The SDK includes consumer ProGuard rules in `consumer-rules.pro`: org.gradle.java.home=/home/greg/.local/share/android-studio/jbr ``` -2. Android SDK with API 34 at `~/Android/Sdk` +2. Android SDK with API 36 at `~/Android/Sdk` 3. `local.properties` file (gitignored): ```properties diff --git a/device-sdk/src/main/java/com/maxmind/device/DeviceTracker.kt b/device-sdk/src/main/java/com/maxmind/device/DeviceTracker.kt index 2b3216a..4c03bf6 100644 --- a/device-sdk/src/main/java/com/maxmind/device/DeviceTracker.kt +++ b/device-sdk/src/main/java/com/maxmind/device/DeviceTracker.kt @@ -48,7 +48,7 @@ public class DeviceTracker private constructor( ) { private val applicationContext: Context = context.applicationContext private val storedIDStorage = StoredIDStorage(applicationContext) - private val deviceDataCollector = DeviceDataCollector(applicationContext, storedIDStorage) + private val deviceDataCollector = DeviceDataCollector(applicationContext, storedIDStorage, config.enableLogging) private val apiClient = DeviceApiClient(config) private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) diff --git a/device-sdk/src/test/java/com/maxmind/device/DeviceTrackerTest.kt b/device-sdk/src/test/java/com/maxmind/device/DeviceTrackerTest.kt index e7606f8..a8a2e50 100644 --- a/device-sdk/src/test/java/com/maxmind/device/DeviceTrackerTest.kt +++ b/device-sdk/src/test/java/com/maxmind/device/DeviceTrackerTest.kt @@ -1,6 +1,7 @@ package com.maxmind.device import android.content.Context +import android.util.Log import com.maxmind.device.collector.DeviceDataCollector import com.maxmind.device.config.SdkConfig import com.maxmind.device.model.ServerResponse @@ -10,6 +11,8 @@ import com.maxmind.device.storage.StoredIDStorage import io.mockk.coEvery import io.mockk.every import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic import io.mockk.verify import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Assertions.assertEquals @@ -261,7 +264,30 @@ internal class DeviceTrackerTest { @Test @Order(15) - internal fun `15 collectAndSend wraps collectDeviceData exception in Result failure`() = + internal fun `15 enableLogging is forwarded to DeviceDataCollector`() { + resetSingleton() + mockkStatic(Log::class) + every { Log.d(any(), any()) } returns 0 + try { + val loggingConfig = + SdkConfig + .Builder(12345) + .enableLogging(true) + .build() + val tracker = DeviceTracker.initialize(mockContext, loggingConfig) + + val collector = getField(tracker, "deviceDataCollector") + val enableLogging = getField(collector, "enableLogging") + + assertTrue(enableLogging, "enableLogging should be forwarded from SdkConfig to DeviceDataCollector") + } finally { + unmockkStatic(Log::class) + } + } + + @Test + @Order(16) + internal fun `16 collectAndSend wraps collectDeviceData exception in Result failure`() = runTest { val tracker = createTrackerWithMocks() val mockCollector = mockk() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 04bce54..cd1abe2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,19 +11,19 @@ serialization = "1.10.0" # Android androidGradlePlugin = "8.13.1" -androidxCore = "1.17.0" +androidxCore = "1.18.0" androidxAppCompat = "1.7.1" androidxLifecycle = "2.10.0" # Networking -ktor = "3.4.0" +ktor = "3.4.2" # Code quality detekt = "1.23.8" -ktlint = "14.0.1" +ktlint = "14.2.0" # Documentation -dokka = "2.1.0" +dokka = "2.2.0" # Testing junit = "4.13.2" diff --git a/mise.toml b/mise.toml index 4214342..e9dae3a 100644 --- a/mise.toml +++ b/mise.toml @@ -4,3 +4,29 @@ java = "temurin-21" # yq is used by release.sh to parse ~/.m2/settings.xml for Maven Central credentials yq = "latest" "github:houseabsolute/precious" = "latest" +android-sdk = "latest" + +[tasks.setup] +description = "Install Android SDK platform packages and configure local.properties" +run = """ +#!/usr/bin/env bash +set -euo pipefail + +echo "Accepting Android SDK licenses..." +yes 2>/dev/null | sdkmanager --licenses > /dev/null 2>&1 || true + +echo "Installing required SDK packages..." +sdkmanager "platforms;android-36" "build-tools;36.0.0" + +if [ ! -f local.properties ]; then + echo "sdk.dir=$ANDROID_HOME" > local.properties + echo "Created local.properties with sdk.dir=$ANDROID_HOME" +elif ! grep -q '^sdk.dir=' local.properties; then + echo "sdk.dir=$ANDROID_HOME" >> local.properties + echo "Added sdk.dir=$ANDROID_HOME to local.properties" +else + echo "local.properties already has sdk.dir configured" +fi + +echo "Setup complete. Run './gradlew :device-sdk:test' to verify." +"""