Android adb shell dumpsys audio 信息查看分析详解

一、前言

Android 如果要分析当前设备的声音通道相关日志, 仅仅看AudioService的日志是看不到啥日志的,但是看整个audio关键字的日志又太多太乱了, 所以可以看一下系统提供的一个调试指令dumpsys audio 返回的信息进行定位分析, 里面主要包含了AudioService启动时间,当前设备的音频流指向,音频流的声音大小,音频外设的连接情况,音频播放记录,音频外设连接断开记录等等信息。

不同的Android 系统使用 dumpsys audio 命令返回的日志信息可能会有差异, 因为打印返回的信息就是AudioService.java里面打印显示的, 本文的示例讲解是以mtk方案的Android14日志信息进行讲解。 网上基本没有对dumpsys audio 日志信息进行分析的,有兴趣的可以收藏查看。

二、分析

1、简单示例和主要内容

本示例日志是设备连接蓝牙耳机后的dumpsys audio情况日志信息:

# dumpsys audio

[18:57:20]Events log: audio services lifecycle

[18:57:20]11-22 18:54:07:681 AudioService() //(1)AudioService 启动时间,大概可以推测出开机时间

[18:57:20]MediaFocusControl dump time: 6:57:22 PM //(2)执行dumpsys audio的时间

//(3)dumpsys audio最重要的内容,设备支持声音流情况

[18:57:20]Stream volumes (device: index)

[18:57:20]- STREAM_VOICE_CALL (aliased to: STREAM_MUSIC):

。。。

[18:57:20]- STREAM_SYSTEM (aliased to: STREAM_MUSIC):

。。。

[18:57:20]- STREAM_RING (aliased to: STREAM_MUSIC):

。。

//(4)基本是音频播放的情况,上面其他声音通道都是注释了以这个为标准

[18:57:20]- STREAM_MUSIC:

[18:57:20] Muted: false

[18:57:20] Muted Internally: false

[18:57:20] Min: 0 //声音范围

[18:57:20] Max: 15

[18:57:20] streamVolume:7 //当前声音大小

[18:57:20] Current: 2 (speaker): 7, 80 (bt_a2dp): 7, 400 (hdmi): 7, 40000000 (default): 7

[18:57:20] Devices: bt_a2dp(80) //当前声音通道,蓝牙

[18:57:20] Volume Group: music

[18:57:20]

[18:57:20]- STREAM_ALARM (aliased to: STREAM_MUSIC):

[18:57:20] Muted: false

[18:57:20] Muted Internally: false

[18:57:20] Min: 1

[18:57:20] Max: 7

[18:57:20] streamVolume:4

[18:57:20] Current: 2 (speaker): 4, 80 (bt_a2dp): 4, 400 (hdmi): 4, 40000000 (default): 4

[18:57:20] Devices: speaker(2), bt_a2dp(80)

[18:57:20] Volume Group: alarm

//其他声音通道比较少实用,比如铃声,通知等情况

[18:57:20]- STREAM_NOTIFICATION (aliased to: STREAM_MUSIC):

[18:57:20]- STREAM_BLUETOOTH_SCO:

[18:57:20]- STREAM_SYSTEM_ENFORCED (aliased to: STREAM_MUSIC):

[18:57:20]- STREAM_DTMF (aliased to: STREAM_MUSIC):

[18:57:20]- STREAM_TTS (aliased to: STREAM_MUSIC):

[18:57:20]- STREAM_ACCESSIBILITY (aliased to: STREAM_MUSIC):

[18:57:20]- STREAM_ASSISTANT (aliased to: STREAM_MUSIC):

。。。

//Volume Groups 不知道是干啥的,类型也是挺多的。

[18:57:20]Volume Groups (device: index)

[18:57:20]- VOLUME GROUP voice_call:

[18:57:20] Muted: false

[18:57:20] Min: 1

[18:57:20] Max: 7

[18:57:20] Current: 2 (speaker): 4, 80 (bt_a2dp): 7, 40000000 (default): 4

[18:57:20] Devices: bt_a2dp

[18:57:20] Streams: STREAM_VOICE_CALL

[18:57:20]- VOLUME GROUP system:

[18:57:20] Muted: false

[18:57:20] Min: 0

[18:57:20] Max: 100

[18:57:20] Current: 2 (speaker): 47, 80 (bt_a2dp): 7, 40000000 (default): 47

[18:57:20] Devices: bt_a2dp

[18:57:20] Streams: STREAM_SYSTEM

[18:57:20]- VOLUME GROUP ring:

[18:57:20]- VOLUME GROUP music:

[18:57:20]- VOLUME GROUP alarm:

