ge0rg / aprsdroid

APRSdroid - Geo-Location for Radio Amateurs
https://aprsdroid.org/
GNU General Public License v2.0
504 stars 96 forks source link

Pull initial Digirig support #382

Open bxlentpartyon opened 1 month ago

bxlentpartyon commented 1 month ago

Pull Digirig support into master.

penguin359 commented 1 month ago

While testing a build of this PR, I am getting an immediate crash when I try to "Start Tracking" after enabling DigiRig in the settings. I have not had a chance to dig deeper yet:

08-03 01:45:12.579 31590 31590 D APRSdroid.Service: onStartCommand: Intent { act=org.aprsdroid.app.SERVICE
cmp=org.aprsdroid.app/.AprsService }, 0, 1
08-03 01:45:12.593 31590 31590 D APRSdroid.Service: addPost: null - APRS Service started: SmartBeaconingΓäó Position,
Audio (AFSK), Digirig.
08-03 01:45:12.610 31590 31590 E AndroidRuntime: Process: org.aprsdroid.app, PID: 31590
08-03 01:45:12.610 31590 31590 E AndroidRuntime: java.lang.RuntimeException: Unable to start service
org.aprsdroid.app.AprsService@60daa5c with Intent { act=org.aprsdroid.app.SERVICE cmp=org.aprsdroid.app/.AprsService
}: java.lang.IllegalArgumentException: org.aprsdroid.app: Targeting S+ (version 31 and above) requires that one of
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
08-03 01:45:12.610 31590 31590 E AndroidRuntime: Caused by: java.lang.IllegalArgumentException: org.aprsdroid.app:
Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a
PendingIntent.
08-03 01:45:12.610 31590 31590 E AndroidRuntime:        at org.aprsdroid.app.DigiRig.<init>(DigiRig.scala:60)
08-03 01:45:12.610 31590 31590 E AndroidRuntime:        at
org.aprsdroid.app.AprsBackend$$anonfun$8.apply(AprsBackend.scala:102)
08-03 01:45:12.610 31590 31590 E AndroidRuntime:        at
org.aprsdroid.app.AprsBackend$$anonfun$8.apply(AprsBackend.scala:102)
08-03 01:45:12.610 31590 31590 E AndroidRuntime:        at
org.aprsdroid.app.AprsBackend$.instanciateUploader(AprsBackend.scala:170)
08-03 01:45:12.610 31590 31590 E AndroidRuntime:        at org.aprsdroid.app.AprsService.startPoster(AprsService.scala:175)
08-03 01:45:12.610 31590 31590 E AndroidRuntime:        at org.aprsdroid.app.AprsService.handleStart(AprsService.scala:164)
08-03 01:45:12.610 31590 31590 E AndroidRuntime:        at org.aprsdroid.app.AprsService.onStartCommand(AprsService.scala:96)
penguin359 commented 1 month ago

OK, well, I was able to bypass that crash by adding a PendingIntent.FLAG_IMMUTABLE to the PendingIntent(), but now it is crashing further down while requesting permissions. I did see the pop-up asking me to grant permission to access the AIOC adapter I have attached:

08-03 02:04:03.286  4903  4903 D APRSdroid.Storage: open(): instanciating StorageDatabase
08-03 02:04:03.305  4903  4903 D APRSdroid.Service: addPost: null - APRS Service started: SmartBeaconingΓäó Position,
Audio (AFSK), Digirig.
08-03 02:04:03.321  4903  4903 D APRSdroid.Digirig: Digirig.requestPermissions
08-03 02:04:03.325  4903  4903 I APRSdroid.Digirig: Found USB device 1209:7388, requesting permissions.
08-03 02:04:03.326  4903  4927 D APRSdroid.AfskDemod: running...
08-03 02:04:03.330  4903  4903 D APRSdroid.Digirig: onReceive: Intent { act=org.aprsdroid.app.DigiRig.PERM flg=0x10 }
08-03 02:04:03.334  4903  4903 E AndroidRuntime: Process: org.aprsdroid.app, PID: 4903
08-03 02:04:03.334  4903  4903 E AndroidRuntime: java.lang.RuntimeException: Error receiving broadcast Intent {
act=org.aprsdroid.app.DigiRig.PERM flg=0x10 } in org.aprsdroid.app.DigiRig$$anon$1@631ed9e
08-03 02:04:03.334  4903  4903 E AndroidRuntime:        at org.aprsdroid.app.DigiRig$$anon$1.onReceive(DigiRig.scala:81)
bxlentpartyon commented 1 month ago

It sounds like you might not be testing with a Digirig?

Please let me know if I'm wrong about that, and I'll definitely look into it. However, if your issues are with different hardware, I think they should be considered a separate effort from this PR.

penguin359 commented 1 month ago

You are correct that I am not using a DigiRig for my testing. I am trying to get it to work with AIOC, however the two crashes I posted don't seem to have anything to do with the hardware, but with how PendingIntents are handles on newer Android API levels. What version of Android did you develop this under?

I am using a Pixel 7 Pro with Android 13 (API Level 33). Can you try this under the Android Emulator with API level 13? You will need to set up USB passthrough which seems possible, but I haven't done it before myself.

penguin359 commented 1 month ago

OK, I finally understand what the crash is. The fix is merely that you need to pass a flag in when creating the PendingIntent for the broadcast receiver. The fourth argument can no longer just be zero as of API level 31. This is due to a security change in the Android 12 (API level 31) where they made the default to be immutable and added a flag for selecting it explicitly to be mutable rather than immutable. My mistake in trying to fix the first crash is that I set the flag to be immutable which doesn't work in this situation leading to the second crash I posted above.

To sum up, please add PendingIntent.FLAG_MUTABLE to the flags (4th argument) of PendingIntent.getBroadcast() and that will prevent a hard crash on Android 12 and newer. Then, also verify that Android 11 and older still works.

You can read more about that here: PendingIntent.FLAG_MUTABLE

bxlentpartyon commented 1 month ago

I'll test this on my device, but I'd still argue that building for a different Android target than the official release is outside the scope of the work that I'm doing here. I specifically set up my environment to build exactly like the production version so that I didn't have to fight with issues that don't exist in production.

penguin359 commented 1 month ago

I am a little confused at to what you are referring to. I am building the for the official SDK target that the upstream APRSdroid is targeted for. The targetSdkVersion in build.gradle is API level 33 which means it must follow all requirements of that API version. The specific crash I was hitting is documented in the officlal Android documentation under PendingIntent.FLAG_MUTABLE. This issue has nothing to do with the DigiRig hardware support itself, but how PendingIntent needs to be used with a BroadcastReceiver. Here is the crash as I hit it describing the issue:

08-03 01:45:12.610 31590 31590 E AndroidRuntime: java.lang.RuntimeException: Unable to start service
org.aprsdroid.app.AprsService@60daa5c with Intent { act=org.aprsdroid.app.SERVICE cmp=org.aprsdroid.app/.AprsService
}: java.lang.IllegalArgumentException: org.aprsdroid.app: Targeting S+ (version 31 and above) requires that one of
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
08-03 01:45:12.610 31590 31590 E AndroidRuntime: Caused by: java.lang.IllegalArgumentException: org.aprsdroid.app:
Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a
PendingIntent.
08-03 01:45:12.610 31590 31590 E AndroidRuntime:        at org.aprsdroid.app.DigiRig.<init>(DigiRig.scala:60)

What Android version are you testing under? This crash will only be seen under Android 12 (API level 31) and newer. If you are testing under an older Android release, you won't see any crash and this patch shouldn't change any behavior, although I haven't been able to test it yet under older Android.

penguin359 commented 1 month ago

I apologize if I've confused things by bringing up the AIOC board, but my recent comments related to the crash I am seeing are not specific to that board. I've sent you a PR with the fix I am talking about in bxlentpartyon/aprsdroid#1 and I expect it to be a simple patch to review. This issue should also affect the DigiRig on newer Android versions.

I am also trying to expand your code to support the AIOC board that I have, but that is above and beyond what is in your PR and I am not expecting you to have to do anything. Once I can get this board also working, I'll create a PR to send to either you or @ge0rg, if your PR is approved and merged in by that time. This is great progress you have made and I am pleased to help beta test the code on my set-up!

bxlentpartyon commented 1 month ago

I got myself confused looking at the error that you hit here - I'm now understanding that this is an actual issue with my branch, just not one that I'm hitting, because I'm using a pretty old device. I will pick your commit on top of my branch so that it gets included with this PR, since I do believe that it probably belongs with it.

Apologies for the confusion here!

bxlentpartyon commented 1 month ago

Branch has been updated - I'm still doing some testing, but, as you mentioned, the patch is pretty simple, so I'm not concerned that pulling it in is going to have unintended side-effects.

Thanks for the additional improvement here!

skteagle commented 1 day ago

Any update on this? I just found this branch and seems like this is exactly the problem I am facing on my Alinco DR-735T and Digirig trying to run on my Samsung A9+.