Android AudioService安全音量设置逻辑

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

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

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

<!-- Safe headphone volume index. When music stream volume is below this index
the SPL on headphone output is compliant to EN 60950 requirements for portable music
players. -->
<integer name="config_safe_media_volume_index">10</integer>

<!-- Whether safe headphone volume is enabled or not (country specific). -->
<bool name="config_safe_media_volume_enabled">true</bool>

1
2
3
4
5
6
7
安全音量逻辑:
frameworks\base\services\core\java\com\android\server\audio\AudioService.java

// mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
private final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET |
AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |
AudioSystem.DEVICE_OUT_USB_HEADSET;

///
// Construction
///
/** @hide */
public AudioService(Context context) {
//…

// The default safe volume index read here will be replaced by the actual value when
// the mcc is read by onConfigureSafeVolume()
mSafeMediaVolumeIndex = mContext.getResources().getInteger(
        com.android.internal.R.integer.config_safe_media_volume_index) * 10;

//...

}

public void onSystemReady() {
//…
sendMsg(mAudioHandler,
MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED,
SENDMSG_REPLACE,
0,
0,
TAG,
SystemProperties.getBoolean(“audio.safemedia.bypass”, false) ?
0 : SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);
//…
}

/** Handles internal volume messages in separate volume thread. */
private class AudioHandler extends Handler {
//…
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED:
case MSG_CONFIGURE_SAFE_MEDIA_VOLUME:
onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED),
(String) msg.obj);
break;
}
}
//…
}

private void onConfigureSafeVolume(boolean force, String caller) {
synchronized (mSafeMediaVolumeState) {
int mcc = mContext.getResources().getConfiguration().mcc;
if ((mMcc != mcc) || ((mMcc == 0) && force)) {
mSafeMediaVolumeIndex = mContext.getResources().getInteger(
com.android.internal.R.integer.config_safe_media_volume_index) * 10;

        mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();

        boolean safeMediaVolumeEnabled =
                SystemProperties.getBoolean("audio.safemedia.force", false)
                || mContext.getResources().getBoolean(
                        com.android.internal.R.bool.config_safe_media_volume_enabled);

        boolean safeMediaVolumeBypass =
                SystemProperties.getBoolean("audio.safemedia.bypass", false);

        // The persisted state is either "disabled" or "active": this is the state applied
        // next time we boot and cannot be "inactive"
        int persistedState;
        if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) {
            persistedState = SAFE_MEDIA_VOLUME_ACTIVE;
            // The state can already be "inactive" here if the user has forced it before
            // the 30 seconds timeout for forced configuration. In this case we don't reset
            // it to "active".
            if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) {
                if (mMusicActiveMs == 0) {
                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
                    enforceSafeMediaVolume(caller);
                } else {
                    // We have existing playback time recorded, already confirmed.
                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
                }
            }
        } else {
            persistedState = SAFE_MEDIA_VOLUME_DISABLED;
            mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
        }
        mMcc = mcc;
        sendMsg(mAudioHandler,
                MSG_PERSIST_SAFE_VOLUME_STATE,
                SENDMSG_QUEUE,
                persistedState,
                0,
                null,
                0);
    }
}

}

private void enforceSafeMediaVolume(String caller) {
VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
int devices = mSafeMediaVolumeDevices;
int i = 0;

while (devices != 0) {
    int device = 1 << i++;
    if ((device & devices) == 0) {
        continue;
    }
    int index = streamState.getIndex(device);
    if (index > safeMediaVolumeIndex(device)) {
        streamState.setIndex(safeMediaVolumeIndex(device), device, caller);
        sendMsg(mAudioHandler,
                MSG_SET_DEVICE_VOLUME,
                SENDMSG_QUEUE,
                device,
                0,
                streamState,
                0);
    }
    devices &= ~device;
}

}

private int safeMediaVolumeIndex(int device) {
if ((device & mSafeMediaVolumeDevices) == 0) {
return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
}
if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
return mSafeUsbMediaVolumeIndex;
} else {
return mSafeMediaVolumeIndex;
}
}

config_safe_media_volume_enabled的配置是一个关键,决定了安全音量的功能是否有效。
————————————————
版权声明:本文为CSDN博主「sunxiaolin2016」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Sunxiaolin2016/article/details/117654459

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值