[18:57:20]- VOLUME GROUP alarm:

[18:57:20]- VOLUME GROUP bluetooth_sco:

[18:57:20]- VOLUME GROUP enforced_audible:

[18:57:20]- VOLUME GROUP dtmf:

[18:57:20]- VOLUME GROUP accessibility:

[18:57:20]- VOLUME GROUP assistant:

[18:57:20]- VOLUME GROUP AUDIO_STREAM_REROUTING:

[18:57:20]- VOLUME GROUP AUDIO_STREAM_PATCH:

VOLUME GROUP类型的 Streams属性值都是指向上面的Stream volumes类型的。

[18:57:20]Audio routes:

[18:57:20] mMainType=0x0

//(5)当前连接蓝牙的设备名称,如果未连接蓝牙为null

[18:57:20] mBluetoothName=Xiaodu Portable Speaker

//(6)音频播放情况日志

[19:00:32]Events log: playback activity as reported through PlayerBase

//开机铃声

[19:00:32]11-22 18:54:09:789 new player piid:71 uid/pid:1000/745 type:android.media.SoundPool attr:AudioAttributes: usage=USAGE_ASSISTANCE_SONIFICATION content=CONTENT_TYPE_SONIFICATION flags=0x800 tags= bundle=null session:0

[19:00:33]11-22 18:54:10:837 new player piid:79 uid/pid:1000/1069 type:android.media.SoundPool attr:AudioAttributes: usage=USAGE_MEDIA content=CONTENT_TYPE_UNKNOWN flags=0x800 tags= bundle=null session:0

。。。

//音频文件播放+停止+播放+停止操作的日志

[19:00:33]11-22 18:58:37:956 player piid:103 event:started

[19:00:33]11-22 18:58:38:076 player piid:103 format update:FormatInfo{isSpatialized=false, channelMask=0x3, sampleRate=44100}

[19:00:33]11-22 18:58:38:175 player piid:103 event:device updated deviceId:5

[19:00:33]11-22 18:58:38:190 player piid:103 event:device updated deviceId:5

[19:00:33]11-22 18:58:42:920 player piid:103 event:paused

[19:00:33]11-22 19:00:24:155 player piid:103 event:started

[19:00:33]11-22 19:00:24:169 player piid:103 format update:FormatInfo{isSpatialized=false, channelMask=0x3, sampleRate=44100}

[19:00:33]11-22 19:00:24:204 player piid:103 event:device updated deviceId:5

[19:00:33]11-22 19:00:29:492 player piid:103 event:paused

//(7)当前连接的设备,这里是连接蓝牙耳机

[18:57:21] Connected devices:

[18:57:21] [DeviceInfo: type:0x80 (bt_a2dp) name:Xiaodu Portable Speaker addr:48:F3:F3:ED:78:AD codec: 1f000000 sensorUuid: 00000000-0000-0000-4254-48f3f3ed78ad disabled modes: {}]

[18:57:21]

//(8)如果是连接的usb有线耳机,另外一份日志拼过来的

[15:01:34] Connected devices:

[15:01:34] [DeviceInfo: type:0x4000000 (usb_headset) name:USB-Audio - USB Speaker Phone addr:card=4;device=0 codec: 0 sensorUuid: null disabled modes: {}]

//(9)连接蓝牙耳机、有线耳机等外设音箱的日志

[18:57:21]Events log: wired/A2DP/hearing aid device connection

。。。

[18:57:21]11-22 18:57:04:640 BT profile service: connecting HEARING_AID profile

[18:57:21]11-22 18:57:04:666 BT profile service: connecting A2DP profile

[18:57:21]11-22 18:57:09:875 msg: onBluetoothActiveDeviceChange state=2 addr=48:F3:F3:ED:78:AD prof=2 supprNoisy=true src=AudioService

[18:57:21]11-22 18:57:09:885 BT connected: addr=48:F3:F3:ED:78:AD profile=2 state=2 codec=AUDIO_FORMAT_SBC

[18:57:21]11-22 18:57:10:074 A2DP device addr=48:F3:F3:ED:78:AD now available

//上面可以看到蓝牙连接的时间记录

//(10)声音通道占用的日志

[18:57:21]Events log: force use (logged before setForceUse() is executed)

[18:57:21]11-22 18:54:07:774 setForceUse(FOR_DOCK, FORCE_DIGITAL_DOCK) due to readDockAudioSettings

。。。

[18:57:21]11-22 18:54:08:521 setForceUse(FOR_VIBRATE_RINGING, FORCE_NONE) due to muteRingerModeStreams() from u/pid:1000/745

。。。

//从最后一行日志看,最后是设置为蓝牙通道的

