Skip to content

Commit 05274f3

Browse files
author
Eric Laurent
committed
AudioService: improve initial safe volume delay
AudioService relies on a valid mmc in order to enforce the headset volume limitation or not. There is a timeout to enforce the limitation if no mcc is configured after boot. Until this timeout is reached or a valid SIM is detected the headset volume is not limited. This change makes that the last known volume limitation state (enforced or not) is persisted so that next time we boot, last known state is applied until a new mcc is configured if any. In most cases, the mcc does not change from one boot to the next and we do the right thing. If teh mcc does change, the correct policy will be enforced when the mcc is detected or after the timeout. Also fix a bug where the volume panel was not displayed if the limitation mechanism is triggered at the first press on VOL+ key. Bug 7455275. Change-Id: Id0f2996d893d38c6a14f4f9e4a0e9e3be17ef127
1 parent 89ac38b commit 05274f3

File tree

2 files changed

+103
-61
lines changed

2 files changed

+103
-61
lines changed

core/java/android/provider/Settings.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5314,6 +5314,12 @@ public static final String getBluetoothInputDevicePriorityKey(String address) {
53145314
*/
53155315
public static final String DOCK_AUDIO_MEDIA_ENABLED = "dock_audio_media_enabled";
53165316

5317+
/**
5318+
* Persisted safe headphone volume management state by AudioService
5319+
* @hide
5320+
*/
5321+
public static final String AUDIO_SAFE_VOLUME_STATE = "audio_safe_volume_state";
5322+
53175323
/**
53185324
* Settings to backup. This is here so that it's in the same place as the settings
53195325
* keys and easy to update.

media/java/android/media/AudioService.java

Lines changed: 97 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
157157
private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 25;
158158
private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 26;
159159
private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 27;
160+
private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 28;
160161

161162
// flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
162163
// persisted
@@ -481,15 +482,21 @@ public AudioService(Context context) {
481482
null,
482483
0);
483484

485+
mSafeMediaVolumeState = new Integer(Settings.Global.getInt(mContentResolver,
486+
Settings.Global.AUDIO_SAFE_VOLUME_STATE,
487+
SAFE_MEDIA_VOLUME_NOT_CONFIGURED));
488+
// The default safe volume index read here will be replaced by the actual value when
489+
// the mcc is read by onConfigureSafeVolume()
490+
mSafeMediaVolumeIndex = mContext.getResources().getInteger(
491+
com.android.internal.R.integer.config_safe_media_volume_index) * 10;
492+
484493
readPersistedSettings();
485494
mSettingsObserver = new SettingsObserver();
486495
updateStreamVolumeAlias(false /*updateVolumes*/);
487496
createStreamStates();
488497

489498
mMediaServerOk = true;
490499

