Home | History | Annotate | Download | only in preference
      1 /*
      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 
     17 package android.preference;
     18 
     19 import android.annotation.NonNull;
     20 import android.annotation.UnsupportedAppUsage;
     21 import android.app.NotificationManager;
     22 import android.content.BroadcastReceiver;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.IntentFilter;
     26 import android.database.ContentObserver;
     27 import android.media.AudioAttributes;
     28 import android.media.AudioManager;
     29 import android.media.Ringtone;
     30 import android.media.RingtoneManager;
     31 import android.media.audiopolicy.AudioProductStrategy;
     32 import android.media.audiopolicy.AudioVolumeGroup;
     33 import android.net.Uri;
     34 import android.os.Handler;
     35 import android.os.HandlerThread;
     36 import android.os.Message;
     37 import android.preference.VolumePreference.VolumeStore;
     38 import android.provider.Settings;
     39 import android.provider.Settings.Global;
     40 import android.provider.Settings.System;
     41 import android.service.notification.ZenModeConfig;
     42 import android.util.Log;
     43 import android.widget.SeekBar;
     44 import android.widget.SeekBar.OnSeekBarChangeListener;
     45 
     46 import com.android.internal.annotations.GuardedBy;
     47 import com.android.internal.os.SomeArgs;
     48 
     49 /**
     50  * Turns a {@link SeekBar} into a volume control.
     51  * @hide
     52  *
     53  * @deprecated Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
     54  *      <a href="{@docRoot}reference/androidx/preference/package-summary.html">
     55  *      Preference Library</a> for consistent behavior across all devices. For more information on
     56  *      using the AndroidX Preference Library see
     57  *      <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.
     58  */
     59 @Deprecated
     60 public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callback {
     61     private static final String TAG = "SeekBarVolumizer";
     62 
     63     public interface Callback {
     64         void onSampleStarting(SeekBarVolumizer sbv);
     65         void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch);
     66         void onMuted(boolean muted, boolean zenMuted);
     67     }
     68 
     69     private static final int MSG_GROUP_VOLUME_CHANGED = 1;
     70     private final Handler mVolumeHandler = new VolumeHandler();
     71     private AudioAttributes mAttributes;
     72     private int mVolumeGroupId;
     73 
     74     private final AudioManager.VolumeGroupCallback mVolumeGroupCallback =
     75             new AudioManager.VolumeGroupCallback() {
     76         @Override
     77         public void onAudioVolumeGroupChanged(int group, int flags) {
     78             if (mHandler == null) {
     79                 return;
     80             }
     81             SomeArgs args = SomeArgs.obtain();
     82             args.arg1 = group;
     83             args.arg2 = flags;
     84             mVolumeHandler.sendMessage(mHandler.obtainMessage(MSG_GROUP_VOLUME_CHANGED, args));
     85         }
     86     };
     87 
     88     @UnsupportedAppUsage
     89     private final Context mContext;
     90     private final H mUiHandler = new H();
     91     private final Callback mCallback;
     92     private final Uri mDefaultUri;
     93     @UnsupportedAppUsage
     94     private final AudioManager mAudioManager;
     95     private final NotificationManager mNotificationManager;
     96     @UnsupportedAppUsage
     97     private final int mStreamType;
     98     private final int mMaxStreamVolume;
     99     private boolean mAffectedByRingerMode;
    100     private boolean mNotificationOrRing;
    101     private final Receiver mReceiver = new Receiver();
    102 
    103     private Handler mHandler;
    104     private Observer mVolumeObserver;
    105     @UnsupportedAppUsage
    106     private int mOriginalStreamVolume;
    107     private int mLastAudibleStreamVolume;
    108     // When the old handler is destroyed and a new one is created, there could be a situation where
    109     // this is accessed at the same time in different handlers. So, access to this field needs to be
    110     // synchronized.
    111     @GuardedBy("this")
    112     @UnsupportedAppUsage
    113     private Ringtone mRingtone;
    114     @UnsupportedAppUsage
    115     private int mLastProgress = -1;
    116     private boolean mMuted;
    117     @UnsupportedAppUsage
    118     private SeekBar mSeekBar;
    119     private int mVolumeBeforeMute = -1;
    120     private int mRingerMode;
    121     private int mZenMode;
    122     private boolean mPlaySample;
    123 
    124     private static final int MSG_SET_STREAM_VOLUME = 0;
    125     private static final int MSG_START_SAMPLE = 1;
    126     private static final int MSG_STOP_SAMPLE = 2;
    127     private static final int MSG_INIT_SAMPLE = 3;
    128     private static final int CHECK_RINGTONE_PLAYBACK_DELAY_MS = 1000;
    129 
    130     private NotificationManager.Policy mNotificationPolicy;
    131     private boolean mAllowAlarms;
    132     private boolean mAllowMedia;
    133     private boolean mAllowRinger;
    134 
    135     @UnsupportedAppUsage
    136     public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) {
    137         this(context, streamType, defaultUri, callback, true /* playSample */);
    138     }
    139 
    140     public SeekBarVolumizer(
    141             Context context,
    142             int streamType,
    143             Uri defaultUri,
    144             Callback callback,
    145             boolean playSample) {
    146         mContext = context;
    147         mAudioManager = context.getSystemService(AudioManager.class);
    148         mNotificationManager = context.getSystemService(NotificationManager.class);
    149         mNotificationPolicy = mNotificationManager.getConsolidatedNotificationPolicy();
    150         mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
    151                 .PRIORITY_CATEGORY_ALARMS) != 0;
    152         mAllowMedia = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
    153                 .PRIORITY_CATEGORY_MEDIA) != 0;
    154         mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(
    155                 mNotificationPolicy);
    156         mStreamType = streamType;
    157         mAffectedByRingerMode = mAudioManager.isStreamAffectedByRingerMode(mStreamType);
    158         mNotificationOrRing = isNotificationOrRing(mStreamType);
    159         if (mNotificationOrRing) {
    160             mRingerMode = mAudioManager.getRingerModeInternal();
    161         }
    162         mZenMode = mNotificationManager.getZenMode();
    163 
    164         if (hasAudioProductStrategies()) {
    165             mVolumeGroupId = getVolumeGroupIdForLegacyStreamType(mStreamType);
    166             mAttributes = getAudioAttributesForLegacyStreamType(
    167                     mStreamType);
    168         }
    169 
    170         mMaxStreamVolume = mAudioManager.getStreamMaxVolume(mStreamType);
    171         mCallback = callback;
    172         mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType);
    173         mLastAudibleStreamVolume = mAudioManager.getLastAudibleStreamVolume(mStreamType);
    174         mMuted = mAudioManager.isStreamMute(mStreamType);
    175         mPlaySample = playSample;
    176         if (mCallback != null) {
    177             mCallback.onMuted(mMuted, isZenMuted());
    178         }
    179         if (defaultUri == null) {
    180             if (mStreamType == AudioManager.STREAM_RING) {
    181                 defaultUri = Settings.System.DEFAULT_RINGTONE_URI;
    182             } else if (mStreamType == AudioManager.STREAM_NOTIFICATION) {
    183                 defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI;
    184             } else {
    185                 defaultUri = Settings.System.DEFAULT_ALARM_ALERT_URI;
    186             }
    187         }
    188         mDefaultUri = defaultUri;
    189     }
    190 
    191     private boolean hasAudioProductStrategies() {
    192         return AudioManager.getAudioProductStrategies().size() > 0;
    193     }
    194 
    195     private int getVolumeGroupIdForLegacyStreamType(int streamType) {
    196         for (final AudioProductStrategy productStrategy :
    197                 AudioManager.getAudioProductStrategies()) {
    198             int volumeGroupId = productStrategy.getVolumeGroupIdForLegacyStreamType(streamType);
    199             if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
    200                 return volumeGroupId;
    201             }
    202         }
    203 
    204         return AudioManager.getAudioProductStrategies().stream()
    205                 .map(strategy -> strategy.getVolumeGroupIdForAudioAttributes(
    206                         AudioProductStrategy.sDefaultAttributes))
    207                 .filter(volumeGroupId -> volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP)
    208                 .findFirst()
    209                 .orElse(AudioVolumeGroup.DEFAULT_VOLUME_GROUP);
    210     }
    211 
    212     private @NonNull AudioAttributes getAudioAttributesForLegacyStreamType(int streamType) {
    213         for (final AudioProductStrategy productStrategy :
    214                 AudioManager.getAudioProductStrategies()) {
    215             AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
    216             if (aa != null) {
    217                 return aa;
    218             }
    219         }
    220         return new AudioAttributes.Builder()
    221                 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
    222                 .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
    223     }
    224 
    225     private static boolean isNotificationOrRing(int stream) {
    226         return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION;
    227     }
    228 
    229     private static boolean isAlarmsStream(int stream) {
    230         return stream == AudioManager.STREAM_ALARM;
    231     }
    232 
    233     private static boolean isMediaStream(int stream) {
    234         return stream == AudioManager.STREAM_MUSIC;
    235     }
    236 
    237     public void setSeekBar(SeekBar seekBar) {
    238         if (mSeekBar != null) {
    239             mSeekBar.setOnSeekBarChangeListener(null);
    240         }
    241         mSeekBar = seekBar;
    242         mSeekBar.setOnSeekBarChangeListener(null);
    243         mSeekBar.setMax(mMaxStreamVolume);
    244         updateSeekBar();
    245         mSeekBar.setOnSeekBarChangeListener(this);
    246     }
    247 
    248     private boolean isZenMuted() {
    249         return mNotificationOrRing && mZenMode == Global.ZEN_MODE_ALARMS
    250                 || mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS
    251                 || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
    252                     && ((!mAllowAlarms && isAlarmsStream(mStreamType))
    253                         || (!mAllowMedia && isMediaStream(mStreamType))
    254                         || (!mAllowRinger && isNotificationOrRing(mStreamType))));
    255     }
    256 
    257     protected void updateSeekBar() {
    258         final boolean zenMuted = isZenMuted();
    259         mSeekBar.setEnabled(!zenMuted);
    260         if (zenMuted) {
    261             mSeekBar.setProgress(mLastAudibleStreamVolume, true);
    262         } else if (mNotificationOrRing && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
    263             mSeekBar.setProgress(0, true);
    264         } else if (mMuted) {
    265             mSeekBar.setProgress(0, true);
    266         } else {
    267             mSeekBar.setProgress(mLastProgress > -1 ? mLastProgress : mOriginalStreamVolume, true);
    268         }
    269     }
    270 
    271     @Override
    272     public boolean handleMessage(Message msg) {
    273         switch (msg.what) {
    274             case MSG_SET_STREAM_VOLUME:
    275                 if (mMuted && mLastProgress > 0) {
    276                     mAudioManager.adjustStreamVolume(mStreamType, AudioManager.ADJUST_UNMUTE, 0);
    277                 } else if (!mMuted && mLastProgress == 0) {
    278                     mAudioManager.adjustStreamVolume(mStreamType, AudioManager.ADJUST_MUTE, 0);
    279                 }
    280                 mAudioManager.setStreamVolume(mStreamType, mLastProgress,
    281                         AudioManager.FLAG_SHOW_UI_WARNINGS);
    282                 break;
    283             case MSG_START_SAMPLE:
    284                 if (mPlaySample) {
    285                     onStartSample();
    286                 }
    287                 break;
    288             case MSG_STOP_SAMPLE:
    289                 if (mPlaySample) {
    290                     onStopSample();
    291                 }
    292                 break;
    293             case MSG_INIT_SAMPLE:
    294                 if (mPlaySample) {
    295                     onInitSample();
    296                 }
    297                 break;
    298             default:
    299                 Log.e(TAG, "invalid SeekBarVolumizer message: "+msg.what);
    300         }
    301         return true;
    302     }
    303 
    304     private void onInitSample() {
    305         synchronized (this) {
    306             mRingtone = RingtoneManager.getRingtone(mContext, mDefaultUri);
    307             if (mRingtone != null) {
    308                 mRingtone.setStreamType(mStreamType);
    309             }
    310         }
    311     }
    312 
    313     private void postStartSample() {
    314         if (mHandler == null) return;
    315         mHandler.removeMessages(MSG_START_SAMPLE);
    316         mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_SAMPLE),
    317                 isSamplePlaying() ? CHECK_RINGTONE_PLAYBACK_DELAY_MS : 0);
    318     }
    319 
    320     private void onStartSample() {
    321         if (!isSamplePlaying()) {
    322             if (mCallback != null) {
    323                 mCallback.onSampleStarting(this);
    324             }
    325 
    326             synchronized (this) {
    327                 if (mRingtone != null) {
    328                     try {
    329                         mRingtone.setAudioAttributes(new AudioAttributes.Builder(mRingtone
    330                                 .getAudioAttributes())
    331                                 .setFlags(AudioAttributes.FLAG_BYPASS_MUTE)
    332                                 .build());
    333                         mRingtone.play();
    334                     } catch (Throwable e) {
    335                         Log.w(TAG, "Error playing ringtone, stream " + mStreamType, e);
    336                     }
    337                 }
    338             }
    339         }
    340     }
    341 
    342     private void postStopSample() {
    343         if (mHandler == null) return;
    344         // remove pending delayed start messages
    345         mHandler.removeMessages(MSG_START_SAMPLE);
    346         mHandler.removeMessages(MSG_STOP_SAMPLE);
    347         mHandler.sendMessage(mHandler.obtainMessage(MSG_STOP_SAMPLE));
    348     }
    349 
    350     private void onStopSample() {
    351         synchronized (this) {
    352             if (mRingtone != null) {
    353                 mRingtone.stop();
    354             }
    355         }
    356     }
    357 
    358     @UnsupportedAppUsage
    359     public void stop() {
    360         if (mHandler == null) return;  // already stopped
    361         postStopSample();
    362         mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
    363         mReceiver.setListening(false);
    364         if (hasAudioProductStrategies()) {
    365             unregisterVolumeGroupCb();
    366         }
    367         mSeekBar.setOnSeekBarChangeListener(null);
    368         mHandler.getLooper().quitSafely();
    369         mHandler = null;
    370         mVolumeObserver = null;
    371     }
    372 
    373     public void start() {
    374         if (mHandler != null) return;  // already started
    375         HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
    376         thread.start();
    377         mHandler = new Handler(thread.getLooper(), this);
    378         mHandler.sendEmptyMessage(MSG_INIT_SAMPLE);
    379         mVolumeObserver = new Observer(mHandler);
    380         mContext.getContentResolver().registerContentObserver(
    381                 System.getUriFor(System.VOLUME_SETTINGS_INT[mStreamType]),
    382                 false, mVolumeObserver);
    383         mReceiver.setListening(true);
    384         if (hasAudioProductStrategies()) {
    385             registerVolumeGroupCb();
    386         }
    387     }
    388 
    389     public void revertVolume() {
    390         mAudioManager.setStreamVolume(mStreamType, mOriginalStreamVolume, 0);
    391     }
    392 
    393     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
    394         if (fromTouch) {
    395             postSetVolume(progress);
    396         }
    397         if (mCallback != null) {
    398             mCallback.onProgressChanged(seekBar, progress, fromTouch);
    399         }
    400     }
    401 
    402     private void postSetVolume(int progress) {
    403         if (mHandler == null) return;
    404         // Do the volume changing separately to give responsive UI
    405         mLastProgress = progress;
    406         mHandler.removeMessages(MSG_SET_STREAM_VOLUME);
    407         mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_STREAM_VOLUME));
    408     }
    409 
    410     public void onStartTrackingTouch(SeekBar seekBar) {
    411     }
    412 
    413     public void onStopTrackingTouch(SeekBar seekBar) {
    414         postStartSample();
    415     }
    416 
    417     public boolean isSamplePlaying() {
    418         synchronized (this) {
    419             return mRingtone != null && mRingtone.isPlaying();
    420         }
    421     }
    422 
    423     public void startSample() {
    424         postStartSample();
    425     }
    426 
    427     public void stopSample() {
    428         postStopSample();
    429     }
    430 
    431     public SeekBar getSeekBar() {
    432         return mSeekBar;
    433     }
    434 
    435     public void changeVolumeBy(int amount) {
    436         mSeekBar.incrementProgressBy(amount);
    437         postSetVolume(mSeekBar.getProgress());
    438         postStartSample();
    439         mVolumeBeforeMute = -1;
    440     }
    441 
    442     public void muteVolume() {
    443         if (mVolumeBeforeMute != -1) {
    444             mSeekBar.setProgress(mVolumeBeforeMute, true);
    445             postSetVolume(mVolumeBeforeMute);
    446             postStartSample();
    447             mVolumeBeforeMute = -1;
    448         } else {
    449             mVolumeBeforeMute = mSeekBar.getProgress();
    450             mSeekBar.setProgress(0, true);
    451             postStopSample();
    452             postSetVolume(0);
    453         }
    454     }
    455 
    456     public void onSaveInstanceState(VolumeStore volumeStore) {
    457         if (mLastProgress >= 0) {
    458             volumeStore.volume = mLastProgress;
    459             volumeStore.originalVolume = mOriginalStreamVolume;
    460         }
    461     }
    462 
    463     public void onRestoreInstanceState(VolumeStore volumeStore) {
    464         if (volumeStore.volume != -1) {
    465             mOriginalStreamVolume = volumeStore.originalVolume;
    466             mLastProgress = volumeStore.volume;
    467             postSetVolume(mLastProgress);
    468         }
    469     }
    470 
    471     private final class H extends Handler {
    472         private static final int UPDATE_SLIDER = 1;
    473 
    474         @Override
    475         public void handleMessage(Message msg) {
    476             if (msg.what == UPDATE_SLIDER) {
    477                 if (mSeekBar != null) {
    478                     mLastProgress = msg.arg1;
    479                     mLastAudibleStreamVolume = msg.arg2;
    480                     final boolean muted = ((Boolean)msg.obj).booleanValue();
    481                     if (muted != mMuted) {
    482                         mMuted = muted;
    483                         if (mCallback != null) {
    484                             mCallback.onMuted(mMuted, isZenMuted());
    485                         }
    486                     }
    487                     updateSeekBar();
    488                 }
    489             }
    490         }
    491 
    492         public void postUpdateSlider(int volume, int lastAudibleVolume, boolean mute) {
    493             obtainMessage(UPDATE_SLIDER, volume, lastAudibleVolume, new Boolean(mute)).sendToTarget();
    494         }
    495     }
    496 
    497     private void updateSlider() {
    498         if (mSeekBar != null && mAudioManager != null) {
    499             final int volume = mAudioManager.getStreamVolume(mStreamType);
    500             final int lastAudibleVolume = mAudioManager.getLastAudibleStreamVolume(mStreamType);
    501             final boolean mute = mAudioManager.isStreamMute(mStreamType);
    502             mUiHandler.postUpdateSlider(volume, lastAudibleVolume, mute);
    503         }
    504     }
    505 
    506     private final class Observer extends ContentObserver {
    507         public Observer(Handler handler) {
    508             super(handler);
    509         }
    510 
    511         @Override
    512         public void onChange(boolean selfChange) {
    513             super.onChange(selfChange);
    514             updateSlider();
    515         }
    516     }
    517 
    518     private final class Receiver extends BroadcastReceiver {
    519         private boolean mListening;
    520 
    521         public void setListening(boolean listening) {
    522             if (mListening == listening) return;
    523             mListening = listening;
    524             if (listening) {
    525                 final IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
    526                 filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
    527                 filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
    528                 filter.addAction(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
    529                 filter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
    530                 mContext.registerReceiver(this, filter);
    531             } else {
    532                 mContext.unregisterReceiver(this);
    533             }
    534         }
    535 
    536         @Override
    537         public void onReceive(Context context, Intent intent) {
    538             final String action = intent.getAction();
    539             if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
    540                 int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
    541                 int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
    542                 if (hasAudioProductStrategies()) {
    543                     updateVolumeSlider(streamType, streamValue);
    544                 }
    545             } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
    546                 if (mNotificationOrRing) {
    547                     mRingerMode = mAudioManager.getRingerModeInternal();
    548                 }
    549                 if (mAffectedByRingerMode) {
    550                     updateSlider();
    551                 }
    552             } else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
    553                 int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
    554                 if (hasAudioProductStrategies()) {
    555                     int streamVolume = mAudioManager.getStreamVolume(streamType);
    556                     updateVolumeSlider(streamType, streamVolume);
    557                 } else {
    558                     int volumeGroup = getVolumeGroupIdForLegacyStreamType(streamType);
    559                     if (volumeGroup != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
    560                             && volumeGroup == mVolumeGroupId) {
    561                         int streamVolume = mAudioManager.getStreamVolume(streamType);
    562                         updateVolumeSlider(streamType, streamVolume);
    563                     }
    564                 }
    565             } else if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED.equals(action)) {
    566                 mZenMode = mNotificationManager.getZenMode();
    567                 updateSlider();
    568             } else if (NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED.equals(action)) {
    569                 mNotificationPolicy = mNotificationManager.getConsolidatedNotificationPolicy();
    570                 mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
    571                         .PRIORITY_CATEGORY_ALARMS) != 0;
    572                 mAllowMedia = (mNotificationPolicy.priorityCategories
    573                         & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) != 0;
    574                 mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(
    575                         mNotificationPolicy);
    576                 updateSlider();
    577             }
    578         }
    579 
    580         private void updateVolumeSlider(int streamType, int streamValue) {
    581             final boolean streamMatch = mNotificationOrRing ? isNotificationOrRing(streamType)
    582                     : (streamType == mStreamType);
    583             if (mSeekBar != null && streamMatch && streamValue != -1) {
    584                 final boolean muted = mAudioManager.isStreamMute(mStreamType)
    585                         || streamValue == 0;
    586                 mUiHandler.postUpdateSlider(streamValue, mLastAudibleStreamVolume, muted);
    587             }
    588         }
    589     }
    590 
    591     private void registerVolumeGroupCb() {
    592         if (mVolumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
    593             mAudioManager.registerVolumeGroupCallback(Runnable::run, mVolumeGroupCallback);
    594             updateSlider();
    595         }
    596     }
    597 
    598     private void unregisterVolumeGroupCb() {
    599         if (mVolumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
    600             mAudioManager.unregisterVolumeGroupCallback(mVolumeGroupCallback);
    601         }
    602     }
    603 
    604     private class VolumeHandler extends Handler {
    605         @Override
    606         public void handleMessage(Message msg) {
    607             SomeArgs args = (SomeArgs) msg.obj;
    608             switch (msg.what) {
    609                 case MSG_GROUP_VOLUME_CHANGED:
    610                     int group = (int) args.arg1;
    611                     if (mVolumeGroupId != group
    612                             || mVolumeGroupId == AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
    613                         return;
    614                     }
    615                     updateSlider();
    616                     break;
    617             }
    618         }
    619     }
    620 }
    621