1 /*
2  * Copyright (C) 2016 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 com.android.settings.notification;
18 
19 import android.app.NotificationManager;
20 import android.content.BroadcastReceiver;
21 import android.content.ComponentName;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.media.AudioManager;
26 import android.os.Handler;
27 import android.os.Looper;
28 import android.os.Message;
29 import android.os.Vibrator;
30 import android.text.TextUtils;
31 
32 import androidx.lifecycle.OnLifecycleEvent;
33 
34 import com.android.settings.R;
35 import com.android.settings.Utils;
36 import com.android.settingslib.core.lifecycle.Lifecycle;
37 
38 import java.util.Objects;
39 
40 public class RingVolumePreferenceController extends VolumeSeekBarPreferenceController {
41 
42     private static final String TAG = "RingVolumeController";
43     private static final String KEY_RING_VOLUME = "ring_volume";
44 
45     private Vibrator mVibrator;
46     private int mRingerMode = -1;
47     private ComponentName mSuppressor;
48     private final RingReceiver mReceiver = new RingReceiver();
49     private final H mHandler = new H();
50 
51     private int mMuteIcon;
52 
RingVolumePreferenceController(Context context)53     public RingVolumePreferenceController(Context context) {
54         this(context, KEY_RING_VOLUME);
55     }
56 
RingVolumePreferenceController(Context context, String key)57     public RingVolumePreferenceController(Context context, String key) {
58         super(context, key);
59         mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
60         if (mVibrator != null && !mVibrator.hasVibrator()) {
61             mVibrator = null;
62         }
63         updateRingerMode();
64     }
65 
66     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
67     @Override
onResume()68     public void onResume() {
69         super.onResume();
70         mReceiver.register(true);
71         updateEffectsSuppressor();
72         updatePreferenceIcon();
73     }
74 
75     @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
76     @Override
onPause()77     public void onPause() {
78         super.onPause();
79         mReceiver.register(false);
80     }
81 
82     @Override
getPreferenceKey()83     public String getPreferenceKey() {
84         return KEY_RING_VOLUME;
85     }
86 
87     @Override
getAvailabilityStatus()88     public int getAvailabilityStatus() {
89         return Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume()
90                 ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
91     }
92 
93     @Override
isSliceable()94     public boolean isSliceable() {
95         return TextUtils.equals(getPreferenceKey(), KEY_RING_VOLUME);
96     }
97 
98     @Override
isPublicSlice()99     public boolean isPublicSlice() {
100         return true;
101     }
102 
103     @Override
useDynamicSliceSummary()104     public boolean useDynamicSliceSummary() {
105         return true;
106     }
107 
108     @Override
getAudioStream()109     public int getAudioStream() {
110         return AudioManager.STREAM_RING;
111     }
112 
113     @Override
getMuteIcon()114     public int getMuteIcon() {
115         return mMuteIcon;
116     }
117 
updateRingerMode()118     private void updateRingerMode() {
119         final int ringerMode = mHelper.getRingerModeInternal();
120         if (mRingerMode == ringerMode) return;
121         mRingerMode = ringerMode;
122         updatePreferenceIcon();
123     }
124 
updateEffectsSuppressor()125     private void updateEffectsSuppressor() {
126         final ComponentName suppressor = NotificationManager.from(mContext).getEffectsSuppressor();
127         if (Objects.equals(suppressor, mSuppressor)) return;
128         mSuppressor = suppressor;
129         if (mPreference != null) {
130             final String text = SuppressorHelper.getSuppressionText(mContext, suppressor);
131             mPreference.setSuppressionText(text);
132         }
133         updatePreferenceIcon();
134     }
135 
updatePreferenceIcon()136     private void updatePreferenceIcon() {
137         if (mPreference != null) {
138             if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
139                 mMuteIcon = R.drawable.ic_volume_ringer_vibrate;
140                 mPreference.showIcon(R.drawable.ic_volume_ringer_vibrate);
141             } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT) {
142                 mMuteIcon = R.drawable.ic_notifications_off_24dp;
143                 mPreference.showIcon(R.drawable.ic_notifications_off_24dp);
144             } else {
145                 mPreference.showIcon(R.drawable.ic_notifications);
146             }
147         }
148     }
149 
150     private final class H extends Handler {
151         private static final int UPDATE_EFFECTS_SUPPRESSOR = 1;
152         private static final int UPDATE_RINGER_MODE = 2;
153 
H()154         private H() {
155             super(Looper.getMainLooper());
156         }
157 
158         @Override
handleMessage(Message msg)159         public void handleMessage(Message msg) {
160             switch (msg.what) {
161                 case UPDATE_EFFECTS_SUPPRESSOR:
162                     updateEffectsSuppressor();
163                     break;
164                 case UPDATE_RINGER_MODE:
165                     updateRingerMode();
166                     break;
167             }
168         }
169     }
170 
171     private class RingReceiver extends BroadcastReceiver {
172         private boolean mRegistered;
173 
register(boolean register)174         public void register(boolean register) {
175             if (mRegistered == register) return;
176             if (register) {
177                 final IntentFilter filter = new IntentFilter();
178                 filter.addAction(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
179                 filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
180                 mContext.registerReceiver(this, filter);
181             } else {
182                 mContext.unregisterReceiver(this);
183             }
184             mRegistered = register;
185         }
186 
187         @Override
onReceive(Context context, Intent intent)188         public void onReceive(Context context, Intent intent) {
189             final String action = intent.getAction();
190             if (NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED.equals(action)) {
191                 mHandler.sendEmptyMessage(H.UPDATE_EFFECTS_SUPPRESSOR);
192             } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
193                 mHandler.sendEmptyMessage(H.UPDATE_RINGER_MODE);
194             }
195         }
196     }
197 
198 }
199