blob: 229783768076e6390df73da097c659858ba1e1b1 [file] [log] [blame]
Doris Ling1b3ec042016-11-30 17:33:50 -08001/*
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
17package com.android.settings.notification;
18
19import android.app.NotificationManager;
20import android.content.BroadcastReceiver;
21import android.content.ComponentName;
22import android.content.Context;
23import android.content.Intent;
24import android.content.IntentFilter;
25import android.content.pm.PackageManager;
26import android.content.pm.ServiceInfo;
27import android.media.AudioManager;
28import android.os.Handler;
29import android.os.Looper;
30import android.os.Message;
31import android.os.Vibrator;
32import android.util.Log;
33
34import com.android.internal.annotations.VisibleForTesting;
35import com.android.settings.Utils;
36import com.android.settings.core.lifecycle.Lifecycle;
37import com.android.settings.notification.VolumeSeekBarPreference.Callback;
38
39import java.util.Objects;
40
41public class RingVolumePreferenceController extends VolumeSeekBarPreferenceController {
42
43 private static final String TAG = "RingVolumeController";
44 private static final String KEY_RING_VOLUME = "ring_volume";
45
46 private AudioManager mAudioManager;
47 private Vibrator mVibrator;
48 private int mRingerMode = -1;
49 private ComponentName mSuppressor;
50 private final RingReceiver mReceiver = new RingReceiver();
51 private final H mHandler = new H();
52 private AudioHelper mHelper;
53
54 public RingVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle) {
55 this(context, callback, lifecycle, new AudioHelper(context));
56 }
57
58 @VisibleForTesting
59 RingVolumePreferenceController(Context context, Callback callback, Lifecycle lifecycle,
60 AudioHelper helper) {
61 super(context, callback, lifecycle);
62 mHelper = helper;
63 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
64 mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
65 if (mVibrator != null && !mVibrator.hasVibrator()) {
66 mVibrator = null;
67 }
68 updateRingerMode();
69 }
70
71 @Override
72 public void onResume() {
73 super.onResume();
74 mReceiver.register(true);
75 updateEffectsSuppressor();
76 updatePreferenceIcon();
77 }
78
79 @Override
80 public void onPause() {
81 super.onPause();
82 mReceiver.register(false);
83 }
84
85 @Override
86 public String getPreferenceKey() {
87 return KEY_RING_VOLUME;
88 }
89
90 @Override
91 public boolean isAvailable() {
92 return Utils.isVoiceCapable(mContext) && !mHelper.isSingleVolume();
93 }
94
95 @Override
96 public int getAudioStream() {
97 return AudioManager.STREAM_RING;
98 }
99
100 @Override
101 public int getMuteIcon() {
102 return com.android.internal.R.drawable.ic_audio_ring_notif_mute;
103 }
104
105 private void updateRingerMode() {
106 final int ringerMode = mAudioManager.getRingerModeInternal();
107 if (mRingerMode == ringerMode) return;
108 mRingerMode = ringerMode;
109 updatePreferenceIcon();
110 }
111
112 private boolean wasRingerModeVibrate() {
113 return mVibrator != null && mRingerMode == AudioManager.RINGER_MODE_SILENT
114 && mAudioManager.getLastAudibleStreamVolume(AudioManager.STREAM_RING) == 0;
115 }
116
117 private void updateEffectsSuppressor() {
118 final ComponentName suppressor = NotificationManager.from(mContext).getEffectsSuppressor();
119 if (Objects.equals(suppressor, mSuppressor)) return;
120 mSuppressor = suppressor;
121 if (mPreference != null) {
122 final String text = suppressor != null ?
123 mContext.getString(com.android.internal.R.string.muted_by,
124 getSuppressorCaption(suppressor)) : null;
125 mPreference.setSuppressionText(text);
126 }
127 updatePreferenceIcon();
128 }
129
130 private void updatePreferenceIcon() {
131 if (mPreference != null) {
132 mPreference.showIcon(mSuppressor != null
133 ? com.android.internal.R.drawable.ic_audio_ring_notif_mute
134 : mRingerMode == AudioManager.RINGER_MODE_VIBRATE || wasRingerModeVibrate()
135 ? com.android.internal.R.drawable.ic_audio_ring_notif_vibrate
136 : com.android.internal.R.drawable.ic_audio_ring_notif);
137 }
138 }
139
140 private String getSuppressorCaption(ComponentName suppressor) {
141 final PackageManager pm = mContext.getPackageManager();
142 try {
143 final ServiceInfo info = pm.getServiceInfo(suppressor, 0);
144 if (info != null) {
145 final CharSequence seq = info.loadLabel(pm);
146 if (seq != null) {
147 final String str = seq.toString().trim();
148 if (str.length() > 0) {
149 return str;
150 }
151 }
152 }
153 } catch (Throwable e) {
154 Log.w(TAG, "Error loading suppressor caption", e);
155 }
156 return suppressor.getPackageName();
157 }
158
159 private final class H extends Handler {
160 private static final int UPDATE_EFFECTS_SUPPRESSOR = 1;
161 private static final int UPDATE_RINGER_MODE = 2;
162
163 private H() {
164 super(Looper.getMainLooper());
165 }
166
167 @Override
168 public void handleMessage(Message msg) {
169 switch (msg.what) {
170 case UPDATE_EFFECTS_SUPPRESSOR:
171 updateEffectsSuppressor();
172 break;
173 case UPDATE_RINGER_MODE:
174 updateRingerMode();
175 break;
176 }
177 }
178 }
179
180 private class RingReceiver extends BroadcastReceiver {
181 private boolean mRegistered;
182
183 public void register(boolean register) {
184 if (mRegistered == register) return;
185 if (register) {
186 final IntentFilter filter = new IntentFilter();
187 filter.addAction(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
188 filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
189 mContext.registerReceiver(this, filter);
190 } else {
191 mContext.unregisterReceiver(this);
192 }
193 mRegistered = register;
194 }
195
196 @Override
197 public void onReceive(Context context, Intent intent) {
198 final String action = intent.getAction();
199 if (NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED.equals(action)) {
200 mHandler.sendEmptyMessage(H.UPDATE_EFFECTS_SUPPRESSOR);
201 } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
202 mHandler.sendEmptyMessage(H.UPDATE_RINGER_MODE);
203 }
204 }
205 }
206
207}