491-
mSafeMediaVolumeState = new Integer(SAFE_MEDIA_VOLUME_NOT_CONFIGURED);
492-
493500
// Call setRingerModeInt() to apply correct mute
494501
// state on streams affected by ringer mode.
495502
mRingerModeMutedStreams = 0;
@@ -822,70 +829,72 @@ public void adjustStreamVolume(int streamType, int direction, int flags) {
822829
// convert one UI step (+/-1) into a number of internal units on the stream alias
823830
int step = rescaleIndex(10, streamType, streamTypeAlias);
824831

825-
if ((direction == AudioManager.ADJUST_RAISE) &&
826-
!checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
827-
return;
828-
}
829-
830832
int index;
831833
int oldIndex;
832834

833-
flags &= ~AudioManager.FLAG_FIXED_VOLUME;
834-
if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
835-
((device & mFixedVolumeDevices) != 0)) {
836-
flags |= AudioManager.FLAG_FIXED_VOLUME;
837-
index = mStreamStates[streamType].getMaxIndex();
835+
if ((direction == AudioManager.ADJUST_RAISE) &&
836+
!checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
837+
index = mStreamStates[streamType].getIndex(device,
838+
(streamState.muteCount() != 0) /* lastAudible */);
838839
oldIndex = index;
839840
} else {
840-
// If either the client forces allowing ringer modes for this adjustment,
841-
// or the stream type is one that is affected by ringer modes
842-
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
843-
(streamTypeAlias == getMasterStreamType())) {
844-
int ringerMode = getRingerMode();
845-
// do not vibrate if already in vibrate mode
846-
if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
847-
flags &= ~AudioManager.FLAG_VIBRATE;
848-
}
849-
// Check if the ringer mode changes with this volume adjustment. If
850-
// it does, it will handle adjusting the volume, so we won't below
851-
adjustVolume = checkForRingerModeChange(aliasIndex, direction, step);
852-
if ((streamTypeAlias == getMasterStreamType()) &&
853-
(mRingerMode == AudioManager.RINGER_MODE_SILENT)) {
854-
streamState.setLastAudibleIndex(0, device);
855-
}
856-
}
857-
858-
// If stream is muted, adjust last audible index only
859-
oldIndex = mStreamStates[streamType].getIndex(device,
860-
(mStreamStates[streamType].muteCount() != 0) /* lastAudible */);
861-
862-
if (streamState.muteCount() != 0) {
863-
if (adjustVolume) {
864-
// Post a persist volume msg
865-
// no need to persist volume on all streams sharing the same alias
866-
streamState.adjustLastAudibleIndex(direction * step, device);
867-
sendMsg(mAudioHandler,
868-
MSG_PERSIST_VOLUME,
869-
SENDMSG_QUEUE,
870-
PERSIST_LAST_AUDIBLE,
871-
device,
872-
streamState,
873-
PERSIST_DELAY);
874-
}
875-
index = mStreamStates[streamType].getIndex(device, true /* lastAudible */);
841+
flags &= ~AudioManager.FLAG_FIXED_VOLUME;
842+
if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
843+
((device & mFixedVolumeDevices) != 0)) {
844+
flags |= AudioManager.FLAG_FIXED_VOLUME;
845+
index = mStreamStates[streamType].getMaxIndex();
846+
oldIndex = index;
876847
} else {
877-
if (adjustVolume && streamState.adjustIndex(direction * step, device)) {
878-
// Post message to set system volume (it in turn will post a message
879-
// to persist). Do not change volume if stream is muted.
880-
sendMsg(mAudioHandler,
881-
MSG_SET_DEVICE_VOLUME,
882-
SENDMSG_QUEUE,
883-
device,
884-
0,
885-
streamState,
886-
0);
848+
// If either the client forces allowing ringer modes for this adjustment,
849+
// or the stream type is one that is affected by ringer modes
850+
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
851+
(streamTypeAlias == getMasterStreamType())) {
852+
int ringerMode = getRingerMode();
853+
// do not vibrate if already in vibrate mode
854+
if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
855+
flags &= ~AudioManager.FLAG_VIBRATE;
856+
}
857+
// Check if the ringer mode changes with this volume adjustment. If
858+
// it does, it will handle adjusting the volume, so we won't below
859+
adjustVolume = checkForRingerModeChange(aliasIndex, direction, step);
860+
if ((streamTypeAlias == getMasterStreamType()) &&
861+
(mRingerMode == AudioManager.RINGER_MODE_SILENT)) {
862+
streamState.setLastAudibleIndex(0, device);
863+
}
864+
}
865+
866+
// If stream is muted, adjust last audible index only
867+
oldIndex = mStreamStates[streamType].getIndex(device,
868+
(mStreamStates[streamType].muteCount() != 0) /* lastAudible */);
869+
870+
if (streamState.muteCount() != 0) {
871+
if (adjustVolume) {
872+
// Post a persist volume msg
873+
// no need to persist volume on all streams sharing the same alias
874+
streamState.adjustLastAudibleIndex(direction * step, device);
875+
sendMsg(mAudioHandler,
876+
MSG_PERSIST_VOLUME,
877+
SENDMSG_QUEUE,
878+
PERSIST_LAST_AUDIBLE,
879+
device,
880+
streamState,
881+
PERSIST_DELAY);
882+
}
883+
index = mStreamStates[streamType].getIndex(device, true /* lastAudible */);
884+
} else {
885+
if (adjustVolume && streamState.adjustIndex(direction * step, device)) {
886+
// Post message to set system volume (it in turn will post a message
887+
// to persist). Do not change volume if stream is muted.
888+
sendMsg(mAudioHandler,
889+
MSG_SET_DEVICE_VOLUME,
890+
SENDMSG_QUEUE,
891+
device,
892+
0,
893+
streamState,
894+
0);
895+
}
896+
index = mStreamStates[streamType].getIndex(device, false /* lastAudible */);
887897
}
888-
index = mStreamStates[streamType].getIndex(device, false /* lastAudible */);
889898
}
890899
}
891900
sendVolumeUpdate(streamType, oldIndex, index, flags);
@@ -2306,13 +2315,31 @@ private void onConfigureSafeVolume(boolean force) {
23062315
com.android.internal.R.integer.config_safe_media_volume_index) * 10;
23072316
boolean safeMediaVolumeEnabled = mContext.getResources().getBoolean(
23082317
com.android.internal.R.bool.config_safe_media_volume_enabled);
2318+
2319+
// The persisted state is either "disabled" or "active": this is the state applied
2320+
// next time we boot and cannot be "inactive"
2321+
int persistedState;
23092322
if (safeMediaVolumeEnabled) {
2310-
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
2311-
enforceSafeMediaVolume();
2323+
persistedState = SAFE_MEDIA_VOLUME_ACTIVE;
2324+
// The state can already be "inactive" here if the user has forced it before
2325+
// the 30 seconds timeout for forced configuration. In this case we don't reset
2326+
// it to "active".
2327+
if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) {
2328+
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
2329+
enforceSafeMediaVolume();
2330+
}
23122331
} else {
2332+
persistedState = SAFE_MEDIA_VOLUME_DISABLED;
23132333
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
23142334
}
23152335
mMcc = mcc;
2336+
sendMsg(mAudioHandler,
2337+
MSG_PERSIST_SAFE_VOLUME_STATE,
2338+
SENDMSG_QUEUE,
2339+
persistedState,
2340+
0,
2341+
null,
2342+
0);
23162343
}
23172344
}
23182345
}
@@ -3224,6 +3251,12 @@ private void setForceUse(int usage, int config) {
32243251
AudioSystem.setForceUse(usage, config);
32253252
}
32263253

3254+
private void onPersistSafeVolumeState(int state) {
3255+
Settings.Global.putInt(mContentResolver,
3256+
Settings.Global.AUDIO_SAFE_VOLUME_STATE,
3257+
state);
3258+
}
3259+
32273260
@Override
32283261
public void handleMessage(Message msg) {
32293262

@@ -3433,6 +3466,9 @@ public void handleMessage(Message msg) {
34333466
case MSG_CONFIGURE_SAFE_MEDIA_VOLUME:
34343467
onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED));
34353468
break;
3469+
case MSG_PERSIST_SAFE_VOLUME_STATE:
3470+
onPersistSafeVolumeState(msg.arg1);
3471+
break;
34363472
}
34373473
}
34383474
}

0 commit comments

Comments
 (0)