Skip to content

feat: add Android 17 (API 37) support (failed) - #182

Closed
pillownara wants to merge 2 commits into
parallelcc:mainfrom
pillownara:android-17-support
Closed

feat: add Android 17 (API 37) support (failed)#182
pillownara wants to merge 2 commits into
parallelcc:mainfrom
pillownara:android-17-support

Conversation

@pillownara

Copy link
Copy Markdown

Support for Android 17 (API 37) with reflection hardening

  • Update compileSdk and targetSdk to 37
  • Wrap R$string field reflection with try-catch for Android 17+ compatibility
  • Handle IllegalAccessException gracefully with -1 fallback

Tested on Android 17 (API 37)

… Android 17+ compatibility

Android 17 blocks reflection to static final fields. VIMSHooker and
CSMSHooker access config strings via reflection, which will throw
IllegalAccessException on Android 17+. Wrap with runCatching and
fallback to -1 if field access fails.

Fixes: Android 17 (API 37) compatibility issue
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add Android 17 support and harden resource reflection

✨ Enhancement 🐞 Bug fix ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Targets Android 17 by compiling against and targeting API 37.
• Prevents restricted internal resource reflection from aborting system-server hook initialization.
• Logs lookup failures and uses -1 sentinels to avoid accidental resource matches.
Diagram

graph TD
  Build["API 37 Build"] --> Hooks["System Hooks"] --> Lookup["Resource Lookup"] --> Result{"Lookup succeeds?"}
  Result -->|Yes| IDs["Resource IDs"] --> Runtime["Hook Matching"]
  Result -->|No| Fallback["Warn and -1"] --> Runtime
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Shared safe resource resolver
  • ➕ Centralizes fallback and warning behavior across hookers.
  • ➕ Reduces duplicated reflection handling and simplifies future field additions.
  • ➖ Adds an abstraction for only three current lookups.
  • ➖ Field-specific log messages still require contextual parameters.

Recommendation: Keep the localized runCatching approach for this small compatibility patch: it contains failures at each optional internal-resource lookup and the -1 sentinel cannot collide with valid positive resource IDs. Consider extracting a resolver only if more reflected resource fields are added.

Files changed (3) +22 / -5

Bug fix (2) +20 / -3
CSMSHooker.ktHarden contextual-search package resource lookup +8/-1

Harden contextual-search package resource lookup

• Wraps reflection of 'config_defaultContextualSearchPackageName' in failure handling. Reflection errors are logged and replaced with '-1', allowing CSMS hook initialization to continue on Android 17.

app/src/main/java/com/parallelc/micts/hooker/CSMSHooker.kt

VIMSHooker.ktHarden voice-interaction resource lookups +12/-2

Harden voice-interaction resource lookups

• Protects both contextual-search key and package-name field reads with warning logs and '-1' fallbacks. Restricted reflection no longer aborts VIMS hook setup on Android 17.

app/src/main/java/com/parallelc/micts/hooker/VIMSHooker.kt

Other (1) +2 / -2
build.gradle.ktsTarget Android 17 SDK +2/-2

Target Android 17 SDK

• Raises both 'compileSdk' and 'targetSdk' from API 36 to API 37 so the application builds for and opts into Android 17 behavior.

app/build.gradle.kts

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Fallback disables CSMS override 🐞 Bug ≡ Correctness
Description
When the resource-field lookup fails, CSMSHooker.hook stores -1 but still installs
DeviceHasConfigStringHooker, whose override only runs when the framework's resource ID equals that
sentinel. Real configuration-resource checks therefore proceed unchanged, so the CSMS availability
override is disabled on the reflection-failure path this change is intended to support.
Code

app/src/main/java/com/parallelc/micts/hooker/CSMSHooker.kt[29]

+            }.getOrElse { -1 }
Evidence
The changed failure branch assigns -1, after which hook registration proceeds unconditionally. The
interceptor only returns true for an argument equal to the stored value and delegates every real
nonmatching resource ID to the original implementation.

app/src/main/java/com/parallelc/micts/hooker/CSMSHooker.kt[25-33]
app/src/main/java/com/parallelc/micts/hooker/CSMSHooker.kt[58-65]
app/src/main/java/com/parallelc/micts/ModuleMain.kt[47-52]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new `-1` fallback allows setup to continue but prevents `DeviceHasConfigStringHooker` from recognizing the contextual-search package resource, disabling the CSMS override whenever reflection fails.

## Issue Context
Use an Android-17-compatible lookup (for example, a framework resource-name lookup or another verified reflection path) that produces the actual resource ID. Do not install the dependent behavior with a sentinel that can never match a real resource request.

## Fix Focus Areas
- app/src/main/java/com/parallelc/micts/hooker/CSMSHooker.kt[25-33]
- app/src/main/java/com/parallelc/micts/hooker/CSMSHooker.kt[58-65]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Fallback disables VIMS substitutions 🐞 Bug ≡ Correctness
Description
Each failed VIMS resource-field lookup is replaced with -1, yet GetStringHooker only substitutes
the contextual-search key or package when the requested resource ID equals those stored values.
Consequently, a failed lookup silently removes the corresponding key/package substitution and breaks
that contextual-search trigger path instead of providing Android 17 compatibility.
Code

app/src/main/java/com/parallelc/micts/hooker/VIMSHooker.kt[R33-39]

+            }.getOrElse { -1 }
+            
+            contextualSearchPackageName = runCatching {
+                rString.getField("config_defaultContextualSearchPackageName").getInt(null)
+            }.onFailure { e ->
+                module!!.log(Log.WARN, "MiCTS", "Failed to get config_defaultContextualSearchPackageName on Android 17+", e)
+            }.getOrElse { -1 }
Evidence
Both changed branches assign -1 on lookup failure and still register ShowSessionHooker. During
the trigger flow that hook installs GetStringHooker, whose only substitutions are equality
branches against the two stored IDs; a sentinel therefore causes normal resource requests to fall
through to the original method.

app/src/main/java/com/parallelc/micts/hooker/VIMSHooker.kt[29-40]
app/src/main/java/com/parallelc/micts/hooker/VIMSHooker.kt[43-63]
app/src/main/java/com/parallelc/micts/hooker/VIMSHooker.kt[67-78]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The `-1` fallbacks cannot match real `Resources.getString` IDs, so any failed lookup disables the corresponding VIMS contextual-search substitution while hook setup appears successful.

## Issue Context
Resolve both internal string IDs through an Android-17-compatible mechanism and only enable the dependent hook after obtaining valid IDs. Preserve independent handling if one ID can be resolved and the other cannot, but do not represent an operational substitution with `-1`.

## Fix Focus Areas
- app/src/main/java/com/parallelc/micts/hooker/VIMSHooker.kt[29-40]
- app/src/main/java/com/parallelc/micts/hooker/VIMSHooker.kt[67-78]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced: This changes runtime reflection behavior in two hook paths and raises compile/target SDK, creating compatibility and startup-risk that merits a careful single-pass review.

Grey Divider

Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

rString.getField("config_defaultContextualSearchPackageName").getInt(null)
}.onFailure { e ->
module!!.log(Log.WARN, "MiCTS", "Failed to get config_defaultContextualSearchPackageName on Android 17+", e)
}.getOrElse { -1 }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Fallback disables csms override 🐞 Bug ≡ Correctness

When the resource-field lookup fails, CSMSHooker.hook stores -1 but still installs
DeviceHasConfigStringHooker, whose override only runs when the framework's resource ID equals that
sentinel. Real configuration-resource checks therefore proceed unchanged, so the CSMS availability
override is disabled on the reflection-failure path this change is intended to support.
Agent Prompt
## Issue description
The new `-1` fallback allows setup to continue but prevents `DeviceHasConfigStringHooker` from recognizing the contextual-search package resource, disabling the CSMS override whenever reflection fails.

## Issue Context
Use an Android-17-compatible lookup (for example, a framework resource-name lookup or another verified reflection path) that produces the actual resource ID. Do not install the dependent behavior with a sentinel that can never match a real resource request.

## Fix Focus Areas
- app/src/main/java/com/parallelc/micts/hooker/CSMSHooker.kt[25-33]
- app/src/main/java/com/parallelc/micts/hooker/CSMSHooker.kt[58-65]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +33 to +39
}.getOrElse { -1 }

contextualSearchPackageName = runCatching {
rString.getField("config_defaultContextualSearchPackageName").getInt(null)
}.onFailure { e ->
module!!.log(Log.WARN, "MiCTS", "Failed to get config_defaultContextualSearchPackageName on Android 17+", e)
}.getOrElse { -1 }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Fallback disables vims substitutions 🐞 Bug ≡ Correctness

Each failed VIMS resource-field lookup is replaced with -1, yet GetStringHooker only substitutes
the contextual-search key or package when the requested resource ID equals those stored values.
Consequently, a failed lookup silently removes the corresponding key/package substitution and breaks
that contextual-search trigger path instead of providing Android 17 compatibility.
Agent Prompt
## Issue description
The `-1` fallbacks cannot match real `Resources.getString` IDs, so any failed lookup disables the corresponding VIMS contextual-search substitution while hook setup appears successful.

## Issue Context
Resolve both internal string IDs through an Android-17-compatible mechanism and only enable the dependent hook after obtaining valid IDs. Preserve independent handling if one ID can be resolved and the other cannot, but do not represent an operational substitution with `-1`.

## Fix Focus Areas
- app/src/main/java/com/parallelc/micts/hooker/VIMSHooker.kt[29-40]
- app/src/main/java/com/parallelc/micts/hooker/VIMSHooker.kt[67-78]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@pillownara pillownara changed the title feat: add Android 17 (API 37) support feat: add Android 17 (API 37) support (failed) Aug 28, 2026
@pillownara pillownara closed this Aug 28, 2026
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