fix(aprs): the service could not start at all on Android 10 and later
The previous commit changed the manifest's foregroundServiceType to location and left
startForeground passing FOREGROUND_SERVICE_TYPE_DATA_SYNC. AOSP requires the passed
type to be a subset of the declared one - location is 0x08, dataSync is 0x01 - and
throws IllegalArgumentException otherwise, a check that has been there since API 29.
That throw landed in the surrounding catch, which calls stopSelf().
So APRS started, died, and said nothing. No notification, no beacon, no Toast, no
last-report row, and the settings switch stayed on because the config had already been
saved. This is worse than the defect the rewrite was written to fix: reporting success
for packets that never left at least sometimes worked, whereas this never ran at all,
on essentially every device in use, with no visible symptom. Two auditors found it
independently by reading the constants against AOSP's own check.
Two more findings from the same review.
Receive-only was reported as a wrong passcode. Both a deliberate -1 and a mismatched
entry log in with -1, and the server answers "unverified" to each, so the operator who
chose receive-only - the one way to test a setup without putting anything on the network
- was told to go and fix the passcode they had set on purpose. The report now carries
whether receive-only was asked for, and says so instead.
The card could show "failed - sent". The detail string was the write's own verdict, and
a write that succeeds on a refused login is exactly the case where those two disagree.
A failure now reports what actually failed.
Also: the packet is built before connecting. The reporter used to open a session and log
in only to discover it had nothing to send, which for an operator with no station
position set meant a pointless login every five minutes.
Still outstanding, and the reason this is not enough on its own: nothing tests the
service, so neither this defect nor the missing line terminator in 7ac54f0a could have
been caught by the suite. Both were found by audit. A location-typed foreground service
on API 34+ may also require a granted location permission before startForeground, which
the settings card does not request - that needs checking on hardware.
This commit is contained in:
1 parent
e0900778f0
commit
0a67f74369
7 files changed
+62
-16
No files matched your search
@@ -120,6 +120,11 @@ class AprsForegroundService : Service() {
|
||||
// problem is the passcode - and APRS-IS is dropping every packet meanwhile.
|
||||
val msg = when {
|
||||
report.ok -> getString(R.string.aprs_toast_ok)
|
||||
// Receive-only first: it logs in with -1 exactly as a wrong passcode does and
|
||||
// the server answers "unverified" to both, so without this branch the one safe
|
||||
// way to test a setup reported itself as a configuration error.
|
||||
!report.verified && report.receiveOnly ->
|
||||
getString(R.string.aprs_toast_receive_only)
|
||||
!report.verified -> getString(R.string.aprs_toast_unverified)
|
||||
else -> getString(R.string.aprs_toast_fail, report.detail)
|
||||
}
|
||||
@@ -147,7 +152,13 @@ class AprsForegroundService : Service() {
|
||||
try {
|
||||
val notif = buildNotification(cfg)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
startForeground(NOTIF_ID, notif, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
|
||||
// Must match the manifest attribute or the platform refuses the call: AOSP checks the
|
||||
// passed type is a subset of the declared one, and location (0x08) does not contain
|
||||
// dataSync (0x01). Changing the manifest without changing this line stopped the
|
||||
// service dead on Android 10 and later - the IllegalArgumentException was caught
|
||||
// below and turned into stopSelf(), so APRS did nothing and reported nothing while
|
||||
// the settings switch stayed on.
|
||||
startForeground(NOTIF_ID, notif, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION)
|
||||
} else {
|
||||
startForeground(NOTIF_ID, notif)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user