blob: 07a3c9b36528a3dfdfd7934521e7cea443be9a09 [file] [log] [blame]
John Spurlock74a2e062014-05-16 21:03:29 -04001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.preference;
18
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +010019import android.annotation.UnsupportedAppUsage;
John Spurlock96d4a9e2015-06-10 17:49:35 -040020import android.app.NotificationManager;
John Spurlock0dbf1a62014-06-01 13:01:23 -040021import android.content.BroadcastReceiver;
John Spurlock74a2e062014-05-16 21:03:29 -040022import android.content.Context;
John Spurlock0dbf1a62014-06-01 13:01:23 -040023import android.content.Intent;
24import android.content.IntentFilter;
John Spurlock74a2e062014-05-16 21:03:29 -040025import android.database.ContentObserver;
John Spurlockbbfd31a2015-02-18 11:58:14 -050026import android.media.AudioAttributes;
John Spurlock74a2e062014-05-16 21:03:29 -040027import android.media.AudioManager;
28import android.media.Ringtone;
29import android.media.RingtoneManager;
30import android.net.Uri;
31import android.os.Handler;
32import android.os.HandlerThread;
33import android.os.Message;
34import android.preference.VolumePreference.VolumeStore;
35import android.provider.Settings;
John Spurlock96d4a9e2015-06-10 17:49:35 -040036import android.provider.Settings.Global;
John Spurlock74a2e062014-05-16 21:03:29 -040037import android.provider.Settings.System;
Beverly925cde82018-01-23 09:31:23 -050038import android.service.notification.ZenModeConfig;
John Spurlock74a2e062014-05-16 21:03:29 -040039import android.util.Log;
40import android.widget.SeekBar;
41import android.widget.SeekBar.OnSeekBarChangeListener;
42
Sudheer Shanka33194352016-03-16 10:53:37 -070043import com.android.internal.annotations.GuardedBy;
44
John Spurlock74a2e062014-05-16 21:03:29 -040045/**
46 * Turns a {@link SeekBar} into a volume control.
47 * @hide
48 */
49public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callback {
John Spurlock95caba12014-05-27 13:10:38 -040050 private static final String TAG = "SeekBarVolumizer";
John Spurlock74a2e062014-05-16 21:03:29 -040051
52 public interface Callback {
53 void onSampleStarting(SeekBarVolumizer sbv);
John Spurlockbcc10872014-11-28 15:29:21 -050054 void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch);
John Spurlock96d4a9e2015-06-10 17:49:35 -040055 void onMuted(boolean muted, boolean zenMuted);
John Spurlock74a2e062014-05-16 21:03:29 -040056 }
57
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +010058 @UnsupportedAppUsage
John Spurlock95caba12014-05-27 13:10:38 -040059 private final Context mContext;
John Spurlock0dbf1a62014-06-01 13:01:23 -040060 private final H mUiHandler = new H();
John Spurlock74a2e062014-05-16 21:03:29 -040061 private final Callback mCallback;
John Spurlock95caba12014-05-27 13:10:38 -040062 private final Uri mDefaultUri;
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +010063 @UnsupportedAppUsage
John Spurlock95caba12014-05-27 13:10:38 -040064 private final AudioManager mAudioManager;
John Spurlock96d4a9e2015-06-10 17:49:35 -040065 private final NotificationManager mNotificationManager;
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +010066 @UnsupportedAppUsage
John Spurlock95caba12014-05-27 13:10:38 -040067 private final int mStreamType;
68 private final int mMaxStreamVolume;
John Spurlockbcc10872014-11-28 15:29:21 -050069 private boolean mAffectedByRingerMode;
70 private boolean mNotificationOrRing;
John Spurlock0dbf1a62014-06-01 13:01:23 -040071 private final Receiver mReceiver = new Receiver();
John Spurlock74a2e062014-05-16 21:03:29 -040072
John Spurlock0e588ea2014-10-08 12:33:22 -040073 private Handler mHandler;
74 private Observer mVolumeObserver;
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +010075 @UnsupportedAppUsage
John Spurlock74a2e062014-05-16 21:03:29 -040076 private int mOriginalStreamVolume;
John Spurlock96d4a9e2015-06-10 17:49:35 -040077 private int mLastAudibleStreamVolume;
Sudheer Shanka33194352016-03-16 10:53:37 -070078 // When the old handler is destroyed and a new one is created, there could be a situation where
79 // this is accessed at the same time in different handlers. So, access to this field needs to be
80 // synchronized.
81 @GuardedBy("this")
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +010082 @UnsupportedAppUsage
John Spurlock74a2e062014-05-16 21:03:29 -040083 private Ringtone mRingtone;
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +010084 @UnsupportedAppUsage
John Spurlock74a2e062014-05-16 21:03:29 -040085 private int mLastProgress = -1;
John Spurlockbcc10872014-11-28 15:29:21 -050086 private boolean mMuted;
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +010087 @UnsupportedAppUsage
John Spurlock74a2e062014-05-16 21:03:29 -040088 private SeekBar mSeekBar;
89 private int mVolumeBeforeMute = -1;
John Spurlockbcc10872014-11-28 15:29:21 -050090 private int mRingerMode;
John Spurlock96d4a9e2015-06-10 17:49:35 -040091 private int mZenMode;
John Spurlock74a2e062014-05-16 21:03:29 -040092
93 private static final int MSG_SET_STREAM_VOLUME = 0;
94 private static final int MSG_START_SAMPLE = 1;
95 private static final int MSG_STOP_SAMPLE = 2;
John Spurlock95caba12014-05-27 13:10:38 -040096 private static final int MSG_INIT_SAMPLE = 3;
John Spurlock74a2e062014-05-16 21:03:29 -040097 private static final int CHECK_RINGTONE_PLAYBACK_DELAY_MS = 1000;
98
Beverly925cde82018-01-23 09:31:23 -050099 private NotificationManager.Policy mNotificationPolicy;
100 private boolean mAllowAlarms;
Beverlyd6964762018-02-16 14:07:03 -0500101 private boolean mAllowMedia;
Beverly925cde82018-01-23 09:31:23 -0500102 private boolean mAllowRinger;
103
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +0100104 @UnsupportedAppUsage
John Spurlockbcc10872014-11-28 15:29:21 -0500105 public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) {
John Spurlock74a2e062014-05-16 21:03:29 -0400106 mContext = context;
John Spurlock96d4a9e2015-06-10 17:49:35 -0400107 mAudioManager = context.getSystemService(AudioManager.class);
108 mNotificationManager = context.getSystemService(NotificationManager.class);
Beverly925cde82018-01-23 09:31:23 -0500109 mNotificationPolicy = mNotificationManager.getNotificationPolicy();
110 mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
111 .PRIORITY_CATEGORY_ALARMS) != 0;
Beverlyd6964762018-02-16 14:07:03 -0500112 mAllowMedia = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
113 .PRIORITY_CATEGORY_MEDIA) != 0;
Beverly925cde82018-01-23 09:31:23 -0500114 mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(
115 mNotificationPolicy);
John Spurlock74a2e062014-05-16 21:03:29 -0400116 mStreamType = streamType;
John Spurlockbcc10872014-11-28 15:29:21 -0500117 mAffectedByRingerMode = mAudioManager.isStreamAffectedByRingerMode(mStreamType);
118 mNotificationOrRing = isNotificationOrRing(mStreamType);
119 if (mNotificationOrRing) {
120 mRingerMode = mAudioManager.getRingerModeInternal();
121 }
John Spurlock96d4a9e2015-06-10 17:49:35 -0400122 mZenMode = mNotificationManager.getZenMode();
John Spurlock95caba12014-05-27 13:10:38 -0400123 mMaxStreamVolume = mAudioManager.getStreamMaxVolume(mStreamType);
John Spurlock74a2e062014-05-16 21:03:29 -0400124 mCallback = callback;
John Spurlock74a2e062014-05-16 21:03:29 -0400125 mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType);
John Spurlock96d4a9e2015-06-10 17:49:35 -0400126 mLastAudibleStreamVolume = mAudioManager.getLastAudibleStreamVolume(mStreamType);
John Spurlockbcc10872014-11-28 15:29:21 -0500127 mMuted = mAudioManager.isStreamMute(mStreamType);
128 if (mCallback != null) {
John Spurlock96d4a9e2015-06-10 17:49:35 -0400129 mCallback.onMuted(mMuted, isZenMuted());
John Spurlockbcc10872014-11-28 15:29:21 -0500130 }
John Spurlock74a2e062014-05-16 21:03:29 -0400131 if (defaultUri == null) {
132 if (mStreamType == AudioManager.STREAM_RING) {
133 defaultUri = Settings.System.DEFAULT_RINGTONE_URI;
134 } else if (mStreamType == AudioManager.STREAM_NOTIFICATION) {
135 defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI;
136 } else {
137 defaultUri = Settings.System.DEFAULT_ALARM_ALERT_URI;
138 }
139 }
John Spurlock95caba12014-05-27 13:10:38 -0400140 mDefaultUri = defaultUri;
John Spurlock95caba12014-05-27 13:10:38 -0400141 }
John Spurlock74a2e062014-05-16 21:03:29 -0400142
John Spurlockbcc10872014-11-28 15:29:21 -0500143 private static boolean isNotificationOrRing(int stream) {
144 return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION;
145 }
146
Beverly925cde82018-01-23 09:31:23 -0500147 private static boolean isAlarmsStream(int stream) {
148 return stream == AudioManager.STREAM_ALARM;
149 }
150
Beverlyd6964762018-02-16 14:07:03 -0500151 private static boolean isMediaStream(int stream) {
152 return stream == AudioManager.STREAM_MUSIC;
Beverly925cde82018-01-23 09:31:23 -0500153 }
154
John Spurlock95caba12014-05-27 13:10:38 -0400155 public void setSeekBar(SeekBar seekBar) {
John Spurlock0dbf1a62014-06-01 13:01:23 -0400156 if (mSeekBar != null) {
157 mSeekBar.setOnSeekBarChangeListener(null);
158 }
John Spurlock95caba12014-05-27 13:10:38 -0400159 mSeekBar = seekBar;
160 mSeekBar.setOnSeekBarChangeListener(null);
161 mSeekBar.setMax(mMaxStreamVolume);
John Spurlockbcc10872014-11-28 15:29:21 -0500162 updateSeekBar();
John Spurlock95caba12014-05-27 13:10:38 -0400163 mSeekBar.setOnSeekBarChangeListener(this);
John Spurlock74a2e062014-05-16 21:03:29 -0400164 }
165
John Spurlock96d4a9e2015-06-10 17:49:35 -0400166 private boolean isZenMuted() {
167 return mNotificationOrRing && mZenMode == Global.ZEN_MODE_ALARMS
Beverly925cde82018-01-23 09:31:23 -0500168 || mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS
169 || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
170 && ((!mAllowAlarms && isAlarmsStream(mStreamType))
Beverlyd6964762018-02-16 14:07:03 -0500171 || (!mAllowMedia && isMediaStream(mStreamType))
Beverly925cde82018-01-23 09:31:23 -0500172 || (!mAllowRinger && isNotificationOrRing(mStreamType))));
John Spurlock96d4a9e2015-06-10 17:49:35 -0400173 }
174
John Spurlockbcc10872014-11-28 15:29:21 -0500175 protected void updateSeekBar() {
John Spurlock96d4a9e2015-06-10 17:49:35 -0400176 final boolean zenMuted = isZenMuted();
177 mSeekBar.setEnabled(!zenMuted);
178 if (zenMuted) {
Julia Reynolds88dabde2016-08-09 13:59:44 -0400179 mSeekBar.setProgress(mLastAudibleStreamVolume, true);
John Spurlock96d4a9e2015-06-10 17:49:35 -0400180 } else if (mNotificationOrRing && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
Julia Reynolds88dabde2016-08-09 13:59:44 -0400181 mSeekBar.setProgress(0, true);
John Spurlockbcc10872014-11-28 15:29:21 -0500182 } else if (mMuted) {
Julia Reynolds88dabde2016-08-09 13:59:44 -0400183 mSeekBar.setProgress(0, true);
John Spurlockbcc10872014-11-28 15:29:21 -0500184 } else {
Julia Reynolds88dabde2016-08-09 13:59:44 -0400185 mSeekBar.setProgress(mLastProgress > -1 ? mLastProgress : mOriginalStreamVolume, true);
John Spurlockbcc10872014-11-28 15:29:21 -0500186 }
187 }
188
John Spurlock74a2e062014-05-16 21:03:29 -0400189 @Override
190 public boolean handleMessage(Message msg) {
191 switch (msg.what) {
192 case MSG_SET_STREAM_VOLUME:
John Spurlock721d4572015-04-16 11:01:15 -0400193 if (mMuted && mLastProgress > 0) {
194 mAudioManager.adjustStreamVolume(mStreamType, AudioManager.ADJUST_UNMUTE, 0);
195 } else if (!mMuted && mLastProgress == 0) {
196 mAudioManager.adjustStreamVolume(mStreamType, AudioManager.ADJUST_MUTE, 0);
197 }
John Spurlock35134602014-07-24 18:10:48 -0400198 mAudioManager.setStreamVolume(mStreamType, mLastProgress,
199 AudioManager.FLAG_SHOW_UI_WARNINGS);
John Spurlock74a2e062014-05-16 21:03:29 -0400200 break;
201 case MSG_START_SAMPLE:
202 onStartSample();
203 break;
204 case MSG_STOP_SAMPLE:
205 onStopSample();
206 break;
John Spurlock95caba12014-05-27 13:10:38 -0400207 case MSG_INIT_SAMPLE:
208 onInitSample();
209 break;
John Spurlock74a2e062014-05-16 21:03:29 -0400210 default:
John Spurlock95caba12014-05-27 13:10:38 -0400211 Log.e(TAG, "invalid SeekBarVolumizer message: "+msg.what);
John Spurlock74a2e062014-05-16 21:03:29 -0400212 }
213 return true;
214 }
215
John Spurlock95caba12014-05-27 13:10:38 -0400216 private void onInitSample() {
Sudheer Shanka33194352016-03-16 10:53:37 -0700217 synchronized (this) {
218 mRingtone = RingtoneManager.getRingtone(mContext, mDefaultUri);
219 if (mRingtone != null) {
220 mRingtone.setStreamType(mStreamType);
221 }
John Spurlock95caba12014-05-27 13:10:38 -0400222 }
223 }
224
John Spurlock74a2e062014-05-16 21:03:29 -0400225 private void postStartSample() {
John Spurlock735f9eb2014-10-21 14:23:24 -0400226 if (mHandler == null) return;
John Spurlock74a2e062014-05-16 21:03:29 -0400227 mHandler.removeMessages(MSG_START_SAMPLE);
228 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_SAMPLE),
229 isSamplePlaying() ? CHECK_RINGTONE_PLAYBACK_DELAY_MS : 0);
230 }
231
232 private void onStartSample() {
233 if (!isSamplePlaying()) {
234 if (mCallback != null) {
235 mCallback.onSampleStarting(this);
236 }
Sudheer Shanka33194352016-03-16 10:53:37 -0700237
238 synchronized (this) {
239 if (mRingtone != null) {
240 try {
241 mRingtone.setAudioAttributes(new AudioAttributes.Builder(mRingtone
242 .getAudioAttributes())
Jean-Michel Trivid51d3982017-10-10 16:32:38 -0700243 .setFlags(AudioAttributes.FLAG_BYPASS_MUTE)
Sudheer Shanka33194352016-03-16 10:53:37 -0700244 .build());
245 mRingtone.play();
246 } catch (Throwable e) {
247 Log.w(TAG, "Error playing ringtone, stream " + mStreamType, e);
248 }
John Spurlock0dbf1a62014-06-01 13:01:23 -0400249 }
John Spurlock74a2e062014-05-16 21:03:29 -0400250 }
251 }
252 }
253
John Spurlock735f9eb2014-10-21 14:23:24 -0400254 private void postStopSample() {
255 if (mHandler == null) return;
John Spurlock74a2e062014-05-16 21:03:29 -0400256 // remove pending delayed start messages
257 mHandler.removeMessages(MSG_START_SAMPLE);
258 mHandler.removeMessages(MSG_STOP_SAMPLE);
259 mHandler.sendMessage(mHandler.obtainMessage(MSG_STOP_SAMPLE));
260 }
261
262 private void onStopSample() {
Sudheer Shanka33194352016-03-16 10:53:37 -0700263 synchronized (this) {
264 if (mRingtone != null) {
265 mRingtone.stop();
266 }
John Spurlock74a2e062014-05-16 21:03:29 -0400267 }
268 }
269
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +0100270 @UnsupportedAppUsage
John Spurlock74a2e062014-05-16 21:03:29 -0400271 public void stop() {
John Spurlock0e588ea2014-10-08 12:33:22 -0400272 if (mHandler == null) return; // already stopped
John Spurlock74a2e062014-05-16 21:03:29 -0400273 postStopSample();
274 mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
John Spurlock0dbf1a62014-06-01 13:01:23 -0400275 mReceiver.setListening(false);
John Spurlock0e588ea2014-10-08 12:33:22 -0400276 mSeekBar.setOnSeekBarChangeListener(null);
John Spurlock0dbf1a62014-06-01 13:01:23 -0400277 mHandler.getLooper().quitSafely();
John Spurlock0e588ea2014-10-08 12:33:22 -0400278 mHandler = null;
279 mVolumeObserver = null;
280 }
281
282 public void start() {
283 if (mHandler != null) return; // already started
284 HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
285 thread.start();
286 mHandler = new Handler(thread.getLooper(), this);
287 mHandler.sendEmptyMessage(MSG_INIT_SAMPLE);
288 mVolumeObserver = new Observer(mHandler);
289 mContext.getContentResolver().registerContentObserver(
290 System.getUriFor(System.VOLUME_SETTINGS[mStreamType]),
291 false, mVolumeObserver);
292 mReceiver.setListening(true);
John Spurlock74a2e062014-05-16 21:03:29 -0400293 }
294
295 public void revertVolume() {
296 mAudioManager.setStreamVolume(mStreamType, mOriginalStreamVolume, 0);
297 }
298
John Spurlockbcc10872014-11-28 15:29:21 -0500299 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
300 if (fromTouch) {
301 postSetVolume(progress);
John Spurlock74a2e062014-05-16 21:03:29 -0400302 }
John Spurlockbcc10872014-11-28 15:29:21 -0500303 if (mCallback != null) {
304 mCallback.onProgressChanged(seekBar, progress, fromTouch);
305 }
John Spurlock74a2e062014-05-16 21:03:29 -0400306 }
307
John Spurlock735f9eb2014-10-21 14:23:24 -0400308 private void postSetVolume(int progress) {
309 if (mHandler == null) return;
John Spurlock74a2e062014-05-16 21:03:29 -0400310 // Do the volume changing separately to give responsive UI
311 mLastProgress = progress;
312 mHandler.removeMessages(MSG_SET_STREAM_VOLUME);
313 mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_STREAM_VOLUME));
314 }
315
316 public void onStartTrackingTouch(SeekBar seekBar) {
317 }
318
319 public void onStopTrackingTouch(SeekBar seekBar) {
320 postStartSample();
321 }
322
323 public boolean isSamplePlaying() {
Sudheer Shanka33194352016-03-16 10:53:37 -0700324 synchronized (this) {
325 return mRingtone != null && mRingtone.isPlaying();
326 }
John Spurlock74a2e062014-05-16 21:03:29 -0400327 }
328
329 public void startSample() {
330 postStartSample();
331 }
332
333 public void stopSample() {
334 postStopSample();
335 }
336
337 public SeekBar getSeekBar() {
338 return mSeekBar;
339 }
340
341 public void changeVolumeBy(int amount) {
342 mSeekBar.incrementProgressBy(amount);
343 postSetVolume(mSeekBar.getProgress());
344 postStartSample();
345 mVolumeBeforeMute = -1;
346 }
347
348 public void muteVolume() {
349 if (mVolumeBeforeMute != -1) {
Julia Reynolds88dabde2016-08-09 13:59:44 -0400350 mSeekBar.setProgress(mVolumeBeforeMute, true);
John Spurlock74a2e062014-05-16 21:03:29 -0400351 postSetVolume(mVolumeBeforeMute);
352 postStartSample();
353 mVolumeBeforeMute = -1;
354 } else {
355 mVolumeBeforeMute = mSeekBar.getProgress();
Julia Reynolds88dabde2016-08-09 13:59:44 -0400356 mSeekBar.setProgress(0, true);
John Spurlock74a2e062014-05-16 21:03:29 -0400357 postStopSample();
358 postSetVolume(0);
359 }
360 }
361
362 public void onSaveInstanceState(VolumeStore volumeStore) {
363 if (mLastProgress >= 0) {
364 volumeStore.volume = mLastProgress;
365 volumeStore.originalVolume = mOriginalStreamVolume;
366 }
367 }
368
369 public void onRestoreInstanceState(VolumeStore volumeStore) {
370 if (volumeStore.volume != -1) {
371 mOriginalStreamVolume = volumeStore.originalVolume;
372 mLastProgress = volumeStore.volume;
373 postSetVolume(mLastProgress);
374 }
375 }
John Spurlock0dbf1a62014-06-01 13:01:23 -0400376
377 private final class H extends Handler {
378 private static final int UPDATE_SLIDER = 1;
379
380 @Override
381 public void handleMessage(Message msg) {
382 if (msg.what == UPDATE_SLIDER) {
383 if (mSeekBar != null) {
John Spurlockbcc10872014-11-28 15:29:21 -0500384 mLastProgress = msg.arg1;
Shigeki Yokomichi8eb355d2016-02-25 17:17:39 +0900385 mLastAudibleStreamVolume = msg.arg2;
386 final boolean muted = ((Boolean)msg.obj).booleanValue();
John Spurlockbcc10872014-11-28 15:29:21 -0500387 if (muted != mMuted) {
388 mMuted = muted;
389 if (mCallback != null) {
John Spurlock96d4a9e2015-06-10 17:49:35 -0400390 mCallback.onMuted(mMuted, isZenMuted());
John Spurlockbcc10872014-11-28 15:29:21 -0500391 }
392 }
393 updateSeekBar();
John Spurlock0dbf1a62014-06-01 13:01:23 -0400394 }
395 }
396 }
397
John Spurlock96d4a9e2015-06-10 17:49:35 -0400398 public void postUpdateSlider(int volume, int lastAudibleVolume, boolean mute) {
Shigeki Yokomichi8eb355d2016-02-25 17:17:39 +0900399 obtainMessage(UPDATE_SLIDER, volume, lastAudibleVolume, new Boolean(mute)).sendToTarget();
John Spurlockbcc10872014-11-28 15:29:21 -0500400 }
401 }
402
403 private void updateSlider() {
404 if (mSeekBar != null && mAudioManager != null) {
405 final int volume = mAudioManager.getStreamVolume(mStreamType);
John Spurlock96d4a9e2015-06-10 17:49:35 -0400406 final int lastAudibleVolume = mAudioManager.getLastAudibleStreamVolume(mStreamType);
John Spurlockbcc10872014-11-28 15:29:21 -0500407 final boolean mute = mAudioManager.isStreamMute(mStreamType);
John Spurlock96d4a9e2015-06-10 17:49:35 -0400408 mUiHandler.postUpdateSlider(volume, lastAudibleVolume, mute);
John Spurlock0dbf1a62014-06-01 13:01:23 -0400409 }
410 }
411
412 private final class Observer extends ContentObserver {
413 public Observer(Handler handler) {
414 super(handler);
415 }
416
417 @Override
418 public void onChange(boolean selfChange) {
419 super.onChange(selfChange);
John Spurlockbcc10872014-11-28 15:29:21 -0500420 updateSlider();
John Spurlock0dbf1a62014-06-01 13:01:23 -0400421 }
422 }
423
424 private final class Receiver extends BroadcastReceiver {
425 private boolean mListening;
426
427 public void setListening(boolean listening) {
428 if (mListening == listening) return;
429 mListening = listening;
430 if (listening) {
431 final IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
John Spurlockbcc10872014-11-28 15:29:21 -0500432 filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
John Spurlock96d4a9e2015-06-10 17:49:35 -0400433 filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
Beverly925cde82018-01-23 09:31:23 -0500434 filter.addAction(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
Julia Reynolds3a10b102015-10-14 16:13:28 -0400435 filter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
John Spurlock0dbf1a62014-06-01 13:01:23 -0400436 mContext.registerReceiver(this, filter);
437 } else {
438 mContext.unregisterReceiver(this);
439 }
440 }
441
442 @Override
443 public void onReceive(Context context, Intent intent) {
John Spurlockbcc10872014-11-28 15:29:21 -0500444 final String action = intent.getAction();
445 if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
446 int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
447 int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
Julia Reynolds3a10b102015-10-14 16:13:28 -0400448 updateVolumeSlider(streamType, streamValue);
John Spurlockbcc10872014-11-28 15:29:21 -0500449 } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
450 if (mNotificationOrRing) {
451 mRingerMode = mAudioManager.getRingerModeInternal();
452 }
453 if (mAffectedByRingerMode) {
454 updateSlider();
455 }
Julia Reynolds3a10b102015-10-14 16:13:28 -0400456 } else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
457 int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
458 int streamVolume = mAudioManager.getStreamVolume(streamType);
459 updateVolumeSlider(streamType, streamVolume);
John Spurlock96d4a9e2015-06-10 17:49:35 -0400460 } else if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED.equals(action)) {
461 mZenMode = mNotificationManager.getZenMode();
462 updateSlider();
Beverly925cde82018-01-23 09:31:23 -0500463 } else if (NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED.equals(action)) {
464 mNotificationPolicy = mNotificationManager.getNotificationPolicy();
465 mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
466 .PRIORITY_CATEGORY_ALARMS) != 0;
Beverlyd6964762018-02-16 14:07:03 -0500467 mAllowMedia = (mNotificationPolicy.priorityCategories
468 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) != 0;
Beverly925cde82018-01-23 09:31:23 -0500469 mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(
470 mNotificationPolicy);
471 updateSlider();
John Spurlock0dbf1a62014-06-01 13:01:23 -0400472 }
473 }
Julia Reynolds3a10b102015-10-14 16:13:28 -0400474
475 private void updateVolumeSlider(int streamType, int streamValue) {
476 final boolean streamMatch = mNotificationOrRing ? isNotificationOrRing(streamType)
477 : (streamType == mStreamType);
478 if (mSeekBar != null && streamMatch && streamValue != -1) {
479 final boolean muted = mAudioManager.isStreamMute(mStreamType)
480 || streamValue == 0;
481 mUiHandler.postUpdateSlider(streamValue, mLastAudibleStreamVolume, muted);
482 }
483 }
John Spurlock0dbf1a62014-06-01 13:01:23 -0400484 }
485}