oboe
oboe copied to clipboard
setPreferredMixerAttributes on USB DAC can cause whole system to hang on MTK device with MTK Hi-Fi
Android version(s): Android 14 (not QPR) stock ROM Android device(s): Any MTK device with MTK Hi-Fi enabled (I used Unihertz Jelly Max) Oboe version: Any (reproduces on 1.9.2) App name used for testing: OboeTester with patch on top of e3bde1b6bcf7ebba0f5461e12de87c4f12a79679
diff --git a/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java
index f286ffbb..ff62151e 100644
--- a/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java
@@ -27,6 +27,7 @@ import android.content.pm.ServiceInfo;
import android.media.AudioAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
+import android.media.AudioMixerAttributes;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -46,6 +47,8 @@ import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.Locale;
/**
@@ -631,6 +634,39 @@ abstract class TestAudioActivity extends AppCompatActivity {
public void openAudio() throws IOException {
closeAudio();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ List<AudioDeviceInfo> info = Arrays.asList(audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS));
+ for (AudioDeviceInfo device : info) {
+ List<AudioMixerAttributes> attr = audioManager.getSupportedMixerAttributes(device);
+ if (attr.isEmpty()) continue;
+ attr.sort((a, b) -> {
+ if (a.getMixerBehavior() != b.getMixerBehavior()) {
+ return a.getMixerBehavior() == AudioMixerAttributes.MIXER_BEHAVIOR_BIT_PERFECT ? 1 : -1;
+ }
+ if (a.getFormat().getSampleRate() != b.getFormat().getSampleRate()) {
+ return a.getFormat().getSampleRate() > b.getFormat().getSampleRate() ? 1 : -1;
+ }
+ if (a.getFormat().getChannelCount() != b.getFormat().getChannelCount()) {
+ return a.getFormat().getChannelCount() > b.getFormat().getChannelCount() ? 1 : -1;
+ }
+ if (a.getFormat().getEncoding() != b.getFormat().getEncoding()) { // :)
+ return a.getFormat().getEncoding() > b.getFormat().getEncoding() ? 1 : -1;
+ }
+ return 0;
+ });
+ audioManager.setPreferredMixerAttributes(new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+ .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+ .build(), device, attr.get(0));
+ }
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
updateNativeAudioParameters();
if (!isTestConfiguredUsingBundle()) {
@@ -811,6 +847,19 @@ abstract class TestAudioActivity extends AppCompatActivity {
updateEnabledWidgets();
onStopAllContexts();
}
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ List<AudioDeviceInfo> info = Arrays.asList(audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS));
+ for (AudioDeviceInfo device : info) {
+ List<AudioMixerAttributes> attr = audioManager.getSupportedMixerAttributes(device);
+ if (attr.isEmpty()) continue;
+ audioManager.clearPreferredMixerAttributes(new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+ .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+ .build(), device);
+ }
+ }
}
public void runTest() {
Short description When stress testing open/close with preferred mixer attributes, device will progressively become more and more unresponsive until eventually hanging for minutes in buggy state (live wallpaper became black, can't open settings app - hanging forever, etc) before recovering. Presumably root cause is audioserver 100% CPU:
Please see attached video for how to reproduce
https://github.com/user-attachments/assets/c0e4ebbd-cb25-4721-9dd7-cbab9e444534
Bug report ZIP bugreport-Jelly_Max_EEA-UP1A.231005.007-2025-04-08-19-44-54.zip
Steps to reproduce Please see the attached video, it was recorded on freshly factory reset test device, no device settings modified.
Expected behavior No ANR, wallpaper not turning black, settings app keeps working, audioserver not 100% cpu, etc
Actual behavior see above :)
Device ro.product.brand = Unihertz ro.product.manufacturer = Unihertz ro.product.model = Jelly Max ro.product.device = Jelly_Max ro.product.cpu.abi = arm64-v8a ro.build.description = sys_mssi_64_64only_ww_armv82_g78v78c2k_dfl_eea-user 14 UP1A.231005.007 V01.00.00 release-keys ro.hardware = mt6878 ro.hardware.chipname = ro.arch = | grep aaudio = [aaudio.mmap_exclusive_policy]: [2] [aaudio.mmap_policy]: [2]
Any additional context not reproducible on Pixel
@nift4 - Thanks for this report. The patch you aded looks reasonable. The busy loop in the audioserver is clearly a bad thing.
We will work with MediaTek on this.
Created 417232363 to discuss with MTK folks.