Skip to content

Target Android 17 (API 37)#771

Open
JordanLongstaff wants to merge 7 commits into
mainfrom
android-17
Open

Target Android 17 (API 37)#771
JordanLongstaff wants to merge 7 commits into
mainfrom
android-17

Conversation

@JordanLongstaff
Copy link
Copy Markdown
Collaborator

@JordanLongstaff JordanLongstaff commented Apr 23, 2026

Summary by CodeRabbit

  • New Features

    • Centralized runtime permission handling with a multi-permission request flow; added local network permission and refined notification rationale prompts
  • Tests

    • Instrumented UI tests now run on Android API level 37
    • New unit tests for runtime permission info; updated permission dialog tests for improved robustness
  • Chores

    • Project SDK target updated to API 37
  • Localization

    • Added and renamed user-facing rationale strings for notification and local network permissions

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

Warning

Review limit reached

@JordanLongstaff, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 9 minutes and 13 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7d3e979c-2e6d-40b8-b2e8-4ed3027374cd

📥 Commits

Reviewing files that changed from the base of the PR and between 5e52ce4 and 7c7050d.

📒 Files selected for processing (1)
  • .github/workflows/instrumented-tests.yml
📝 Walkthrough

Walkthrough

Refactors runtime permission handling to a multi-permission request with a retry queue, centralizes permission metadata in a new enum, adds ACCESS_LOCAL_NETWORK and string resources for it, bumps target SDK to 37 and test matrix to API 37, and updates instrumented tests to use TestContext extension helpers.

Changes

Cohort / File(s) Summary
Build & CI
.github/workflows/instrumented-tests.yml, build.gradle.kts
Adds API level 37 to instrumented-test matrix and updates project sdkVersion extra from 36 → 37.
Runtime Permission Core
app/src/main/kotlin/artemis/agent/MainActivity.kt, app/src/main/kotlin/artemis/agent/RuntimePermissionInfo.kt
Implements multi-permission RequestMultiplePermissions flow with a retry/queue for rationale-eligible denials; introduces RuntimePermissionInfo enum (POST_NOTIFICATIONS, ACCESS_LOCAL_NETWORK) with permission string and rationale resource; startup now calls requestRuntimePermissions().
Manifest & Resources
app/src/main/AndroidManifest.xml, app/src/main/res/values-v33/strings.xml, app/src/main/res/values-v37/strings.xml
Adds ACCESS_LOCAL_NETWORK permission to manifest; renames permission_rationalenotification_rationale in v33 strings; adds local_network_rationale in v37 strings.
Instrumented Test helpers
app/src/androidTest/kotlin/artemis/agent/screens/MainScreen.kt
Refactors permission helper APIs from taking Device to TestContext<*> extensions; computes numPermissionDialogs from SDK (Tiramisu/Cinnamon Bun) and iterates dialog accept/deny accordingly; updates rationale verifier to accept a string resource argument.
Instrumented Tests
app/src/androidTest/kotlin/artemis/agent/MainActivityTest.kt, app/src/androidTest/kotlin/artemis/agent/PermissionRationaleTest.kt
Updates tests to call TestContext extension methods directly; adjusts permission-deny and rationale dialog assertion loops to match multi-dialog behavior.
Unit Tests
app/src/test/kotlin/artemis/agent/RuntimePermissionInfoTest.kt
Adds new Kotest spec validating each RuntimePermissionInfo entry for expected permission strings and rationale resource IDs.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant MA as MainActivity
    participant Sys as PermissionSystem
    participant Dialog as AlertDialog
    participant Settings

    User->>MA: App startup
    MA->>Sys: requestRuntimePermissions()
    Sys->>Sys: Determine permissions array<br/>based on SDK (POST_NOTIFICATIONS, ACCESS_LOCAL_NETWORK)
    Sys->>Sys: Launch RequestMultiplePermissions
    Sys-->>MA: Permission results

    alt Denied but rationale eligible
        MA->>Sys: shouldShowRequestPermissionRationale(permission)
        Sys-->>MA: true (enqueue permission)
        MA->>Dialog: Show rationale message for permission
        User->>Dialog: Chooses "No" or "Yes"
        alt User chooses "Yes"
            Dialog->>Sys: Trigger request for the queued permission
            Sys-->>MA: Result for re-request
        else User chooses "No"
            Dialog->>Settings: Option to open App Settings
        end
    else All permissions granted
        MA->>MA: Continue initialization
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Faster startup #718: Modifies MainActivity startup/permission initialization and overlaps the same permission-startup area affected by this PR.

