1./frameworks/base/services/core/java/com/android/server/audio/AudioService.java
public static final class Lifecycle extends SystemService {
private AudioService mService;
public Lifecycle(Context context) {
super(context);
mService = new AudioService(context,
AudioSystemAdapter.getDefaultAdapter(),
SystemServerAdapter.getDefaultAdapter(context),
SettingsAdapter.getDefaultAdapter(),
new DefaultAudioPolicyFacade(),
null);
}
@Override
public void onStart() {
publishBinderService(Context.AUDIO_SERVICE, mService);
}
@Override
public void onBootPhase(int phase) {
//Activity Manager 已经完成初始化,开始启动服务
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mService.systemReady();
}
}
}
public void systemReady() {
sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
0, 0, null, 0);
if (false) {
// This is turned off for now, because it is racy and thus causes apps to break.
// Currently banning a uid means that if an app tries to start playing an audio
// stream, that will be preventing, and unbanning it will not allow that stream
// to resume. However these changes in uid state are racy with what the app is doing,
// so that after taking a process out of the cached state we can't guarantee that
// we will unban the uid before the app actually tries to start playing audio.
// (To do that, the activity manager would need to wait until it knows for sure
// that the ban has been removed, before telling the app to do whatever it is
// supposed to do that caused it to go out of the cached state.)
try {
ActivityManager.getService().registerUidObserver(mUidObserver,
ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE,
ActivityManager.PROCESS_STATE_UNKNOWN, null);
} catch (RemoteException e) {
// ignored; both services live in system_server
}
}
}
case MSG_SYSTEM_READY:
onSystemReady();
break;
public void onSystemReady() {
mSystemReady = true;
scheduleLoadSoundEffects();
mDeviceBroker.onSystemReady();
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
synchronized (mHdmiClientLock) {
mHdmiManager = mContext.getSystemService(HdmiControlManager.class);
if (mHdmiManager != null) {
mHdmiManager.addHdmiControlStatusChangeListener(
mHdmiControlStatusChangeListenerCallback);
mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(),
mMyHdmiCecVolumeControlFeatureListener);
}
mHdmiTvClient = mHdmiManager.getTvClient();
if (mHdmiTvClient != null) {
mFixedVolumeDevices.removeAll(
AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET);
}
mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
}
}
if (mSupportsMicPrivacyToggle) {
mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
if (userId == getCurrentUserId()) {
mMicMuteFromPrivacyToggle = enabled;
setMicrophoneMuteNoCallerCheck(getCurrentUserId());
}
});
}
mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
//定义了一个名为 SoundDoseHelper 的类,用于安全管理媒体音量,这里是去进行配置
mSoundDoseHelper.configureSafeMedia(/*forced=*/true, TAG);
initA11yMonitoring();
mRoleObserver = new RoleObserver();
mRoleObserver.register();
onIndicateSystemReady();
mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
setMicMuteFromSwitchInput();
initMinStreamVolumeWithoutModifyAudioSettings();
updateVibratorInfos();
synchronized (mSupportedSystemUsagesLock) {
AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
}
}
/*package*/ void configureSafeMedia(boolean forced, String caller) {
int msg = forced ? MSG_CONFIGURE_SAFE_MEDIA_FORCED : MSG_CONFIGURE_SAFE_MEDIA;
mAudioHandler.removeMessages(msg);
long time = 0;
if (forced) {
time = (SystemClock.uptimeMillis() + (SystemProperties.getBoolean(
"audio.safemedia.bypass", false) ? 0 : SAFE_VOLUME_CONFIGURE_TIMEOUT_MS));
}
mAudioHandler.sendMessageAtTime(
mAudioHandler.obtainMessage(msg, /*arg1=*/0, /*arg2=*/0, caller),
time);
}
case MSG_CONFIGURE_SAFE_MEDIA_FORCED:
case MSG_CONFIGURE_SAFE_MEDIA:
onConfigureSafeMedia((msg.what == MSG_CONFIGURE_SAFE_MEDIA_FORCED),
(String) msg.obj);
break;
//配置安全媒体音量索引和安全音量功能
private void onConfigureSafeMedia(boolean force, String caller) {
updateCsdEnabled(caller);
synchronized (mSafeMediaVolumeStateLock) {
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;
initSafeMediaVolumeIndex();
updateSafeMediaVolume_l(caller);
mMcc = mcc;
}
}
}
//最重要的地方,决定是否设置安全音量功能
private void updateSafeMediaVolume_l(String caller) {
boolean safeMediaVolumeEnabled =
SystemProperties.getBoolean(SYSTEM_PROPERTY_SAFEMEDIA_FORCE, false)
|| (mContext.getResources().getBoolean(
com.android.internal.R.bool.config_safe_media_volume_enabled)
&& !mEnableCsd.get());
boolean safeMediaVolumeBypass =
SystemProperties.getBoolean(SYSTEM_PROPERTY_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;
mLastMusicActiveTimeMs = 0;
}
}
} else {
//安全音量功能状态为关闭
persistedState = SAFE_MEDIA_VOLUME_DISABLED;
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
}
mAudioHandler.sendMessageAtTime(
mAudioHandler.obtainMessage(MSG_PERSIST_SAFE_VOLUME_STATE,
persistedState, /*arg2=*/0,
/*obj=*/null), /*delay=*/0);
}
关闭安全音量弹窗,将true改为false
/frameworks/base/core/res/res/values/config.xml
<!-- Whether safe headphone volume is enabled or not (country specific). -->
<bool name="config_safe_media_volume_enabled">true</bool>