Merge "Fix a race condition in SeekBarVolumizer." into nyc-dev
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 2445bc2..1ec00db 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -38,6 +38,8 @@
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
+import com.android.internal.annotations.GuardedBy;
+
/**
* Turns a {@link SeekBar} into a volume control.
* @hide
@@ -67,6 +69,10 @@
private Observer mVolumeObserver;
private int mOriginalStreamVolume;
private int mLastAudibleStreamVolume;
+ // When the old handler is destroyed and a new one is created, there could be a situation where
+ // this is accessed at the same time in different handlers. So, access to this field needs to be
+ // synchronized.
+ @GuardedBy("this")
private Ringtone mRingtone;
private int mLastProgress = -1;
private boolean mMuted;
@@ -174,9 +180,11 @@
}
private void onInitSample() {
- mRingtone = RingtoneManager.getRingtone(mContext, mDefaultUri);
- if (mRingtone != null) {
- mRingtone.setStreamType(mStreamType);
+ synchronized (this) {
+ mRingtone = RingtoneManager.getRingtone(mContext, mDefaultUri);
+ if (mRingtone != null) {
+ mRingtone.setStreamType(mStreamType);
+ }
}
}
@@ -192,16 +200,19 @@
if (mCallback != null) {
mCallback.onSampleStarting(this);
}
- if (mRingtone != null) {
- try {
- mRingtone.setAudioAttributes(new AudioAttributes.Builder(mRingtone
- .getAudioAttributes())
- .setFlags(AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY |
- AudioAttributes.FLAG_BYPASS_MUTE)
- .build());
- mRingtone.play();
- } catch (Throwable e) {
- Log.w(TAG, "Error playing ringtone, stream " + mStreamType, e);
+
+ synchronized (this) {
+ if (mRingtone != null) {
+ try {
+ mRingtone.setAudioAttributes(new AudioAttributes.Builder(mRingtone
+ .getAudioAttributes())
+ .setFlags(AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY |
+ AudioAttributes.FLAG_BYPASS_MUTE)
+ .build());
+ mRingtone.play();
+ } catch (Throwable e) {
+ Log.w(TAG, "Error playing ringtone, stream " + mStreamType, e);
+ }
}
}
}
@@ -216,8 +227,10 @@
}
private void onStopSample() {
- if (mRingtone != null) {
- mRingtone.stop();
+ synchronized (this) {
+ if (mRingtone != null) {
+ mRingtone.stop();
+ }
}
}
@@ -274,7 +287,9 @@
}
public boolean isSamplePlaying() {
- return mRingtone != null && mRingtone.isPlaying();
+ synchronized (this) {
+ return mRingtone != null && mRingtone.isPlaying();
+ }
}
public void startSample() {