Poem

🐰 I hopped through perms with a curious mind,
Queued the denials, no prompt left behind,
SDK thirty-seven—fresh morning delight,
Tests now hop in step, tidy and bright,
A tiny rabbit cheers: permissions aligned!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 'Target Android 17 (API 37)' accurately and directly describes the main objective of the pull request, which is updating the app to target Android 17 with API level 37.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch android-17

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link
Copy Markdown
Contributor

No dependency violations found. 👍

@JordanLongstaff
Copy link
Copy Markdown
Collaborator Author

JordanLongstaff commented Apr 23, 2026

LGTM

Generated by 🚫 Danger

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/androidTest/kotlin/artemis/agent/screens/MainScreen.kt (1)

85-94: ⚠️ Potential issue | 🟠 Major

assertPermissionRationaleDialogOpen hardcodes notification_rationale but the queue can surface other permissions' rationales.

On API 34+ (CINNAMON_BUN), MainActivity.requestRuntimePermissions requests both POST_NOTIFICATIONS and ACCESS_LOCAL_NETWORK. When both are denied, resentPermissionRequests queues both and the rationale dialog sequentially shows each permission's rationaleMessageR.string.notification_rationale for the first, R.string.local_network_rationale for the second (per RuntimePermissionInfo.ACCESS_LOCAL_NETWORK). Because PermissionRationaleTest.testPermissionDialog loops numPermissionDialogs times and calls this assertion each iteration, the 2nd iteration on API 34+ will fail matching notification_rationale against the actual local_network_rationale text.