[18:57:21]11-22 18:57:09:897 setForceUse(FOR_MEDIA, FORCE_NONE) due to setBluetoothA2dpOn(true) from u/pid:1000/745 src:onSetBtActiveDevice

//(11)声音变化和通道情况

[18:57:21]Events log: volume changes (logged when command received by AudioService)

[18:57:21]11-22 18:57:09:885 VolumeStreamState.muteInternally(stream:STREAM_MUSIC, muted)

[18:57:21]11-22 18:57:10:053 setDeviceVolumeBehavior: dev:bt_a2dp addr:48:F3:F3:ED:78:AD behavior:DEVICE_VOLUME_BEHAVIOR_VARIABLE pack:com.android.bluetooth

[18:57:21]11-22 18:57:10:156 avrcpSupportsAbsoluteVolume addr=48:F3:F3:ED:78:AD support=false

[18:57:21]11-22 18:57:10:323 VolumeStreamState.muteInternally(stream:STREAM_MUSIC, unmuted)

//从上面日志看是蓝牙声音通道,STREAM_MUSIC 流

//(12)AudioSystemAdapter 不清楚是啥日志

[18:57:21]AudioSystemAdapter:

[18:57:21] last cache clear time: 11-22 18:57:10:110

[18:57:21] mDevicesForAttrCache:

[18:57:21] AudioAttributes: usage=USAGE_ASSISTANCE_SONIFICATION content=CONTENT_TYPE_UNKNOWN flags=0x800 tags= bundle=null forVolume: true stream: STREAM_SYSTEM(1)

[18:57:21] AudioDeviceAttributes: role:output type:bt_a2dp addr:48:F3:F3:ED:78:AD name: profiles:[] descriptors:[]

[18:57:21] AudioAttributes: usage=USAGE_ASSISTANCE_ACCESSIBILITY content=CONTENT_TYPE_UNKNOWN flags=0x800 tags= bundle=null forVolume: true stream: STREAM_ACCESSIBILITY(10)

[18:57:21] AudioDeviceAttributes: role:output type:bt_a2dp addr:48:F3:F3:ED:78:AD name: profiles:[] descriptors:[]

[18:57:21] AudioAttributes: usage=USAGE_UNKNOWN content=CONTENT_TYPE_UNKNOWN flags=0x801 tags= bundle=null forVolume: true stream: STREAM_SYSTEM(1)

[18:57:21] AudioDeviceAttributes: role:output type:speaker addr: name: profiles:[] descriptors:[]

[18:57:21] AudioDeviceAttributes: role:output type:bt_a2dp addr:48:F3:F3:ED:78:AD name: profiles:[] descriptors:[]

。。。

百度查询到:AudioSystemAdapter可能会包含如下功能:

设备检测:检查设备是否支持特定音频特性(如蓝牙、耳机插孔等)。

音频路径管理:动态选择音频流的最佳路径,如扬声器、耳机或蓝牙设备。

音效处理:应用特定的音效效果,如均衡器设置或环绕声模式。

但是从上面日志看不出这些信息,可能信息比较隐蔽。

从上面的示例的主要日志信息,可以看到dumpsys主要包含当前音频流和外设的信息。

2、dumpsys audio日志的主要格式内容

# dumpsys audio //(1)执行命令

[18:57:20]Events log: audio services lifecycle

//(2)AudioService 启动时间,大概可以推测出开机时间

[18:57:20]11-22 18:54:07:681 AudioService()

//(3)dumpsys audio最重要的内容,设备支持声音流情况,正常看STREAM_MUSIC

[18:57:20]Stream volumes (device: index)

[18:57:20]- STREAM_MUSIC:

[18:57:20] Muted: false

[18:57:20] Muted Internally: false

[18:57:20] Min: 0 //声音范围

[18:57:20] Max: 15

[18:57:20] streamVolume:7 //当前声音大小

[18:57:20] Current: 2 (speaker): 7, 80 (bt_a2dp): 7, 400 (hdmi): 7, 40000000 (default): 7

[18:57:20] Devices: bt_a2dp(80) //当前声音通道,蓝牙

[18:57:20] Volume Group: music

[18:57:20]

//(4)音频播放情况日志

[19:00:32]Events log: playback activity as reported through

//(5)音频外设连接情况

[18:57:21] Connected devices:

//(6)声音通道占用的日志

[18:57:21]Events log: force use (logged before setForceUse() is executed)

//(7)音频外设连接断开日志

[18:57:21]Events log: wired/A2DP/hearing aid device connection

//(8)声音变化和通道情况

[18:57:21]Events log: volume changes (logged when command received by AudioService)

