ryanheise / audio_session

MIT License
107 stars 68 forks source link

Dependency causing an ANR in the Background #119

Open sumittiware opened 7 months ago

sumittiware commented 7 months ago

We are using the dependency to record the audio, we have noticed that it causing an ANR in the background with the following stack trace.

Dependency version : audio_session: ^0.1.13 Device : Redmi 9 Power Android version : 12 Flutter doctor :

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.5, on macOS 14.1.1 23B81 darwin-arm64, locale en-IN)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.0)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.84.2)
[✓] Connected device (2 available)
[✓] Network resources

Stacktrace

main (runnable):tid=1 systid=22413 
       at android.media.AudioDeviceInfo.getProductName(AudioDeviceInfo.java:415)
       at com.ryanheise.audio_session.AndroidAudioManager$Singleton.encodeAudioDevice(AndroidAudioManager.java:273)
       at com.ryanheise.audio_session.AndroidAudioManager$Singleton.encodeAudioDevices(AndroidAudioManager.java:265)
       at com.ryanheise.audio_session.AndroidAudioManager$Singleton.access$4300(AndroidAudioManager.java:251)
       at com.ryanheise.audio_session.AndroidAudioManager$Singleton$1.onAudioDevicesAdded(AndroidAudioManager.java:298)
       at android.media.AudioManager$NativeEventHandlerDelegate$1.handleMessage(AudioManager.java:7926)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:211)
       at android.os.Looper.loop(Looper.java:300)
       at android.app.ActivityThread.main(ActivityThread.java:8322)
       at java.lang.reflect.Method.invoke(Native method)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1038)

Couldn’t reproduce the issue locally as there was no Flutter/dart associated stacktrace.

ryanheise commented 7 months ago

Thank you for the report.

Without seeing the exception message, it's hard to know what is the cause of this. The getProductName method inside of the SDK looks like this:

    /**
     * @return The human-readable name of the audio device.
     */
    public CharSequence getProductName() {
        String portName = mPort.name();
        return (portName != null && portName.length() != 0) ? portName : android.os.Build.MODEL;
    }

I guess it could be a NullPointerException if mPort is null. It would be strange if this were null, though. Since I can't reproduce it, you would have to do some debugging on your end. For example, you could add a println in the code just before the call to device.getProductName() to print out device.getPort() and see if it is null. If that's the cause, I can fix it.

sumittiware commented 7 months ago

Thank you for the response! Since the issue is not reproducible in my end either, it is getting reported on our firebase-crashlytics dashboard, not sure if this will work, but will try this.

ryanheise commented 7 months ago

If you could get the exception message as well, that would be helpful.

Taking a second look, audio_session calls device.getId() first without crashing, and getId() should theoretically trigger the same NPE since it accesses a member of mPort. So that would suggest mPort is not the problem, although then I have no more clues on what the error is pointing to.

Aside from the error, I'm also suspicious that an error on this line could cause an ANR. One theory is that the cause of the ANR is elsewhere, then the app gets killed, and then this stack trace happens to just reveal what audio_session was doing at the time the app was killed, without that audio_session's activity itself being blocking in any way. That could also explain why there is no exception message.