1cb93a386Sopenharmony_ci[Oboe Docs Home](README.md) 2cb93a386Sopenharmony_ci 3cb93a386Sopenharmony_ci# Tech Note: Disconnected Streams and Plugin Issues 4cb93a386Sopenharmony_ci 5cb93a386Sopenharmony_ciWhen Oboe is using **OpenSL ES**, and a headset is plugged in or out, then OpenSL ES will automatically switch between devices. 6cb93a386Sopenharmony_ciThis is convenient but can cause problems because the new device may have different burst sizes and different latency. 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ciWhen Oboe is using **AAudio**, and a headset is plugged in or out, then 9cb93a386Sopenharmony_cithe stream is no longer available and becomes "disconnected". 10cb93a386Sopenharmony_ciThe app should then be notified in one of two ways. 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci1) If the app is using a callback then the AudioStreamCallback object will be called. 13cb93a386Sopenharmony_ciIt will launch a thread, which will call onErrorBeforeClose(). 14cb93a386Sopenharmony_ciThen it stops and closes the stream. 15cb93a386Sopenharmony_ciThen onErrorAfterClose() will be called. 16cb93a386Sopenharmony_ciAn app may choose to reopen a stream in the onErrorAfterClose() method. 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci2) If an app is using read()/write() calls then they will return an error when a disconnect occurs. 19cb93a386Sopenharmony_ciThe app should then stop() and close() the stream. 20cb93a386Sopenharmony_ciAn app may then choose to reopen a stream. 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci## Workaround for not Disconnecting Properly 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ciOn some versions of Android P the disconnect message does not reach AAudio and the app will not 25cb93a386Sopenharmony_ciknow that the device has changed. There is a "Test Disconnects" option in 26cb93a386Sopenharmony_ci[OboeTester](https://github.com/google/oboe/tree/master/apps/OboeTester/docs) 27cb93a386Sopenharmony_cithat can be used to diagnose this problem. 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ciAs a workaround you can listen for a Java [Intent.ACTION_HEADSET_PLUG](https://developer.android.com/reference/android/content/Intent#ACTION_HEADSET_PLUG), 30cb93a386Sopenharmony_ciwhich is fired when a head set is plugged in or out. If your min SDK is LOLLIPOP or later then you can use [AudioManager.ACTION_HEADSET_PLUG](https://developer.android.com/reference/android/media/AudioManager#ACTION_HEADSET_PLUG) instead. 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci // Receive a broadcast Intent when a headset is plugged in or unplugged. 33cb93a386Sopenharmony_ci public class PluginBroadcastReceiver extends BroadcastReceiver { 34cb93a386Sopenharmony_ci @Override 35cb93a386Sopenharmony_ci public void onReceive(Context context, Intent intent) { 36cb93a386Sopenharmony_ci // Close the stream if it was not disconnected. 37cb93a386Sopenharmony_ci } 38cb93a386Sopenharmony_ci } 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci private BroadcastReceiver mPluginReceiver = new PluginBroadcastReceiver(); 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ciYou can register for the Intent when your app resumes and unregister when it pauses. 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci @Override 45cb93a386Sopenharmony_ci public void onResume() { 46cb93a386Sopenharmony_ci super.onResume(); 47cb93a386Sopenharmony_ci IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG); 48cb93a386Sopenharmony_ci this.registerReceiver(mPluginReceiver, filter); 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci @Override 52cb93a386Sopenharmony_ci public void onPause() { 53cb93a386Sopenharmony_ci this.unregisterReceiver(mPluginReceiver); 54cb93a386Sopenharmony_ci super.onPause(); 55cb93a386Sopenharmony_ci } 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci## Internal Notes 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci* Oboe Issues 60cb93a386Sopenharmony_ci * [#381](https://github.com/google/oboe/issues/381) Connecting headphones does not trigger any event. S9 61cb93a386Sopenharmony_ci * [#893](https://github.com/google/oboe/issues/893) onErrorBeforeClose and onErrorAfterClose not called, S10 62cb93a386Sopenharmony_ci * [#908](https://github.com/google/oboe/issues/908) Huawei MAR-LX3A 63cb93a386Sopenharmony_ci* This issue is tracked internally as b/111711159. 64cb93a386Sopenharmony_ci* A fix in AOSP is [here](https://android-review.googlesource.com/c/platform/frameworks/av/+/836184) 65cb93a386Sopenharmony_ci* A fix was also merged into pi-dev on July 30, 2018. 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci### Results from Test Disconnect in OboeTester 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci| Device | Build | Result | 70cb93a386Sopenharmony_ci|:--|:--|:--| 71cb93a386Sopenharmony_ci| Pixel 1 | QQ1A.190919.002 | ALL PASS | 72cb93a386Sopenharmony_ci| Samsung S10e | PPR1.180610.011 | MMAP Output plugIN failed | 73cb93a386Sopenharmony_ci| Huawei MAR-LX3A | 10.0.0.216 | MMAP In/Out fails, Legacy In fails. | 74