//(9)AudioSystemAdapter 音频管理信息

这里只是根据一个实际的示例日志进行的讲解, 上面的讲解不一定完全正确和全面,仅供参考吧。

三、其他

1、dumpsys audio小结

dumpsys audio 主要能看到

当前设备音频流的指向情况,Stream volumes (device: index)

当前系统音频外设连接情况,Connected devices

声音通道占用情况记录,Events log: force use

音频外设连接断开日志,Events log: wired/A2DP/hearing aid device connection

dumpsys audio 最主要就是上面这几个声音相关信息。 更多的要看具体情况的日志了。

2、dumpsys audio 的源码

dumpsys audio 返回的打印信息,其实是Java代码上打印的,具体源码如下:

framework/base/services/core/java/com/android/server/audio/AudioService.java

@Override

protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {

if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;

sLifecycleLogger.dump(pw);

if (mAudioHandler != null) {

pw.println("\nMessage handler (watch for unhandled messages):");

mAudioHandler.dump(new PrintWriterPrinter(pw), " ");

} else {

pw.println("\nMessage handler is null");

}

...

pw.println("\nAudio routes:");

pw.print(" mMainType=0x"); pw.println(Integer.toHexString(

mDeviceBroker.getCurAudioRoutes().mainType));

pw.print(" mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName);

...

pw.println("\n");

pw.println("\nSpatial audio:");

pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)");

pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)");

mSpatializerHelper.dump(pw);

sSpatialLogger.dump(pw);

mAudioSystem.dump(pw);

}

可以看到 dumpsys audio 命令返回的数据,都是在 AudioService.java 里面返回打印的; Audio相关数据很多,有兴趣的可以自己分析研究看看; 如果想要自定义添加一下额外的打印,可以在源码里面添加。

3、使用谷歌文件管理器 GoogleFile 播放音频文件日志:

logct | grep -E "AudioService|AudioTrack"

//打开文件管理器后首次播放:

11-23 10:22:26.542 798 1614 I MediaSessionStack: addSession to bottom of stack | record: com.google.android.apps.nbu.files/AudioService (userId=0)

11-23 10:22:26.938 798 1614 I AudioService.FadeOutManager: unfadeOutUid() uid:10074

11-23 10:22:27.148 798 937 I MediaSessionStack: onPlaybackStateChanged - Pushing session to top | record: com.google.android.apps.nbu.files/AudioService (userId=0)

11-23 10:22:27.635 798 1457 I ActivityManager: Background started FGS: Allowed [callingPackage: com.google.android.apps.nbu.files; callingUid: 10074; uidState: TOP ; uidBFSL: [BFSL]; intent: Intent { cmp=com.google.android.apps.nbu.files/.mediaconsumption.audio.service.AudioService (has extras) }; code:PROC_STATE_TOP; tempAllowListReason:; targetSdkVersion:34; callerTargetSdkVersion:34; startForegroundCount:0; bindFromPackage:null: isBindService:true]

11-23 10:22:27.666 798 798 D MediaSessionService: Media button session is changed to com.google.android.apps.nbu.files/AudioService (userId=0)

//停止后,再次点击播放

11-23 10:22:58.294 7108 7259 D AudioTrack: getTimestamp_l(16): device stall time corrected using current time 2328289907108

11-23 10:22:58.339 798 1460 I MediaSessionStack: onPlaybackStateChanged - Pushing session to top | record: com.google.android.apps.nbu.files/AudioService (userId=0)

11-23 10:22:58.344 7108 7259 D AudioTrack: getTimestamp_l(16): stale timestamp time corrected, currentTimeNanos: 2318205649000 < limitNs: 2328189081941 < mStartNs: 2328287081941

11-23 10:22:58.344 7108 7259 W AudioTrack: getTimestamp_l(16): retrograde timestamp time corrected, 2328189081941 < 2328329633858

能看到一点日志,比如AudioTrack播放时间,但是没有太多日志,比如用什么设备播放、播放音量等等信息。 所以dumpsys audio 还是可以看到当时比较有用的一些日志的。

4、Android 的声音通道类型

其中streamType定义如下:

STREAM_ALARM:闹钟

STREAM_DTMF:双音多频,拨号键的声音

STREAM_MUSIC:音乐

STREAM_NOTIFICATION:通知

STREAM_RING:铃声

STREAM_SYSTEM:系统

STREAM_VOICE_CALL:通话

Android大概支持上面的声音通道类型,主要使用的是外放的 STREAM_MUSIC。

5、Android–耳机插拔检测(framework篇)

上层到底层的一顿讲解

https://blog.csdn.net/qq_42364999/article/details/143256027