summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--media/java/android/media/AudioService.java89
1 files changed, 54 insertions, 35 deletions
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 093b1086e307..8a3fd7ab931b 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -145,7 +145,8 @@ public class AudioService extends IAudioService.Stub {
private SettingsObserver mSettingsObserver;
private int mMode;
- private Object mSettingsLock = new Object();
+ // protects mRingerMode
+ private final Object mSettingsLock = new Object();
private boolean mMediaServerOk;
private SoundPool mSoundPool;
@@ -236,6 +237,7 @@ public class AudioService extends IAudioService.Stub {
* {@link AudioManager#RINGER_MODE_SILENT}, or
* {@link AudioManager#RINGER_MODE_VIBRATE}.
*/
+ // protected by mSettingsLock
private int mRingerMode;
/** @see System#MODE_RINGER_STREAMS_AFFECTED */
@@ -442,12 +444,15 @@ public class AudioService extends IAudioService.Stub {
private void readPersistedSettings() {
final ContentResolver cr = mContentResolver;
- mRingerMode = System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
+ int ringerMode = System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
// sanity check in case the settings are restored from a device with incompatible
// ringer modes
- if (!AudioManager.isValidRingerMode(mRingerMode)) {
- mRingerMode = AudioManager.RINGER_MODE_NORMAL;
- System.putInt(cr, System.MODE_RINGER, mRingerMode);
+ if (!AudioManager.isValidRingerMode(ringerMode)) {
+ ringerMode = AudioManager.RINGER_MODE_NORMAL;
+ System.putInt(cr, System.MODE_RINGER, ringerMode);
+ }
+ synchronized(mSettingsLock) {
+ mRingerMode = ringerMode;
}
mVibrateSetting = System.getInt(cr, System.VIBRATE_ON, 0);
@@ -473,7 +478,7 @@ public class AudioService extends IAudioService.Stub {
// Each stream will read its own persisted settings
// Broadcast the sticky intent
- broadcastRingerMode();
+ broadcastRingerMode(ringerMode);
// Broadcast vibrate settings
broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
@@ -538,8 +543,9 @@ public class AudioService extends IAudioService.Stub {
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
streamTypeAlias == AudioSystem.STREAM_RING ||
(!mVoiceCapable && streamTypeAlias == AudioSystem.STREAM_MUSIC)) {
+ int ringerMode = getRingerMode();
// do not vibrate if already in vibrate mode
- if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
+ if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
flags &= ~AudioManager.FLAG_VIBRATE;
}
// Check if the ringer mode changes with this volume adjustment. If
@@ -599,7 +605,7 @@ public class AudioService extends IAudioService.Stub {
// setting ring or notifications volume to 0 on voice capable devices enters silent mode
if (mVoiceCapable && (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
(STREAM_VOLUME_ALIAS[streamType] == AudioSystem.STREAM_RING))) {
- int newRingerMode = mRingerMode;
+ int newRingerMode;
if (index == 0) {
newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
? AudioManager.RINGER_MODE_VIBRATE
@@ -608,9 +614,7 @@ public class AudioService extends IAudioService.Stub {
} else {
newRingerMode = AudioManager.RINGER_MODE_NORMAL;
}
- if (newRingerMode != mRingerMode) {
- setRingerMode(newRingerMode);
- }
+ setRingerMode(newRingerMode);
}
index = rescaleIndex(index * 10, streamType, STREAM_VOLUME_ALIAS[streamType]);
@@ -722,22 +726,31 @@ public class AudioService extends IAudioService.Stub {
/** @see AudioManager#getRingerMode() */
public int getRingerMode() {
- return mRingerMode;
+ synchronized(mSettingsLock) {
+ return mRingerMode;
+ }
+ }
+
+ private void ensureValidRingerMode(int ringerMode) {
+ if (!AudioManager.isValidRingerMode(ringerMode)) {
+ throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
+ }
}
/** @see AudioManager#setRingerMode(int) */
public void setRingerMode(int ringerMode) {
- synchronized (mSettingsLock) {
- if (ringerMode != mRingerMode) {
- setRingerModeInt(ringerMode, true);
- // Send sticky broadcast
- broadcastRingerMode();
- }
+ ensureValidRingerMode(ringerMode);
+ if (ringerMode != getRingerMode()) {
+ setRingerModeInt(ringerMode, true);
+ // Send sticky broadcast
+ broadcastRingerMode(ringerMode);
}
}
private void setRingerModeInt(int ringerMode, boolean persist) {
- mRingerMode = ringerMode;
+ synchronized(mSettingsLock) {
+ mRingerMode = ringerMode;
+ }
// Mute stream if not previously muted by ringer mode and ringer mode
// is not RINGER_MODE_NORMAL and stream is affected by ringer mode.
@@ -747,7 +760,7 @@ public class AudioService extends IAudioService.Stub {
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
if (isStreamMutedByRingerMode(streamType)) {
if (!isStreamAffectedByRingerMode(streamType) ||
- mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
+ ringerMode == AudioManager.RINGER_MODE_NORMAL) {
// ring and notifications volume should never be 0 when not silenced
// on voice capable devices
if (mVoiceCapable &&
@@ -760,7 +773,7 @@ public class AudioService extends IAudioService.Stub {
}
} else {
if (isStreamAffectedByRingerMode(streamType) &&
- mRingerMode != AudioManager.RINGER_MODE_NORMAL) {
+ ringerMode != AudioManager.RINGER_MODE_NORMAL) {
mStreamStates[streamType].mute(null, true);
mRingerModeMutedStreams |= (1 << streamType);
}
@@ -780,10 +793,10 @@ public class AudioService extends IAudioService.Stub {
switch (getVibrateSetting(vibrateType)) {
case AudioManager.VIBRATE_SETTING_ON:
- return mRingerMode != AudioManager.RINGER_MODE_SILENT;
+ return getRingerMode() != AudioManager.RINGER_MODE_SILENT;
case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
- return mRingerMode == AudioManager.RINGER_MODE_VIBRATE;
+ return getRingerMode() == AudioManager.RINGER_MODE_VIBRATE;
case AudioManager.VIBRATE_SETTING_OFF:
// return false, even for incoming calls
@@ -1688,11 +1701,12 @@ public class AudioService extends IAudioService.Stub {
*/
private boolean checkForRingerModeChange(int oldIndex, int direction, int streamType) {
boolean adjustVolumeIndex = true;
- int newRingerMode = mRingerMode;
+ int ringerMode = getRingerMode();
+ int newRingerMode = ringerMode;
int uiIndex = (oldIndex + 5) / 10;
boolean vibeInSilent = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1;
- if (mRingerMode == RINGER_MODE_NORMAL) {
+ if (ringerMode == RINGER_MODE_NORMAL) {
if ((direction == AudioManager.ADJUST_LOWER) && (uiIndex <= 1)) {
// enter silent mode if current index is the last audible one and not repeating a
// volume key down
@@ -1707,7 +1721,7 @@ public class AudioService extends IAudioService.Stub {
adjustVolumeIndex = false;
}
}
- } else if (mRingerMode == RINGER_MODE_VIBRATE) {
+ } else if (ringerMode == RINGER_MODE_VIBRATE) {
if ((direction == AudioManager.ADJUST_LOWER)) {
// Set it to silent, if it wasn't a long-press
if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
@@ -1726,9 +1740,7 @@ public class AudioService extends IAudioService.Stub {
adjustVolumeIndex = false;
}
- if (newRingerMode != mRingerMode) {
- setRingerMode(newRingerMode);
- }
+ setRingerMode(newRingerMode);
mPrevVolDirection = direction;
@@ -1818,10 +1830,10 @@ public class AudioService extends IAudioService.Stub {
}
}
- private void broadcastRingerMode() {
+ private void broadcastRingerMode(int ringerMode) {
// Send sticky broadcast
Intent broadcast = new Intent(AudioManager.RINGER_MODE_CHANGED_ACTION);
- broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, mRingerMode);
+ broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode);
broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_REPLACE_PENDING);
long origCallerIdentityToken = Binder.clearCallingIdentity();
@@ -2013,7 +2025,8 @@ public class AudioService extends IAudioService.Stub {
if (muteCount() == 0) {
// If the stream is not muted any more, restore it's volume if
// ringer mode allows it
- if (!isStreamAffectedByRingerMode(mStreamType) || mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
+ if (!isStreamAffectedByRingerMode(mStreamType) ||
+ getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
setIndex(mLastAudibleIndex, false);
sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, SENDMSG_NOOP, 0, 0,
VolumeStreamState.this, 0);
@@ -2131,8 +2144,8 @@ public class AudioService extends IAudioService.Stub {
}
}
- private void persistRingerMode() {
- System.putInt(mContentResolver, System.MODE_RINGER, mRingerMode);
+ private void persistRingerMode(int ringerMode) {
+ System.putInt(mContentResolver, System.MODE_RINGER, ringerMode);
}
private void persistVibrateSetting() {
@@ -2219,7 +2232,9 @@ public class AudioService extends IAudioService.Stub {
break;
case MSG_PERSIST_RINGER_MODE:
- persistRingerMode();
+ // note that the value persisted is the current ringer mode, not the
+ // value of ringer mode as of the time the request was made to persist
+ persistRingerMode(getRingerMode());
break;
case MSG_PERSIST_VIBRATE_SETTING:
@@ -2335,6 +2350,10 @@ public class AudioService extends IAudioService.Stub {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
+ // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
+ // However there appear to be some missing locks around mRingerModeMutedStreams
+ // and mRingerModeAffectedStreams, so will leave this synchronized for now.
+ // mRingerModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
synchronized (mSettingsLock) {
int ringerModeAffectedStreams = Settings.System.getInt(mContentResolver,
Settings.System.MODE_RINGER_STREAMS_AFFECTED,