故障现场
这里的首次开机也包括恢复出厂设置后的第一次开机。出现故障后,配合机发送一条短信过来,一直没有提示音。打开AudioHW的PCM DUMP之后发现写下去的音频流为全0数据,查看dumpsys media.audio_policy的信息如下:Streams dump:
Stream Can be muted Index Min Index Max Index Cur [device : index]...
00 true 01 05 0001 : 04, 40000000 : 04,
01 true 00 07 0001 : 00, 0002 : 00, 40000000 : 05,
02 true 00 07 0001 : 05, 0002 : 05, 40000000 : 05,
03 true 00 15 0004 : 10, 0008 : 10, 40000000 : 11,
04 true 00 07 40000000 : 06,
05 true 00 07 0001 : 00, 0002 : 00, 40000000 : 05,
06 true 00 15 40000000 : 07,
07 true 00 07 0001 : 00, 0002 : 00, 40000000 : 05,
08 true 00 15 0001 : 11, 0002 : 11, 40000000 : 11,
09 true 00 15 0002 : 11, 40000000 : 11,
10 true 00 15 0004 : 10, 0008 : 10, 40000000 : 11,
11 true 00 01 40000000 : 00,
12 true 00 01 40000000 : 00,
可以看到SYSTEM、NOTIFICATION和ENFORCED_AUDIBLE的当前音量值被设置0。查看log可以发现在来电前后有如下的几行可疑打印:
05-03 21:06:09.419 2826 2932 I vol.Events: writeEvent internal_ringer_mode_changed silent
05-03 21:06:09.420 2826 2932 I vol.Events: writeEvent mute_changed STREAM_RING true
05-03 21:06:09.433 2826 2932 I vol.Events: writeEvent mute_changed STREAM_SYSTEM true
05-03 21:06:09.433 2826 2932 I vol.Events: writeEvent external_ringer_mode_changed silent
来电铃音播放结束后对应有:
05-03 21:06:18.479 2826 2932 I vol.Events: writeEvent mute_changed STREAM_RING false
05-03 21:06:18.525 2826 2932 I vol.Events: writeEvent mute_changed STREAM_SYSTEM false
05-03 21:06:18.532 2826 2932 I vol.Events: writeEvent internal_ringer_mode_changed normal
这些代码是电话接通后切成勿扰模式相关的调用,是在systemUI中控制的。
进一步分析
增加AudioFlinger、Thread和APM的log之后,来电之后开始播放短信提示音时将Stream 5设为了Mute。05-03 21:06:36.752 1517 2963 I ExtendedNuUtils: printFileName fd(13) -> /data/system_de/0/ringtones/notification_sound_cache
05-03 21:06:37.055 1504 1690 V APM_AudioPolicyManager: startOutput() output 13, stream 5, session 425
05-03 21:06:37.057 1504 1690 V APM_AudioPolicyManager: setStrategyMute() strategy 3, mute 1, output ID 3
05-03 21:06:37.057 1504 1690 V APM_AudioPolicyManager: setStreamMute() stream 5, mute 1, mMuteCount 0 device 0002
05-03 21:06:37.058 1504 1690 V APM_AudioPolicyManager: setStrategyMute() strategy 3, mute 0, output ID 3
05-03 21:06:37.058 1504 1690 V APM_AudioPolicyManager: setStreamMute() stream 5, mute 0, mMuteCount 1 device 0002
整体搜索Stream 5,发现了如下两条打印:
05-03 21:06:17.097 1504 9147 V APM_AudioPolicyManager: setStreamVolumeIndex() stream 5, device 00000001, index 0
05-03 21:06:17.953 1504 1882 V APM_AudioPolicyManager: setStreamVolumeIndex() stream 5, device 00000002, index 0
下面分别从两个方向来分析这个故障的原因:
1)调用setStreamVolumeIndex将音量设为0
发起该调用的地方来自AudioService.java,总共有applyDeviceVolume_syncVSS(int device)和applyAllVolumes()两个函数,它们的逻辑是从mIsMuted、mFullVolumeDevices和mIndexMap获取各个设备和Stream的音量值并设置下去。结合另一个故障的细节(即发生故障后,上面直接从AudioManager读取出来的音量值为5,且按下音量上键时直接跳到6级音量,因此可以判断&#