Getting the value of the scenario mode: AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); final int ringerMode = audioManager.getRingerMode();
Conclusion: The ringerMode value will change after the user modifies the sound, and the vibration mode is changed to normal mode, silent mode or silent mode
The process is as follows
/frameworks/base/services/core/java/com/android/server/audio/AudioService.java private void setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings) { ... if (isAndroidNPlus(callingPackage) & amp; & amp; wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags)) & amp; & amp; !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) { throw new SecurityException("Not allowed to change Do Not Disturb state"); } ... }
private int getNewRingerMode(int stream, int index, int flags) { // setRingerMode does nothing if the device is single volume, so the value would be unchanged if (mIsSingleVolume) { return getRingerModeExternal(); } // setting volume on ui sounds stream type also controls silent mode if (((flags & amp; AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || (stream == getUiSoundsStreamType())) { int newRingerMode; //index volume size if (index == 0) { //volumeDownToEnterSilent Note allows the volume to be turned down from vibration to ring mode = silent newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT : AudioManager.RINGER_MODE_NORMAL; Log.w(TAG, "setMode() getNewRingerMode22:" + newRingerMode); } else { //When the sound is not 0, change to RINGER_MODE_NORMAL mode value=2 newRingerMode = AudioManager.RINGER_MODE_NORMAL; } return newRingerMode; } return getRingerModeExternal(); }
private void setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings) { ... if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { mVolumeController.postDisplaySafeVolumeWarning(flags); mPendingVolumeCommand = new StreamVolumeCommand( streamType, index, flags, device); } else { //reset volume onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings); index = mStreamStates[streamType].getIndex(device); } ... }
private void onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings) { final int stream = mStreamVolumeAlias[streamType]; setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings); // setting volume on ui sounds stream type also controls silent mode if (((flags & amp; AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || (stream == getUiSoundsStreamType())) { //Reset the mode and execute the getNewRingerMode method. According to the above analysis, the method returns the RINGER_MODE_NORMAL mode after execution. Modify the original mode. setRingerMode(getNewRingerMode(stream, index, flags), TAG + ".onSetStreamVolume", false /*external*/); } // setting non-zero volume for a muted stream unmutes the stream and vice versa, // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) { mStreamStates[stream].mute(index == 0); } }
private void setRingerMode(int ringerMode, String caller, boolean external) { if (mUseFixedVolume || mIsSingleVolume) { return; } if (caller == null || caller.length() == 0) { throw new IllegalArgumentException("Bad caller: " + caller); } ensureValidRingerMode(ringerMode); if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) & amp; & amp; !mHasVibrator) { ringerMode = AudioManager.RINGER_MODE_SILENT; } final long identity = Binder.clearCallingIdentity(); try { synchronized (mSettingsLock) { final int ringerModeInternal = getRingerModeInternal(); final int ringerModeExternal = getRingerModeExternal(); if (external) { setRingerModeExt(ringerMode); if (mRingerModeDelegate != null) { ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal, ringerMode, caller, ringerModeInternal, mVolumePolicy); } if (ringerMode != ringerModeInternal) { setRingerModeInt(ringerMode, true /*persist*/); } } else /*internal*/ { //Take the internal mode value ringerModeInternal, setRingerModeInt resets the settings.global data if (ringerMode != ringerModeInternal) { setRingerModeInt(ringerMode, true /*persist*/); } if (mRingerModeDelegate != null) { //The external value ringerModeExternal will be processed here, involving ZenMode ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal, ringerMode, caller, ringerModeExternal, mVolumePolicy); } //****Key points*** The ringmodel is reassigned here. The vibration mode is changed to RINGER_MODE_NORMAL, but the silent mode is still RINGER_MODE_SILENT. //At the beginning of this article, it was mentioned that the value of audioManager.getRingerMode() will change, which is basically clear. setRingerModeExt(ringerMode); } } } finally { Binder.restoreCallingIdentity(identity); } }
frameworks/base/services/core/java/com/android/server/notification/ZenModeHelper.java
@Override public int onSetRingerModeInternal(int ringerModeOld, int ringerModeNew, String caller, int ringerModeExternal, VolumePolicy policy) { final boolean isChange = ringerModeOld != ringerModeNew; int ringerModeExternalOut = ringerModeNew; if (mZenMode == Global.ZEN_MODE_OFF || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS & amp; & amp; !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(mConfig))) { // in priority only with ringer not muted, save ringer mode changes // in dnd off, save ringer mode changes setPreviousRingerModeSetting(ringerModeNew); } int newZen = -1; //Process the new ringmodel mode, because the method will change the mode to ringerModeNew==2==RINGER_MODE_NORMAL according to the volume change //Reprocess when RINGER_MODE_VIBRATE/RINGER_MODE_NORMAL switch (ringerModeNew) { case AudioManager.RINGER_MODE_SILENT: if (isChange & amp; & amp; policy.doNotDisturbWhenSilent) { if (mZenMode == Global.ZEN_MODE_OFF) { newZen = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; } setPreviousRingerModeSetting(ringerModeOld); } break; case AudioManager.RINGER_MODE_VIBRATE: case AudioManager.RINGER_MODE_NORMAL: if (isChange & amp; & amp; ringerModeOld == AudioManager.RINGER_MODE_SILENT & amp; & amp; (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS || mZenMode == Global.ZEN_MODE_ALARMS || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS & amp; & amp; ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted( mConfig)))) { newZen = Global.ZEN_MODE_OFF; } else if (mZenMode != Global.ZEN_MODE_OFF) { //If the active setting mode is silent mode, that is, RINGER_MODE_SILENT, although the volume value will be modified to RINGER_MODE_NORMAL, the incoming mZenMode value mZenMode==1==ZEN_MODE_IMPORTANT_INTERRUPTIONS //That is, ringerModeExternalOut==0 will be reset. This is the difference. //Can log when the set mode is not RINGER_MODE_SILENT, mZenMode is also different ringerModeExternalOut = AudioManager.RINGER_MODE_SILENT; } break; } if (newZen != -1) { setManualZenMode(newZen, null, "ringerModeInternal", null, false /*setRingerMode*/); } if (isChange || newZen != -1 || ringerModeExternal != ringerModeExternalOut) { ZenLog.traceSetRingerModeInternal(ringerModeOld, ringerModeNew, caller, ringerModeExternal, ringerModeExternalOut); } return ringerModeExternalOut; }
There is also an adjustStreamVolume volume increment method to set the volume.
protected void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, int keyEventMode) { ... if (((flags & amp; AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || (streamTypeAlias == getUiSoundsStreamType())) { int ringerMode = getRingerModeInternal(); // do not vibrate if already in vibrate mode if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { flags & amp;= ~AudioManager.FLAG_VIBRATE; } // Check if the ringer mode handles this adjustment. If it does we don't // need to adjust the volume further. //Check whether the mode needs to be modified final int result = checkForRingerModeChange(aliasIndex, direction, step, streamState.mIsMuted, callingPackage, flags); adjustVolume = (result & amp; FLAG_ADJUST_VOLUME) != 0; // If suppressing a volume adjustment in silent mode, display the UI hint if ((result & amp; AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { flags |= AudioManager.FLAG_SHOW_SILENT_HINT; } // If suppressing a volume down adjustment in vibrate mode, display the UI hint if ((result & amp; AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) { flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; } } ... } private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags) { int result = FLAG_ADJUST_VOLUME; if (isPlatformTelevision() || mIsSingleVolume) { return result; } int ringerMode = getRingerModeInternal(); switch (ringerMode) { case RINGER_MODE_NORMAL://Normal mode if (direction == AudioManager.ADJUST_LOWER) { if (mHasVibrator) { // "step" is the delta in internal index units corresponding to a // change of 1 in UI index units. // Because of rounding when rescaling from one stream index range to its alias // index range, we cannot simply test oldIndex == step: // (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1) if (step <= oldIndex & amp; & amp; oldIndex < 2 * step) { ringerMode = RINGER_MODE_VIBRATE; mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis(); } } else { if (oldIndex == step & amp; & amp; mVolumePolicy.volumeDownToEnterSilent) { ringerMode = RINGER_MODE_SILENT; } } } else if (mIsSingleVolume & amp; & amp; (direction == AudioManager.ADJUST_TOGGLE_MUTE || direction == AudioManager.ADJUST_MUTE)) { if (mHasVibrator) { ringerMode = RINGER_MODE_VIBRATE; } else { ringerMode = RINGER_MODE_SILENT; } // Setting the ringer mode will toggle mute result & amp;= ~FLAG_ADJUST_VOLUME; } break; case RINGER_MODE_VIBRATE://Vibration mode if (!mHasVibrator) { Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" + "but no vibrator is present"); break; } if ((direction == AudioManager.ADJUST_LOWER)) { // This is the case we were muted with the volume turned up if (mIsSingleVolume & amp; & amp; oldIndex >= 2 * step & amp; & amp; isMuted) { ringerMode = RINGER_MODE_NORMAL; } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { if (mVolumePolicy.volumeDownToEnterSilent) { final long diff = SystemClock.uptimeMillis() - mLoweredFromNormalToVibrateTime; if (diff > mVolumePolicy.vibrateToSilentDebounce & amp; & amp; mRingerModeDelegate.canVolumeDownEnterSilent()) { ringerMode = RINGER_MODE_SILENT; } } else { result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; } } } else if (direction == AudioManager.ADJUST_RAISE || direction == AudioManager.ADJUST_TOGGLE_MUTE || direction == AudioManager.ADJUST_UNMUTE) { //*****When set to vibration mode, direction == AudioManager.ADJUST_UNMUTE is satisfied, so ringerMode is modified** ringerMode = RINGER_MODE_NORMAL; } result & amp;= ~FLAG_ADJUST_VOLUME; break; case RINGER_MODE_SILENT://Silent mode if (mIsSingleVolume & amp; & amp; direction == AudioManager.ADJUST_LOWER & amp; & amp; oldIndex >= 2 * step & amp; & amp; isMuted) { // This is the case we were muted with the volume turned up ringerMode = RINGER_MODE_NORMAL; } else if (direction == AudioManager.ADJUST_RAISE || direction == AudioManager.ADJUST_TOGGLE_MUTE || direction == AudioManager.ADJUST_UNMUTE) { if (!mVolumePolicy.volumeUpToExitSilent) { //******When set to silent mode, volumeUpToExitSilent is false and ringerMode is not modified** result |= AudioManager.FLAG_SHOW_SILENT_HINT; } else { if (mHasVibrator & amp; & amp; direction == AudioManager.ADJUST_RAISE) { ringerMode = RINGER_MODE_VIBRATE; } else { // If we don't have a vibrator or they were toggling mute // go straight back to normal. ringerMode = RINGER_MODE_NORMAL; } } } result &= ~FLAG_ADJUST_VOLUME; break; default: Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: " + ringerMode); break; } if (isAndroidNPlus(caller) & amp; & amp; wouldToggleZenMode(ringerMode) & amp; & amp; !mNm.isNotificationPolicyAccessGrantedForPackage(caller) & amp; & amp; (flags & amp; AudioManager.FLAG_FROM_KEY) == 0) { throw new SecurityException("Not allowed to change Do Not Disturb state"); } //Enter mode modification setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/); mPrevVolDirection = direction; return result; }
volumeUpToExitSilent description:
/frameworks/base/media/java/android/media/VolumePolicy.java
public final class VolumePolicy implements Parcelable { public static final VolumePolicy DEFAULT = new VolumePolicy(false, false, false, 400); public VolumePolicy(boolean volumeDownToEnterSilent, boolean volumeUpToExitSilent, boolean doNotDisturbWhenSilent, int vibrateToSilentDebounce) { this.volumeDownToEnterSilent = volumeDownToEnterSilent; this.volumeUpToExitSilent = volumeUpToExitSilent;//is set to false this.doNotDisturbWhenSilent = doNotDisturbWhenSilent; this.vibrateToSilentDebounce = vibrateToSilentDebounce; } }
The difference between ringerModeInternal and ringerModeExternal
ringerModeInternal gets: adb shell settings get global mode_ringer
ringerModeExternal gets: audioManager.getRingerMode()
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Algorithm skill tree Home page Overview 56888 people are learning the system