174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock/*
274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * Copyright (C) 2014 The Android Open Source Project
374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock *
474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * Licensed under the Apache License, Version 2.0 (the "License");
574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * you may not use this file except in compliance with the License.
674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * You may obtain a copy of the License at
774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock *
874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock *      http://www.apache.org/licenses/LICENSE-2.0
974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock *
1074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * Unless required by applicable law or agreed to in writing, software
1174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * distributed under the License is distributed on an "AS IS" BASIS,
1274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * See the License for the specific language governing permissions and
1474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * limitations under the License.
1574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock */
1674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
1774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockpackage android.preference;
1874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
1996d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlockimport android.app.NotificationManager;
200dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlockimport android.content.BroadcastReceiver;
2174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.content.Context;
220dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlockimport android.content.Intent;
230dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlockimport android.content.IntentFilter;
2474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.database.ContentObserver;
25bbfd31a5d4f126167e20fa8bd256c810cf8c2c85John Spurlockimport android.media.AudioAttributes;
2674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.media.AudioManager;
2774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.media.Ringtone;
2874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.media.RingtoneManager;
2974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.net.Uri;
3074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.os.Handler;
3174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.os.HandlerThread;
3274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.os.Message;
3374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.preference.VolumePreference.VolumeStore;
3474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.provider.Settings;
3596d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlockimport android.provider.Settings.Global;
3674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.provider.Settings.System;
3774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.util.Log;
3874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.widget.SeekBar;
3974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockimport android.widget.SeekBar.OnSeekBarChangeListener;
4074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
4174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock/**
4274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * Turns a {@link SeekBar} into a volume control.
4374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock * @hide
4474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock */
4574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlockpublic class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callback {
4695caba127051845ff1e26d7e64909db89408e8e7John Spurlock    private static final String TAG = "SeekBarVolumizer";
4774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
4874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public interface Callback {
4974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        void onSampleStarting(SeekBarVolumizer sbv);
50bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch);
5196d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        void onMuted(boolean muted, boolean zenMuted);
5274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
5374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
5495caba127051845ff1e26d7e64909db89408e8e7John Spurlock    private final Context mContext;
550dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock    private final H mUiHandler = new H();
5674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private final Callback mCallback;
5795caba127051845ff1e26d7e64909db89408e8e7John Spurlock    private final Uri mDefaultUri;
5895caba127051845ff1e26d7e64909db89408e8e7John Spurlock    private final AudioManager mAudioManager;
5996d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock    private final NotificationManager mNotificationManager;
6095caba127051845ff1e26d7e64909db89408e8e7John Spurlock    private final int mStreamType;
6195caba127051845ff1e26d7e64909db89408e8e7John Spurlock    private final int mMaxStreamVolume;
62bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    private boolean mAffectedByRingerMode;
63bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    private boolean mNotificationOrRing;
640dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock    private final Receiver mReceiver = new Receiver();
6574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
660e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock    private Handler mHandler;
670e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock    private Observer mVolumeObserver;
6874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private int mOriginalStreamVolume;
6996d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock    private int mLastAudibleStreamVolume;
7074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private Ringtone mRingtone;
7174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private int mLastProgress = -1;
72bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    private boolean mMuted;
7374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private SeekBar mSeekBar;
7474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private int mVolumeBeforeMute = -1;
75bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    private int mRingerMode;
7696d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock    private int mZenMode;
7774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
7874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private static final int MSG_SET_STREAM_VOLUME = 0;
7974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private static final int MSG_START_SAMPLE = 1;
8074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private static final int MSG_STOP_SAMPLE = 2;
8195caba127051845ff1e26d7e64909db89408e8e7John Spurlock    private static final int MSG_INIT_SAMPLE = 3;
8274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private static final int CHECK_RINGTONE_PLAYBACK_DELAY_MS = 1000;
8374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
84bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) {
8574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mContext = context;
8696d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        mAudioManager = context.getSystemService(AudioManager.class);
8796d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        mNotificationManager = context.getSystemService(NotificationManager.class);
8874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mStreamType = streamType;
89bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        mAffectedByRingerMode = mAudioManager.isStreamAffectedByRingerMode(mStreamType);
90bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        mNotificationOrRing = isNotificationOrRing(mStreamType);
91bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        if (mNotificationOrRing) {
92bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            mRingerMode = mAudioManager.getRingerModeInternal();
93bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        }
9496d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        mZenMode = mNotificationManager.getZenMode();
9595caba127051845ff1e26d7e64909db89408e8e7John Spurlock        mMaxStreamVolume = mAudioManager.getStreamMaxVolume(mStreamType);
9674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mCallback = callback;
9774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType);
9896d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        mLastAudibleStreamVolume = mAudioManager.getLastAudibleStreamVolume(mStreamType);
99bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        mMuted = mAudioManager.isStreamMute(mStreamType);
100bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        if (mCallback != null) {
10196d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock            mCallback.onMuted(mMuted, isZenMuted());
102bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        }
10374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        if (defaultUri == null) {
10474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            if (mStreamType == AudioManager.STREAM_RING) {
10574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                defaultUri = Settings.System.DEFAULT_RINGTONE_URI;
10674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            } else if (mStreamType == AudioManager.STREAM_NOTIFICATION) {
10774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI;
10874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            } else {
10974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                defaultUri = Settings.System.DEFAULT_ALARM_ALERT_URI;
11074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            }
11174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        }
11295caba127051845ff1e26d7e64909db89408e8e7John Spurlock        mDefaultUri = defaultUri;
11395caba127051845ff1e26d7e64909db89408e8e7John Spurlock    }
11474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
115bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    private static boolean isNotificationOrRing(int stream) {
116bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION;
117bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    }
118bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock
11995caba127051845ff1e26d7e64909db89408e8e7John Spurlock    public void setSeekBar(SeekBar seekBar) {
1200dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        if (mSeekBar != null) {
1210dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            mSeekBar.setOnSeekBarChangeListener(null);
1220dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        }
12395caba127051845ff1e26d7e64909db89408e8e7John Spurlock        mSeekBar = seekBar;
12495caba127051845ff1e26d7e64909db89408e8e7John Spurlock        mSeekBar.setOnSeekBarChangeListener(null);
12595caba127051845ff1e26d7e64909db89408e8e7John Spurlock        mSeekBar.setMax(mMaxStreamVolume);
126bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        updateSeekBar();
12795caba127051845ff1e26d7e64909db89408e8e7John Spurlock        mSeekBar.setOnSeekBarChangeListener(this);
12874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
12974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
13096d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock    private boolean isZenMuted() {
13196d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        return mNotificationOrRing && mZenMode == Global.ZEN_MODE_ALARMS
13296d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock                || mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
13396d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock    }
13496d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock
135bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    protected void updateSeekBar() {
13696d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        final boolean zenMuted = isZenMuted();
13796d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        mSeekBar.setEnabled(!zenMuted);
13896d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        if (zenMuted) {
13996d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock            mSeekBar.setProgress(mLastAudibleStreamVolume);
14096d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        } else if (mNotificationOrRing && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
141bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            mSeekBar.setProgress(0);
142bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        } else if (mMuted) {
143bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            mSeekBar.setProgress(0);
144bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        } else {
145bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            mSeekBar.setProgress(mLastProgress > -1 ? mLastProgress : mOriginalStreamVolume);
146bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        }
147bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    }
148bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock
14974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    @Override
15074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public boolean handleMessage(Message msg) {
15174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        switch (msg.what) {
15274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            case MSG_SET_STREAM_VOLUME:
153721d457685cc83785d0d0aad259e3218af899fc9John Spurlock                if (mMuted && mLastProgress > 0) {
154721d457685cc83785d0d0aad259e3218af899fc9John Spurlock                    mAudioManager.adjustStreamVolume(mStreamType, AudioManager.ADJUST_UNMUTE, 0);
155721d457685cc83785d0d0aad259e3218af899fc9John Spurlock                } else if (!mMuted && mLastProgress == 0) {
156721d457685cc83785d0d0aad259e3218af899fc9John Spurlock                    mAudioManager.adjustStreamVolume(mStreamType, AudioManager.ADJUST_MUTE, 0);
157721d457685cc83785d0d0aad259e3218af899fc9John Spurlock                }
158351346092acdfbfcc1d9ebf98d539d2a1196c5e8John Spurlock                mAudioManager.setStreamVolume(mStreamType, mLastProgress,
159351346092acdfbfcc1d9ebf98d539d2a1196c5e8John Spurlock                        AudioManager.FLAG_SHOW_UI_WARNINGS);
16074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                break;
16174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            case MSG_START_SAMPLE:
16274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                onStartSample();
16374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                break;
16474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            case MSG_STOP_SAMPLE:
16574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                onStopSample();
16674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                break;
16795caba127051845ff1e26d7e64909db89408e8e7John Spurlock            case MSG_INIT_SAMPLE:
16895caba127051845ff1e26d7e64909db89408e8e7John Spurlock                onInitSample();
16995caba127051845ff1e26d7e64909db89408e8e7John Spurlock                break;
17074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            default:
17195caba127051845ff1e26d7e64909db89408e8e7John Spurlock                Log.e(TAG, "invalid SeekBarVolumizer message: "+msg.what);
17274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        }
17374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        return true;
17474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
17574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
17695caba127051845ff1e26d7e64909db89408e8e7John Spurlock    private void onInitSample() {
17795caba127051845ff1e26d7e64909db89408e8e7John Spurlock        mRingtone = RingtoneManager.getRingtone(mContext, mDefaultUri);
17895caba127051845ff1e26d7e64909db89408e8e7John Spurlock        if (mRingtone != null) {
17995caba127051845ff1e26d7e64909db89408e8e7John Spurlock            mRingtone.setStreamType(mStreamType);
18095caba127051845ff1e26d7e64909db89408e8e7John Spurlock        }
18195caba127051845ff1e26d7e64909db89408e8e7John Spurlock    }
18295caba127051845ff1e26d7e64909db89408e8e7John Spurlock
18374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private void postStartSample() {
184735f9ebc188e1cb225533e1f5f9ef925d1f0b20eJohn Spurlock        if (mHandler == null) return;
18574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mHandler.removeMessages(MSG_START_SAMPLE);
18674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_SAMPLE),
18774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                isSamplePlaying() ? CHECK_RINGTONE_PLAYBACK_DELAY_MS : 0);
18874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
18974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
19074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private void onStartSample() {
19174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        if (!isSamplePlaying()) {
19274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            if (mCallback != null) {
19374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock                mCallback.onSampleStarting(this);
19474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            }
19574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            if (mRingtone != null) {
1960dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                try {
197bbfd31a5d4f126167e20fa8bd256c810cf8c2c85John Spurlock                    mRingtone.setAudioAttributes(new AudioAttributes.Builder(mRingtone
198bbfd31a5d4f126167e20fa8bd256c810cf8c2c85John Spurlock                            .getAudioAttributes())
199bbfd31a5d4f126167e20fa8bd256c810cf8c2c85John Spurlock                            .setFlags(AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY |
200bbfd31a5d4f126167e20fa8bd256c810cf8c2c85John Spurlock                                    AudioAttributes.FLAG_BYPASS_MUTE)
201bbfd31a5d4f126167e20fa8bd256c810cf8c2c85John Spurlock                            .build());
2020dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                    mRingtone.play();
2030dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                } catch (Throwable e) {
2040dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                    Log.w(TAG, "Error playing ringtone, stream " + mStreamType, e);
2050dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                }
20674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            }
20774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        }
20874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
20974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
210735f9ebc188e1cb225533e1f5f9ef925d1f0b20eJohn Spurlock    private void postStopSample() {
211735f9ebc188e1cb225533e1f5f9ef925d1f0b20eJohn Spurlock        if (mHandler == null) return;
21274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        // remove pending delayed start messages
21374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mHandler.removeMessages(MSG_START_SAMPLE);
21474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mHandler.removeMessages(MSG_STOP_SAMPLE);
21574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mHandler.sendMessage(mHandler.obtainMessage(MSG_STOP_SAMPLE));
21674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
21774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
21874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    private void onStopSample() {
21974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        if (mRingtone != null) {
22074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            mRingtone.stop();
22174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        }
22274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
22374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
22474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void stop() {
2250e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        if (mHandler == null) return;  // already stopped
22674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        postStopSample();
22774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
2280dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        mReceiver.setListening(false);
2290e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        mSeekBar.setOnSeekBarChangeListener(null);
2300dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        mHandler.getLooper().quitSafely();
2310e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        mHandler = null;
2320e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        mVolumeObserver = null;
2330e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock    }
2340e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock
2350e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock    public void start() {
2360e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        if (mHandler != null) return;  // already started
2370e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
2380e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        thread.start();
2390e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        mHandler = new Handler(thread.getLooper(), this);
2400e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        mHandler.sendEmptyMessage(MSG_INIT_SAMPLE);
2410e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        mVolumeObserver = new Observer(mHandler);
2420e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        mContext.getContentResolver().registerContentObserver(
2430e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock                System.getUriFor(System.VOLUME_SETTINGS[mStreamType]),
2440e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock                false, mVolumeObserver);
2450e588ea8e1746f3335b2b5c8a51fdd9a96167b59John Spurlock        mReceiver.setListening(true);
24674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
24774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
24874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void revertVolume() {
24974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mAudioManager.setStreamVolume(mStreamType, mOriginalStreamVolume, 0);
25074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
25174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
252bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
253bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        if (fromTouch) {
254bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            postSetVolume(progress);
255bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        }
256bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        if (mCallback != null) {
257bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            mCallback.onProgressChanged(seekBar, progress, fromTouch);
25874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        }
25974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
26074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
261735f9ebc188e1cb225533e1f5f9ef925d1f0b20eJohn Spurlock    private void postSetVolume(int progress) {
262735f9ebc188e1cb225533e1f5f9ef925d1f0b20eJohn Spurlock        if (mHandler == null) return;
26374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        // Do the volume changing separately to give responsive UI
26474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mLastProgress = progress;
26574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mHandler.removeMessages(MSG_SET_STREAM_VOLUME);
26674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_STREAM_VOLUME));
26774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
26874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
26974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void onStartTrackingTouch(SeekBar seekBar) {
27074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
27174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
27274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void onStopTrackingTouch(SeekBar seekBar) {
27374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        postStartSample();
27474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
27574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
27674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public boolean isSamplePlaying() {
27774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        return mRingtone != null && mRingtone.isPlaying();
27874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
27974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
28074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void startSample() {
28174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        postStartSample();
28274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
28374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
28474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void stopSample() {
28574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        postStopSample();
28674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
28774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
28874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public SeekBar getSeekBar() {
28974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        return mSeekBar;
29074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
29174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
29274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void changeVolumeBy(int amount) {
29374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mSeekBar.incrementProgressBy(amount);
29474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        postSetVolume(mSeekBar.getProgress());
29574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        postStartSample();
29674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        mVolumeBeforeMute = -1;
29774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
29874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
29974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void muteVolume() {
30074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        if (mVolumeBeforeMute != -1) {
30174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            mSeekBar.setProgress(mVolumeBeforeMute);
30274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            postSetVolume(mVolumeBeforeMute);
30374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            postStartSample();
30474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            mVolumeBeforeMute = -1;
30574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        } else {
30674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            mVolumeBeforeMute = mSeekBar.getProgress();
30774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            mSeekBar.setProgress(0);
30874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            postStopSample();
30974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            postSetVolume(0);
31074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        }
31174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
31274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
31374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void onSaveInstanceState(VolumeStore volumeStore) {
31474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        if (mLastProgress >= 0) {
31574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            volumeStore.volume = mLastProgress;
31674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            volumeStore.originalVolume = mOriginalStreamVolume;
31774a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        }
31874a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
31974a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock
32074a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    public void onRestoreInstanceState(VolumeStore volumeStore) {
32174a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        if (volumeStore.volume != -1) {
32274a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            mOriginalStreamVolume = volumeStore.originalVolume;
32374a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            mLastProgress = volumeStore.volume;
32474a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock            postSetVolume(mLastProgress);
32574a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock        }
32674a2e06d831432f27ebd17cf6f1d0086356e7ee0John Spurlock    }
3270dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock
3280dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock    private final class H extends Handler {
3290dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        private static final int UPDATE_SLIDER = 1;
3300dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock
3310dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        @Override
3320dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        public void handleMessage(Message msg) {
3330dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            if (msg.what == UPDATE_SLIDER) {
3340dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                if (mSeekBar != null) {
335bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                    mLastProgress = msg.arg1;
33696d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock                    mLastAudibleStreamVolume = Math.abs(msg.arg2);
33796d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock                    final boolean muted = msg.arg2 < 0;
338bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                    if (muted != mMuted) {
339bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                        mMuted = muted;
340bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                        if (mCallback != null) {
34196d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock                            mCallback.onMuted(mMuted, isZenMuted());
342bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                        }
343bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                    }
344bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                    updateSeekBar();
3450dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                }
3460dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            }
3470dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        }
3480dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock
34996d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock        public void postUpdateSlider(int volume, int lastAudibleVolume, boolean mute) {
35096d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock            final int arg2 = lastAudibleVolume * (mute ? -1 : 1);
35196d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock            obtainMessage(UPDATE_SLIDER, volume, arg2).sendToTarget();
352bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        }
353bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    }
354bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock
355bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    private void updateSlider() {
356bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock        if (mSeekBar != null && mAudioManager != null) {
357bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            final int volume = mAudioManager.getStreamVolume(mStreamType);
35896d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock            final int lastAudibleVolume = mAudioManager.getLastAudibleStreamVolume(mStreamType);
359bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            final boolean mute = mAudioManager.isStreamMute(mStreamType);
36096d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock            mUiHandler.postUpdateSlider(volume, lastAudibleVolume, mute);
3610dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        }
3620dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock    }
3630dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock
3640dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock    private final class Observer extends ContentObserver {
3650dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        public Observer(Handler handler) {
3660dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            super(handler);
3670dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        }
3680dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock
3690dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        @Override
3700dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        public void onChange(boolean selfChange) {
3710dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            super.onChange(selfChange);
372bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            updateSlider();
3730dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        }
3740dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock    }
3750dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock
3760dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock    private final class Receiver extends BroadcastReceiver {
3770dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        private boolean mListening;
3780dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock
3790dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        public void setListening(boolean listening) {
3800dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            if (mListening == listening) return;
3810dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            mListening = listening;
3820dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            if (listening) {
3830dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                final IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
384bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
38596d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock                filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
3860dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                mContext.registerReceiver(this, filter);
3870dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            } else {
3880dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock                mContext.unregisterReceiver(this);
3890dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            }
3900dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        }
3910dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock
3920dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        @Override
3930dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        public void onReceive(Context context, Intent intent) {
394bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            final String action = intent.getAction();
395bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
396bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
397bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
398bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                final boolean streamMatch = mNotificationOrRing ? isNotificationOrRing(streamType)
399bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                        : (streamType == mStreamType);
400bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                if (mSeekBar != null && streamMatch && streamValue != -1) {
401721d457685cc83785d0d0aad259e3218af899fc9John Spurlock                    final boolean muted = mAudioManager.isStreamMute(mStreamType)
402721d457685cc83785d0d0aad259e3218af899fc9John Spurlock                            || streamValue == 0;
40396d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock                    mUiHandler.postUpdateSlider(streamValue, mLastAudibleStreamVolume, muted);
404bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                }
405bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
406bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                if (mNotificationOrRing) {
407bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                    mRingerMode = mAudioManager.getRingerModeInternal();
408bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                }
409bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                if (mAffectedByRingerMode) {
410bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                    updateSlider();
411bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock                }
41296d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock            } else if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED.equals(action)) {
41396d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock                mZenMode = mNotificationManager.getZenMode();
41496d4a9ec394975818b073b537ccb6220ef0949baJohn Spurlock                updateSlider();
4150dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock            }
4160dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock        }
4170dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock    }
4180dbf1a6be21bb8947aa716fc40c6e288178b1803John Spurlock}
419