Skip to content

Support Android API level 27 (STF-772)#42

Open
oschwald wants to merge 3 commits into
mainfrom
greg/stf-772-support-android-sdk-api-level-27-for-device-tracking
Open

Support Android API level 27 (STF-772)#42
oschwald wants to merge 3 commits into
mainfrom
greg/stf-772-support-android-sdk-api-level-27-for-device-tracking

Conversation

@oschwald

@oschwald oschwald commented Jun 20, 2026

Copy link
Copy Markdown
Member

Summary

Lowers the SDK's minSdk from 29 (Android 10) to 27 (Android 8.1) so the library installs on a wider device base. Requested in STF-772 — a payment-processor prospect blocked their evaluation on the lack of API-27 support (~7% of their customers on Android 8.1/9).

An audit of every Android framework call in device-sdk/src/main found only two call sites that use an API above 27, both API 28, and both have lossless fallbacks — no collected signal is lost on older devices, so nothing needed to be disabled:

  • InstallationInfoHelper — reads the deprecated int PackageInfo.versionCode when longVersionCode (API 28) is unavailable. On API 27 there is no versionCodeMajor, so the value is identical.
  • DeviceIDsCollector — releases MediaDrm via release() instead of close() (the AutoCloseable close() was added in API 28). The DRM ID is read before the finally, so only cleanup differs.

All other framework calls are ≤ API 24 or already guarded (refreshRate@30, hdrCapabilities@24, getInstallSourceInfo@30).

Changes

  • gradle/libs.versions.toml: minSdk 29 → 27 (single source of truth; moves both modules).
  • Two Build.VERSION.SDK_INT >= P guards with pre-28 fallbacks.
  • New API-27 Robolectric test classes exercising the legacy branches (pinned to @Config(sdk = [27]) since the JUnit 5 Robolectric extension only allows class-level @Config).
  • Docs: README requirement updated to "Android API 27+ (Android 8.1+)"; CHANGELOG entry under 0.3.0. Also corrected a stale Kotlin version in the README (1.9.22+2.2.21+), in its own commit.

Verification

  • ./gradlew :device-sdk:lintDebug — zero NewApi errors at minSdk 27 (the authoritative gate that nothing above 27 remains unguarded).
  • ./gradlew :device-sdk:test — all pass, including the new API-27 tests.
  • ./gradlew detekt ktlintCheck — clean.
  • ./gradlew :device-sdk:assemble — release AAR builds; merged manifest declares minSdkVersion="27" (no transitive dependency raises the floor).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Improvements

    • Expanded device compatibility by reducing the minimum supported Android API level from 29 to 27, allowing more devices to use the SDK
    • Updated minimum Kotlin version requirement to 2.2.21
  • Bug Fixes

    • Resolved an issue where logging configuration settings were not being correctly forwarded to data collection services, ensuring proper log output when enabled

oschwald and others added 3 commits June 20, 2026 13:44
Lower minSdk from 29 (Android 10) to 27 (Android 8.1) so the SDK installs
on a wider device base. Two framework calls require API 28 and now route
through lossless pre-28 fallbacks on older devices:

- InstallationInfoHelper: read the deprecated int versionCode when
  PackageInfo.longVersionCode is unavailable (< API 28).
- DeviceIDsCollector: release MediaDrm via release() instead of close()
  (the AutoCloseable close() was added in API 28).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pin new Robolectric test classes to @config(sdk = [27]) to exercise the
pre-API-28 branches added for API 27 support: the legacy int versionCode
read in InstallationInfoHelper, and the MediaDrm release()/collect path in
DeviceIDsCollector. The JUnit 5 Robolectric extension only allows @config
at the class level, so these live in separate classes from the sdk-29/30
tests that cover the modern branches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The README listed Kotlin 1.9.22+, but the project builds with Kotlin
2.2.21 (gradle/libs.versions.toml). Update the requirement to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0d894d01-ece8-4227-a78a-9362d9e36749

📥 Commits

Reviewing files that changed from the base of the PR and between 6905801 and 4301609.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • README.md
  • device-sdk/src/main/java/com/maxmind/device/collector/DeviceIDsCollector.kt
  • device-sdk/src/main/java/com/maxmind/device/collector/helper/InstallationInfoHelper.kt
  • device-sdk/src/test/java/com/maxmind/device/collector/DeviceIDsCollectorApi27RobolectricTest.kt
  • device-sdk/src/test/java/com/maxmind/device/collector/helper/InstallationInfoHelperApi27RobolectricTest.kt
  • gradle/libs.versions.toml

📝 Walkthrough

Walkthrough

The minimum supported Android API level is lowered from 29 to 27. DeviceIDsCollector and InstallationInfoHelper gain SDK-version-conditional branches to use deprecated pre-API-28 APIs on older devices. The Gradle minSdk config, README, and CHANGELOG are updated accordingly, and Robolectric tests pinned to SDK 27 cover the new legacy code paths.

Changes

Android API 27 compatibility

Layer / File(s) Summary
minSdk config and API 27 implementation branches
gradle/libs.versions.toml, device-sdk/src/main/java/com/maxmind/device/collector/DeviceIDsCollector.kt, device-sdk/src/main/java/com/maxmind/device/collector/helper/InstallationInfoHelper.kt, README.md, CHANGELOG.md
minSdk is lowered to 27; DeviceIDsCollector.collectMediaDrmID() calls close() on API 28+ and release() on older SDKs; InstallationInfoHelper.collect() reads longVersionCode on API 28+ and versionCode.toLong() below; README and CHANGELOG document the new minimum requirement and the enableLogging forwarding fix.
Robolectric tests for API 27 legacy branches
device-sdk/src/test/java/com/maxmind/device/collector/DeviceIDsCollectorApi27RobolectricTest.kt, device-sdk/src/test/java/com/maxmind/device/collector/helper/InstallationInfoHelperApi27RobolectricTest.kt
DeviceIDsCollectorApi27RobolectricTest asserts collect() returns a non-null result at SDK 27; InstallationInfoHelperApi27RobolectricTest stubs the deprecated versionCode int field to verify the legacy long conversion and confirms the legacy installer-resolution branch completes without throwing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 Hop hop, we've gone back in time,
From API 29 to 27 — sublime!
release() or close(), we check the SDK,
versionCode int? We handle that too, okay.
No signal is lost on this backwards leap,
The rabbit's been digging just a little more deep! 🕳️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Support Android API level 27 (STF-772)' directly and specifically summarizes the main change: lowering the minimum API level from 29 to 27 to support Android 8.1 devices.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch greg/stf-772-support-android-sdk-api-level-27-for-device-tracking

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request lowers the minimum supported Android API level from 29 to 27, introducing fallback mechanisms for retrieving the app version code and cleaning up MediaDrm on older API levels. Corresponding Robolectric tests have been added to verify these changes on API 27. The reviewer recommends reverting the Kotlin version update in the README as it is out of scope for this pull request.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread README.md
- Android API 29+ (Android 10+)
- Kotlin 1.9.22+
- Android API 27+ (Android 8.1+)
- Kotlin 2.2.21+

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This pull request includes an update to the Kotlin version in the README (Kotlin 1.9.22+ to Kotlin 2.2.21+). According to our general rules, we should avoid making out-of-scope edits to pre-existing content that is not the primary focus of the pull request. Please revert this change and address it in a separate PR or commit if necessary.

Suggested change
- Kotlin 2.2.21+
- Kotlin 1.9.22+
References
  1. Avoid making out-of-scope edits (such as wording or accessibility improvements) to pre-existing content that is not the primary focus of the pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant