altera2015 / usbserial

Flutter Android USB Serial plugin
BSD 3-Clause "New" or "Revised" License
119 stars 83 forks source link

Connection Failure with Android 13 Plugin #90

Closed dpkristensen closed 9 months ago

dpkristensen commented 10 months ago

Bug

I have run into an issue on Android 13 devices where it seems something is breaking when I try to connect. The permission dialog doesn't always come up, and if it came up previously and was cancelled it will just continue to break. I have traced it down to this line in the Android plugin:

PendingIntent permissionIntent = PendingIntent.getBroadcast(cw, 0, new Intent(ACTION_USB_PERMISSION), 0);

This results in a log message: D/CompatibilityChangeReporter( 6530): Compat change id reported: 160794467; UID 10332; state: ENABLED and it never makes it to the next line in the function.

It looks like Android 12 started requiring mutability in intents. See [https://developer.android.com/guide/components/intents-filters#CreateImmutablePendingIntents]. If you change the last argument from 0 to PendingIntent.FLAG_IMMUTABLE I believe it would at least not have that specific problem.

I can't figure out what happens on why the next line is not executed in that case. Maybe Android changed the compatibility setting and then reloaded the app, breaking the debug session? This is already happening in the exception handler for java.lang.SecurityException, so maybe it's a double exception?

On a higher level note about program flow, I don't get why the code is trying to open the port and then catch the security exception later; this results in a huge stack trace in the log that makes it look like something terrible happened. Why not call m_Context.checkSelfPermission(ACTION_USB_PERMISSION) and request permissions before calling the open?

It could be that it requires some API level checks if you're going to support really old versions of Android that don't have this API.

Additional context

My Phone is a OnePlus 8T, running Android 13 (API Level 33). On this phone the permission dialog isn't a simple checkbox to allow the app to use it, it brings up a box that says "Which app do you want to use for this device?". It's not intuitive, so I originally just backed out of it and then was unable to connect.

altera2015 commented 10 months ago

Thanks for the detailed bug report. I'd happily review a PR for this...

dpkristensen commented 10 months ago

I will try as I can, schedule/priorities permitting; but they are shifting atm.

I think if you were able to also add a new API to query/request permissions separately from the create API, then it wouldn't break any existing use case to do those things before connecting. I can't do that myself as it would require modifying all the supported plugins; that could also be considered a new feature.

dpkristensen commented 9 months ago

Sorry, I'm new to using Flutter / Dart; I'm working on a project initially created by someone else and did not see it was using an older version of this library (0.4.0). After updating to 0.5.1 it works now.

WRT my suggestion of program flow, you could also check for permission prior to opening, if you wanted:

import android.content.pm.PackageManager;
...
            if(PackageManager.PERMISSION_GRANTED != m_Context.checkSelfPermission(ACTION_USB_PERMISSION)) {
                acquirePermissions(device, cb);
            }
Rushi-Gandhi commented 6 months ago

Resolved the "Connection Failure with Android 13 Plugin" error by including the following in my pubspec.yaml file:

dependencies:
    usb_serial: ^0.5.1

This addition fixed the issue for me.