Android AudioService安全音量设置逻辑

31 篇文章 0 订阅

问题点描述:
还原出厂设置后,第一次启动安卓系统会自动降音量设成10,导致开机时音量不一致问题。

原因:安全音量逻辑将音量设置为10

安全音量配置和音量值
\frameworks\base\core\res\res\values\config.xml

  1. <!-- Safe headphone volume index. When music stream volume is below this index

  2. the SPL on headphone output is compliant to EN 60950 requirements for portable music

  3. players. -->

  4. <integer name="config_safe_media_volume_index">10</integer>

  5. <!-- Whether safe headphone volume is enabled or not (country specific). -->

  6. <bool name="config_safe_media_volume_enabled">true</bool>

安全音量逻辑:
frameworks\base\services\core\java\com\android\server\audio\AudioService.java

​​​​​​​
  1. // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,

  2. private final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET |

  3. AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |

  4. AudioSystem.DEVICE_OUT_USB_HEADSET;

  5. ///

  6. // Construction

  7. ///

  8. /** @hide */

  9. public AudioService(Context context) {

  10. //...

  11. // The default safe volume index read here will be replaced by the actual value when

  12. // the mcc is read by onConfigureSafeVolume()

  13. mSafeMediaVolumeIndex = mContext.getResources().getInteger(

  14. com.android.internal.R.integer.config_safe_media_volume_index) * 10;

  15. //...

  16. }

  17. public void onSystemReady() {

  18. //...

  19. sendMsg(mAudioHandler,

  20. MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED,

  21. SENDMSG_REPLACE,

  22. 0,

  23. 0,

  24. TAG,

  25. SystemProperties.getBoolean("audio.safemedia.bypass", false) ?

  26. 0 : SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);

  27. //...

  28. }

  29. /** Handles internal volume messages in separate volume thread. */

  30. private class AudioHandler extends Handler {

  31. //...

  32. @Override

  33. public void handleMessage(Message msg) {

  34. switch (msg.what) {

  35. case MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED:

  36. case MSG_CONFIGURE_SAFE_MEDIA_VOLUME:

  37. onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED),

  38. (String) msg.obj);

  39. break;

  40. }

  41. }

  42. //...

  43. }

  44. private void onConfigureSafeVolume(boolean force, String caller) {

  45. synchronized (mSafeMediaVolumeState) {

  46. int mcc = mContext.getResources().getConfiguration().mcc;

  47. if ((mMcc != mcc) || ((mMcc == 0) && force)) {

  48. mSafeMediaVolumeIndex = mContext.getResources().getInteger(

  49. com.android.internal.R.integer.config_safe_media_volume_index) * 10;

  50. mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();

  51. boolean safeMediaVolumeEnabled =

  52. SystemProperties.getBoolean("audio.safemedia.force", false)

  53. || mContext.getResources().getBoolean(

  54. com.android.internal.R.bool.config_safe_media_volume_enabled);

  55. boolean safeMediaVolumeBypass =

  56. SystemProperties.getBoolean("audio.safemedia.bypass", false);

  57. // The persisted state is either "disabled" or "active": this is the state applied

  58. // next time we boot and cannot be "inactive"

  59. int persistedState;

  60. if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) {

  61. persistedState = SAFE_MEDIA_VOLUME_ACTIVE;

  62. // The state can already be "inactive" here if the user has forced it before

  63. // the 30 seconds timeout for forced configuration. In this case we don't reset

  64. // it to "active".

  65. if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) {

  66. if (mMusicActiveMs == 0) {

  67. mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;

  68. enforceSafeMediaVolume(caller);

  69. } else {

  70. // We have existing playback time recorded, already confirmed.

  71. mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;

  72. }

  73. }

  74. } else {

  75. persistedState = SAFE_MEDIA_VOLUME_DISABLED;

  76. mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;

  77. }

  78. mMcc = mcc;

  79. sendMsg(mAudioHandler,

  80. MSG_PERSIST_SAFE_VOLUME_STATE,

  81. SENDMSG_QUEUE,

  82. persistedState,

  83. 0,

  84. null,

  85. 0);

  86. }

  87. }

  88. }

  89. private void enforceSafeMediaVolume(String caller) {

  90. VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];

  91. int devices = mSafeMediaVolumeDevices;

  92. int i = 0;

  93. while (devices != 0) {

  94. int device = 1 << i++;

  95. if ((device & devices) == 0) {

  96. continue;

  97. }

  98. int index = streamState.getIndex(device);

  99. if (index > safeMediaVolumeIndex(device)) {

  100. streamState.setIndex(safeMediaVolumeIndex(device), device, caller);

  101. sendMsg(mAudioHandler,

  102. MSG_SET_DEVICE_VOLUME,

  103. SENDMSG_QUEUE,

  104. device,

  105. 0,

  106. streamState,

  107. 0);

  108. }

  109. devices &= ~device;

  110. }

  111. }

  112. private int safeMediaVolumeIndex(int device) {

  113. if ((device & mSafeMediaVolumeDevices) == 0) {

  114. return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];

  115. }

  116. if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {

  117. return mSafeUsbMediaVolumeIndex;

  118. } else {

  119. return mSafeMediaVolumeIndex;

  120. }

  121. }

config_safe_media_volume_enabled

config_safe_media_volume_index

的配置是一个关键,决定了安全音量的功能是否有效已经安全音量的档位。

本文转载自: Android AudioService安全音量设置逻辑_快導碗里来的博客-CSDN博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值