🐛 Proposed fix: parameterize the expected rationale string
-    fun assertPermissionRationaleDialogOpen() {
+    fun assertPermissionRationaleDialogOpen(`@StringRes` messageRes: Int) {
         alertDialog {
             isCompletelyDisplayed()
             title.isRemoved()
-            message.isDisplayedWithText(R.string.notification_rationale)
+            message.isDisplayedWithText(messageRes)
             positiveButton.isDisplayedWithText(R.string.yes)
             negativeButton.isDisplayedWithText(R.string.no)
             neutralButton.isRemoved()
         }
     }

Then in PermissionRationaleTest.testPermissionDialog, iterate with the expected rationales in the same order the queue produces them (driven by RuntimePermissionInfo.entries filtered by SDK), e.g.:

val expectedRationales = buildList {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
        add(R.string.notification_rationale)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CINNAMON_BUN)
        add(R.string.local_network_rationale)
}
expectedRationales.forEach { messageRes ->
    step("Check for permission rationale dialog") {
        assertPermissionRationaleDialogOpen(messageRes)
    }
    withDialog()
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/androidTest/kotlin/artemis/agent/screens/MainScreen.kt` around lines
85 - 94, The current assertPermissionRationaleDialogOpen hardcodes
R.string.notification_rationale so it fails when other permission rationales
(e.g., R.string.local_network_rationale) are shown; modify the function
assertPermissionRationaleDialogOpen to accept an expected message resource id
parameter (e.g., messageRes: Int) and use that instead of the hardcoded
R.string.notification_rationale, and update
PermissionRationaleTest.testPermissionDialog to build and iterate an
expectedRationales list in the same order RuntimePermissionInfo.entries produces
(filtering by SDK version) and call
assertPermissionRationaleDialogOpen(messageRes) for each entry so each dialog
assertion matches the queued rationale text.
🧹 Nitpick comments (1)
app/src/test/kotlin/artemis/agent/RuntimePermissionInfoTest.kt (1)

10-26: Ordinal-indexed expectations are fragile; consider per-entry mapping.

Driving expectations via permissionNames[info.ordinal] / rationaleResIds[info.ordinal] silently breaks if entries are reordered or a new entry is inserted in the middle — the test will then assert the wrong pair without any visible change to this file. A Map<RuntimePermissionInfo, Pair<String, Int>> (or a list of triples fed into withData) keeps expectations co-located with the entry they describe.

♻️ Proposed refactor
-            val rationaleResIds =
-                intArrayOf(R.string.notification_rationale, R.string.local_network_rationale)
-            val permissionNames =
-                arrayOf(
-                    "android.permission.POST_NOTIFICATIONS",
-                    "android.permission.ACCESS_LOCAL_NETWORK",
-                )
-
-            withData(nameFn = { it.name }, RuntimePermissionInfo.entries) { info ->
-                it("Permission name") {
-                    info.permission shouldBeEqual permissionNames[info.ordinal]
-                }
-
-                it("Rationale message") {
-                    info.rationaleMessage shouldBeEqual rationaleResIds[info.ordinal]
-                }
-            }
+            val expected = mapOf(
+                RuntimePermissionInfo.POST_NOTIFICATIONS to
+                    ("android.permission.POST_NOTIFICATIONS" to R.string.notification_rationale),
+                RuntimePermissionInfo.ACCESS_LOCAL_NETWORK to
+                    ("android.permission.ACCESS_LOCAL_NETWORK" to R.string.local_network_rationale),
+            )
+
+            withData(nameFn = { it.name }, RuntimePermissionInfo.entries) { info ->
+                val (permissionName, rationaleResId) = expected.getValue(info)
+                it("Permission name") { info.permission shouldBeEqual permissionName }
+                it("Rationale message") { info.rationaleMessage shouldBeEqual rationaleResId }
+            }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/test/kotlin/artemis/agent/RuntimePermissionInfoTest.kt` around lines
10 - 26, The test currently uses ordinal-indexed arrays (permissionNames,
rationaleResIds) and compares via permissionNames[info.ordinal] and
rationaleResIds[info.ordinal], which breaks if RuntimePermissionInfo.entries
order changes; replace this with a per-entry mapping: create a
Map<RuntimePermissionInfo, Pair<String, Int>> (or list of triples) that maps
each RuntimePermissionInfo value to its expected permission string and rationale
res id, then iterate that map in the withData call (or feed the list into
withData) and assert info.permission equals the mapped string and
info.rationaleMessage equals the mapped res id, updating the assertions that
reference info.ordinal to use the lookup by key instead so expectations stay
co-located with each entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@build.gradle.kts`:
- Line 32: The project currently sets the SDK to 37 via set("sdkVersion", 37)
which makes both compile/target use API 37; change the target SDK to 36 for now
(keep compileSdk at 37 for testing) by updating the Gradle Kotlin DSL so the
compile SDK remains 37 (leave set("sdkVersion", 37) if that maps to compileSdk)
and explicitly set targetSdk (e.g., set("targetSdk", 36) or the existing
targetSdk property) to 36 until Android 17 is stable; if this repo uses a
different property name for targetSdk, change that property to 36 instead of 37.

---

Outside diff comments:
In `@app/src/androidTest/kotlin/artemis/agent/screens/MainScreen.kt`:
- Around line 85-94: The current assertPermissionRationaleDialogOpen hardcodes
R.string.notification_rationale so it fails when other permission rationales
(e.g., R.string.local_network_rationale) are shown; modify the function
assertPermissionRationaleDialogOpen to accept an expected message resource id
parameter (e.g., messageRes: Int) and use that instead of the hardcoded
R.string.notification_rationale, and update
PermissionRationaleTest.testPermissionDialog to build and iterate an
expectedRationales list in the same order RuntimePermissionInfo.entries produces
(filtering by SDK version) and call
assertPermissionRationaleDialogOpen(messageRes) for each entry so each dialog
assertion matches the queued rationale text.

---

Nitpick comments:
In `@app/src/test/kotlin/artemis/agent/RuntimePermissionInfoTest.kt`:
- Around line 10-26: The test currently uses ordinal-indexed arrays
(permissionNames, rationaleResIds) and compares via
permissionNames[info.ordinal] and rationaleResIds[info.ordinal], which breaks if
RuntimePermissionInfo.entries order changes; replace this with a per-entry
mapping: create a Map<RuntimePermissionInfo, Pair<String, Int>> (or list of
triples) that maps each RuntimePermissionInfo value to its expected permission
string and rationale res id, then iterate that map in the withData call (or feed
the list into withData) and assert info.permission equals the mapped string and
info.rationaleMessage equals the mapped res id, updating the assertions that
reference info.ordinal to use the lookup by key instead so expectations stay
co-located with each entry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d85332a6-4836-4dc7-b5a9-f5eb9175053e

📥 Commits

Reviewing files that changed from the base of the PR and between 3e9f305 and a2de820.

📒 Files selected for processing (11)
  • .github/workflows/instrumented-tests.yml
  • app/src/androidTest/kotlin/artemis/agent/MainActivityTest.kt
  • app/src/androidTest/kotlin/artemis/agent/PermissionRationaleTest.kt
  • app/src/androidTest/kotlin/artemis/agent/screens/MainScreen.kt
  • app/src/main/AndroidManifest.xml
  • app/src/main/kotlin/artemis/agent/MainActivity.kt
  • app/src/main/kotlin/artemis/agent/RuntimePermissionInfo.kt
  • app/src/main/res/values-v33/strings.xml
  • app/src/main/res/values-v37/strings.xml
  • app/src/test/kotlin/artemis/agent/RuntimePermissionInfoTest.kt
  • build.gradle.kts

Comment thread build.gradle.kts

extra.apply {
set("sdkVersion", 36)
set("sdkVersion", 37)
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 23, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's locate and examine the build.gradle.kts file
fd -n "build\.gradle\.kts" | head -5

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 309


🏁 Script executed:

# Let's look at the content around line 32 to understand the full context
head -n 50 build.gradle.kts | tail -n 25

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 644


🏁 Script executed:

# Search for all SDK-related configurations
rg "sdkVersion|compileSdk|targetSdk" build.gradle.kts -A 2 -B 2

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 188


🏁 Script executed:

# Search for compileSdk and targetSdk usage across the project
rg "compileSdk|targetSdk" -t gradle -t kotlin

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 236


🏁 Script executed:

# Look for AGP version and Build-Tools
rg "com\.android\.tools\.build:gradle|buildToolsVersion|androidGradlePlugin" -t gradle -t kotlin

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 61


🏁 Script executed:

# Check the gradle wrapper and libs.versions.toml if available
find . -name "gradle-wrapper.properties" -o -name "libs.versions.toml" | head -5

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 149


🏁 Script executed:

# Check libs.versions.toml for AGP version
cat gradle/libs.versions.toml | head -50

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 1310


🏁 Script executed:

# Look at app/build.gradle.kts to see full Android configuration
head -n 100 app/build.gradle.kts | grep -A 10 -B 5 "android\|compileSdk\|targetSdk\|buildToolsVersion"

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 1756


🏁 Script executed:

# Search more thoroughly for AGP version in libs.versions.toml
cat gradle/libs.versions.toml | grep -i "android\|agp"

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 4097


🏁 Script executed:

# Also check if there's a plugins section in libs.versions.toml
cat gradle/libs.versions.toml | grep -A 30 "\[plugins\]"

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 1075


🏁 Script executed:

# Check the gradle wrapper version
cat gradle/wrapper/gradle-wrapper.properties

Repository: JPL-Software-Solutions/ArtemisAgent

Length of output: 417


Consider deferring targetSdk to 36 until Android 17 reaches stable release.

Both compileSdk and targetSdk are set to API level 37 (Android 17/Cinnamon Bun). As of April 2026, Android 17 has not yet reached stable release (scheduled for June 2026, currently Beta 4), meaning your app will opt into pre-release behavior changes that may still shift, including the lock-free MessageQueue for apps targeting SDK 37+ (potentially breaking reflective clients) and removal of the developer opt-out for orientation/resizability restrictions on large screens (sw > 600 dp).

AGP 9.2.0 supports API 37 compilation, so there are no build-tool compatibility blockers. However, if stable release is not required for this build, consider keeping compileSdk=37 with targetSdk=36 until Android 17 stabilizes in June.

If targeting API 37 pre-release is intentional (e.g., pre-release testing branch), this can be ignored.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@build.gradle.kts` at line 32, The project currently sets the SDK to 37 via
set("sdkVersion", 37) which makes both compile/target use API 37; change the
target SDK to 36 for now (keep compileSdk at 37 for testing) by updating the
Gradle Kotlin DSL so the compile SDK remains 37 (leave set("sdkVersion", 37) if
that maps to compileSdk) and explicitly set targetSdk (e.g., set("targetSdk",
36) or the existing targetSdk property) to 36 until Android 17 is stable; if
this repo uses a different property name for targetSdk, change that property to
36 instead of 37.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I did want to be an early bird on letting this project adopt Android 17's API. My only regret is that the stable emulator images have not been released yet. Until that happens, the instrumented tests will not pass.

I don't see MessageQueue behaviour as a concern because, AFAIK, my app does not use it anywhere. AFAICT, the only major change that my app needs to account for is the local network permission.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@JordanLongstaff, that makes perfect sense — thank you for the context. A few things worth noting that support your approach:

  • Android 17 has officially reached Platform Stability with Beta 3, meaning the API surface is now locked — so there's no risk of APIs still shifting under you.
  • Beta 4 is the final scheduled beta of the release cycle, and the API surface is confirmed final, meaning no major new features are expected before the stable rollout.
  • The stable release is expected in June 2026, timed around Google I/O (scheduled for May 20, 2026) — so stable emulator images should arrive soon.
  • Regarding MessageQueue: the new lock-free implementation only affects clients that reflect on MessageQueue private fields and methods, so if your app doesn't do that, it's a non-issue as you've assessed.

Your early adoption approach is completely reasonable here, especially given that Platform Stability is already declared. I'll withdraw my concern.

(ᵔ◡ᵔ)🐇


✏️ Learnings added
Learnt from: JordanLongstaff
Repo: JPL-Software-Solutions/ArtemisAgent PR: 771
File: build.gradle.kts:32-32
Timestamp: 2026-05-18T02:56:07.819Z
Learning: The ArtemisAgent project (JPL-Software-Solutions/ArtemisAgent) intentionally targets the latest Android SDK version, even pre-stable (e.g., API 37 / Android 17), for early adoption purposes. Do not flag targeting a pre-release SDK version as a concern in this project when it has reached Platform Stability (API surface locked). The author is aware of the trade-off that instrumented tests may not pass until stable emulator images are released.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: JordanLongstaff
Repo: JPL-Software-Solutions/ArtemisAgent PR: 762
File: app/build.gradle.kts:120-122
Timestamp: 2026-04-21T10:57:28.416Z
Learning: When reviewing Android projects using the Android Gradle Plugin (AGP), recognize that local JVM unit test tasks are generated per build variant with the naming convention `test<VariantName>UnitTest` (for example, `testDebugUnitTest`, `testReleaseUnitTest`). If a PR references a task name matching this pattern, do not flag it as invalid or non-existent solely due to the name.

Learnt from: JordanLongstaff
Repo: JPL-Software-Solutions/ArtemisAgent PR: 762
File: app/build.gradle.kts:120-122
Timestamp: 2026-04-21T12:14:21.084Z
Learning: For Android projects using Android Gradle Plugin (AGP) 9+, do not assume a `release`-variant local JVM unit test task (e.g., `testReleaseUnitTest`) will be generated. Only the `debug` unit test task (e.g., `testDebugUnitTest`) is created by default. If you need unit tests (including any konsist/unit-test integration) to always run before `assemble*` tasks across variants, wire the relevant `assemble` tasks to depend on `:app:<test-task>` (specifically `testDebugUnitTest` in AGP 9) rather than hardcoding per-variant test task names that may not exist for `release`. Ensure the dependency targets the actual generated task and matches AGP 9 task naming/creation behavior.

Learnt from: JordanLongstaff
Repo: JPL-Software-Solutions/ArtemisAgent PR: 775
File: gradle/libs.versions.toml:254-255
Timestamp: 2026-04-25T22:22:05.582Z
Learning: In ArtemisAgent modules that apply the `io.kotzilla.kotzilla-plugin`, the plugin will auto-add `kotzilla-sdk` but will not auto-add `kotzilla-core`. Always declare `kotzilla-core` explicitly in that module’s dependencies. If a module omits `kotzilla-core`, the Dependency Analysis Gradle plugin will fail (so this should be treated as a review-blocking misconfiguration).

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage (IAN/enums)

Total Project Coverage 100.00%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 7c7050d.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage (IAN/udp)

Total Project Coverage 100.00%

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage (IAN/util)

Total Project Coverage 100.00%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Code Coverage (IAN)

Total Project Coverage 98.30%

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage (IAN/grid)

Total Project Coverage 100.00%

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage (IAN/world)

Total Project Coverage 99.45%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Code Coverage (IAN/packets)

Total Project Coverage 99.67%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Code Coverage (app)

File Coverage [1.27%]
app/src/main/kotlin/artemis/agent/MainActivity.kt 0.00%
app/src/main/kotlin/artemis/agent/RuntimePermissionInfo.kt 100.00%
Total Project Coverage 21.20%

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage (IAN/vesseldata)

Total Project Coverage 98.91%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Unit Test Results

  128 files    128 suites   17m 26s ⏱️
1 597 tests 1 597 ✅ 0 💤 0 ❌
3 343 runs  3 343 ✅ 0 💤 0 ❌

Results for commit 7c7050d.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Konsist Test Results

 14 files   14 suites   45s ⏱️
150 tests 150 ✅ 0 💤 0 ❌
533 runs  533 ✅ 0 💤 0 ❌

Results for commit 7c7050d.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage (IAN/listener)

Total Project Coverage 100.00%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Total Code Coverage

File Coverage [1.27%]
app/src/main/kotlin/artemis/agent/MainActivity.kt 0.00%
app/src/main/kotlin/artemis/agent/RuntimePermissionInfo.kt 100.00%
Total Project Coverage 33.33%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Instrumented Test Results

  7 files  104 suites   37m 7s ⏱️
 41 tests  40 ✅ 0 💤 1 ❌
237 runs  236 ✅ 0 💤 1 ❌

For more details on these failures, see this check.

Results for commit 7c7050d.

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/src/androidTest/kotlin/artemis/agent/PermissionRationaleTest.kt (1)

46-49: Consider deriving rationaleMessages from RuntimePermissionInfo to avoid duplication.

The array hardcodes the same rationaleMessage IDs already declared on each RuntimePermissionInfo entry, and its positional indexing relies on the implicit assumption that the enum's API-gating order (TIRAMISU → CINNAMON_BUN) matches numPermissionDialogs's iteration. If a future permission is inserted between these API levels, the index alignment in the loop at lines 59–62 will silently use the wrong rationale. Sourcing the list from the enum (filtered by Build.VERSION.SDK_INT) keeps the test in lockstep with production metadata.

♻️ Suggested approach
-        val rationaleMessages = intArrayOf(
-            R.string.notification_rationale,
-            R.string.local_network_rationale,
-        )
+        val rationaleMessages: IntArray =
+            RuntimePermissionInfo.entries
+                .filter { Build.VERSION.SDK_INT >= /* min API per entry */ }
+                .map { it.rationaleMessage }
+                .toIntArray()

(Exposing the min API on RuntimePermissionInfo — or a helper like RuntimePermissionInfo.applicableEntries() — would make this clean.)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/androidTest/kotlin/artemis/agent/PermissionRationaleTest.kt` around
lines 46 - 49, The test hardcodes rationaleMessages which duplicates IDs from
RuntimePermissionInfo and relies on positional order; instead derive the
expected rationale IDs from RuntimePermissionInfo (filtering entries by
Build.VERSION.SDK_INT or using a helper like
RuntimePermissionInfo.applicableEntries()) and use that list when asserting
against numPermissionDialogs in the loop, so replace the hardcoded
rationaleMessages with a computed array sourced from RuntimePermissionInfo to
keep the test aligned with production metadata.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/src/androidTest/kotlin/artemis/agent/PermissionRationaleTest.kt`:
- Around line 46-49: The test hardcodes rationaleMessages which duplicates IDs
from RuntimePermissionInfo and relies on positional order; instead derive the
expected rationale IDs from RuntimePermissionInfo (filtering entries by
Build.VERSION.SDK_INT or using a helper like
RuntimePermissionInfo.applicableEntries()) and use that list when asserting
against numPermissionDialogs in the loop, so replace the hardcoded
rationaleMessages with a computed array sourced from RuntimePermissionInfo to
keep the test aligned with production metadata.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b1e2018f-82c3-4fa1-90b7-962c6f02be3d

📥 Commits

Reviewing files that changed from the base of the PR and between a2de820 and 7b8790a.

📒 Files selected for processing (4)
  • .github/workflows/instrumented-tests.yml
  • app/src/androidTest/kotlin/artemis/agent/PermissionRationaleTest.kt
  • app/src/androidTest/kotlin/artemis/agent/screens/MainScreen.kt
  • app/src/test/kotlin/artemis/agent/RuntimePermissionInfoTest.kt
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/src/test/kotlin/artemis/agent/RuntimePermissionInfoTest.kt
  • .github/workflows/instrumented-tests.yml
  • app/src/androidTest/kotlin/artemis/agent/screens/MainScreen.kt

@JordanLongstaff JordanLongstaff mentioned this pull request May 18, 2026
6 tasks
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant