Repository navigation
android: drop AppCompat and Material (#55, step B) - #58
Conversation
PR Summary by QodoAndroid: replace AppCompat and Material with platform components
AI Description
Diagram
High-Level Assessment
Files changed (10)
|
Code Review by Qodo
1. Settings crash on older Android
|
| registerReceiver(exitReceiver, new IntentFilter(TunnelService.ACTION_EXITED), | ||
| TunnelService.PERMISSION_INTERNAL, null, RECEIVER_NOT_EXPORTED); |
There was a problem hiding this comment.
1. Settings crash on older android 📎 Requirement gap ☼ Reliability
MainActivity.onCreate() unconditionally calls the five-argument registerReceiver overload, which is available only on API 33 and newer. On supported Android 8–12 devices (API 26–32), launching the activity reaches that unavailable method before the main screen, settings, or VPN controls are usable.
Agent Prompt
## Issue description
`MainActivity` uses an API-33-only receiver-registration overload during launcher activity startup, so supported Android 8–12 devices cannot open the main screen.
## Fix Focus Areas
- android/app/src/main/java/org/openipc/camex/MainActivity.java[57-61]
- android/app/build.gradle.kts[12-14]
## Recommended Fix
Guard receiver registration with an API 33 check. On API 33 and newer, use the five-argument `registerReceiver` overload with `RECEIVER_NOT_EXPORTED`; on older supported versions, use the four-argument overload with `TunnelService.PERMISSION_INTERNAL` so the receiver remains protected by the signature permission.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
Thanks, @qodo. On Settings crash on older Android: the call is registerReceiver(exitReceiver, filter, TunnelService.PERMISSION_INTERNAL, null, RECEIVER_NOT_EXPORTED);that is |
Your API-level analysis is correct. |
The app used AppCompat for its activity and theme and Material only for the settings bottom sheet; together they were most of classes.dex and resources.arsc. - MainActivity extends Activity; the theme is the platform Material one, light with a dark action bar, dark in night mode (as DayNight). - Settings are a SettingsActivity with EditText, RadioGroup, Switch and a "Show the key" check box instead of the bottom sheet; same fields, preference keys and validation. Typed values survive a rotation. - TunnelService calls startForeground() itself: with the type on Android 14+, where systemExempted exists, without it before. - The ACTION_EXITED receiver is registered with the not-exported flag and, for Android 8-12, a signature permission of the app, as ContextCompat.registerReceiver did. - Only androidx.annotation is left (@keep for the native callback). Release APK built locally: 1967120 -> 513198 bytes (v3.0.1: 2509592).
797bef8 to
dd9f9d2
Compare
The main screen and the settings screen after dropping AppCompat and Material; taken with the CI release APK of dd9f9d2.
|
Retargeted to master and rebased on it (dd9f9d2, CI run 39052899407 green). Device test on the Android 10 TV box (OpenIPC lab) with the CI build:
|
Step B of #55, stacked on #57 (step A). Fixes #55 together with #57.
What changes
MainActivityextendsActivity. Theme:android:Theme.Material.Light.DarkActionBar, andandroid:Theme.Materialinvalues-night, the platform equivalent of the old DayNight theme.SettingsActivity:EditTextfields with labels, aRadioGroupfor UDP/TCP, aSwitchfor the full tunnel, and a "Show the key" check box instead of the password toggle. The fields, preference keys and validation are the same; typed values survive a rotation (the views keep their state; the saved settings are loaded only on the first start).TunnelService:startForeground(id, notification, FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED)on Android 14+ (the type exists only there); before that, the two-argument form, which takes the type from the manifest. This replacesServiceCompat.ACTION_EXITEDreceiver:registerReceiver(..., permission, null, RECEIVER_NOT_EXPORTED)(API 26+). Android 13+ honours the flag; on 8–12 a new signature permissionorg.openipc.camex.permission.INTERNALkeeps other apps out, which is whatContextCompat.registerReceiverdid.androidx.annotationis left (@Keepon the method the native code calls).Result (release APK built locally in the compot/android container)
Almost all of what is left is the two
libcamex.so(333 KB) and the launcher icons.gradle lintreports no new errors. The one error left,ForegroundServicePermissionon the<service>element, was there before.Still to do
tests/android/device-test.sh) with the CI debug APK, plus a manual check that the settings screen saves and restores every field.docs/images/android-settings*.png).