blob: 91821bad988af3221e5492d5f6fc1a09fead4ccd [file] [log] [blame]
John Spurlock3c4076a2015-02-24 12:12:25 -05001/*
2 * Copyright (C) 2015 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.systemui.qs.tiles;
18
19import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.content.SharedPreferences;
John Spurlockcd863ad2015-04-07 14:01:28 -040024import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
Sudheer Shanka1c7cda82015-12-31 14:46:02 +000025import android.os.UserManager;
John Spurlock3c4076a2015-02-24 12:12:25 -050026import android.provider.Settings;
27import android.provider.Settings.Global;
28import android.view.LayoutInflater;
29import android.view.View;
30import android.view.View.OnAttachStateChangeListener;
31import android.view.ViewGroup;
Julia Reynolds20aef8a2016-05-04 16:44:08 -040032import android.widget.Switch;
Sudheer Shankaa8fbbb32016-02-11 17:17:57 +000033import android.widget.Toast;
Chris Wrenf6e9228b2016-01-26 18:04:35 -050034
Chris Wren457a21c2015-05-06 17:50:34 -040035import com.android.internal.logging.MetricsLogger;
Chris Wrenf6e9228b2016-01-26 18:04:35 -050036import com.android.internal.logging.MetricsProto.MetricsEvent;
Andrew Flynn82862572015-04-01 14:22:37 -040037import com.android.systemui.Prefs;
John Spurlock3c4076a2015-02-24 12:12:25 -050038import com.android.systemui.R;
Sudheer Shankaa8fbbb32016-02-11 17:17:57 +000039import com.android.systemui.SysUIToast;
John Spurlock3c4076a2015-02-24 12:12:25 -050040import com.android.systemui.qs.QSTile;
41import com.android.systemui.statusbar.policy.ZenModeController;
42import com.android.systemui.volume.ZenModePanel;
43
44/** Quick settings tile: Do not disturb **/
45public class DndTile extends QSTile<QSTile.BooleanState> {
John Spurlock036e7cb2015-06-15 13:49:57 -040046
John Spurlockd9c75db2015-04-28 11:19:13 -040047 private static final Intent ZEN_SETTINGS =
48 new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
49
50 private static final Intent ZEN_PRIORITY_SETTINGS =
51 new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS);
John Spurlock3c4076a2015-02-24 12:12:25 -050052
53 private static final String ACTION_SET_VISIBLE = "com.android.systemui.dndtile.SET_VISIBLE";
54 private static final String EXTRA_VISIBLE = "visible";
John Spurlock3c4076a2015-02-24 12:12:25 -050055
John Spurlock036e7cb2015-06-15 13:49:57 -040056 private static final QSTile.Icon TOTAL_SILENCE =
57 ResourceIcon.get(R.drawable.ic_qs_dnd_on_total_silence);
58
59 private final AnimationIcon mDisable =
Jason Monk1aec93f2016-03-01 09:39:30 -050060 new AnimationIcon(R.drawable.ic_dnd_disable_animation,
61 R.drawable.ic_qs_dnd_off);
John Spurlock036e7cb2015-06-15 13:49:57 -040062 private final AnimationIcon mDisableTotalSilence =
Jason Monk1aec93f2016-03-01 09:39:30 -050063 new AnimationIcon(R.drawable.ic_dnd_total_silence_disable_animation,
64 R.drawable.ic_qs_dnd_off);
John Spurlock036e7cb2015-06-15 13:49:57 -040065
John Spurlock3c4076a2015-02-24 12:12:25 -050066 private final ZenModeController mController;
67 private final DndDetailAdapter mDetailAdapter;
68
69 private boolean mListening;
John Spurlock3c4076a2015-02-24 12:12:25 -050070 private boolean mShowingDetail;
71
72 public DndTile(Host host) {
73 super(host);
74 mController = host.getZenModeController();
75 mDetailAdapter = new DndDetailAdapter();
John Spurlock3c4076a2015-02-24 12:12:25 -050076 mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_SET_VISIBLE));
77 }
78
79 public static void setVisible(Context context, boolean visible) {
Andrew Flynn82862572015-04-01 14:22:37 -040080 Prefs.putBoolean(context, Prefs.Key.DND_TILE_VISIBLE, visible);
John Spurlock3c4076a2015-02-24 12:12:25 -050081 }
82
83 public static boolean isVisible(Context context) {
Andrew Flynn82862572015-04-01 14:22:37 -040084 return Prefs.getBoolean(context, Prefs.Key.DND_TILE_VISIBLE, false /* defaultValue */);
John Spurlock3c4076a2015-02-24 12:12:25 -050085 }
86
John Spurlockf88d8082015-03-25 18:09:51 -040087 public static void setCombinedIcon(Context context, boolean combined) {
Andrew Flynn82862572015-04-01 14:22:37 -040088 Prefs.putBoolean(context, Prefs.Key.DND_TILE_COMBINED_ICON, combined);
John Spurlockf88d8082015-03-25 18:09:51 -040089 }
90
91 public static boolean isCombinedIcon(Context context) {
Andrew Flynn82862572015-04-01 14:22:37 -040092 return Prefs.getBoolean(context, Prefs.Key.DND_TILE_COMBINED_ICON,
93 false /* defaultValue */);
John Spurlockf88d8082015-03-25 18:09:51 -040094 }
95
John Spurlock3c4076a2015-02-24 12:12:25 -050096 @Override
97 public DetailAdapter getDetailAdapter() {
98 return mDetailAdapter;
99 }
100
101 @Override
Jason Monk62b63a02016-02-02 15:15:31 -0500102 public BooleanState newTileState() {
John Spurlock3c4076a2015-02-24 12:12:25 -0500103 return new BooleanState();
104 }
105
106 @Override
Jason Monk76c67aa2016-02-19 14:49:42 -0500107 public Intent getLongClickIntent() {
108 return ZEN_SETTINGS;
109 }
110
111 @Override
John Spurlock3c4076a2015-02-24 12:12:25 -0500112 public void handleClick() {
Sudheer Shankaa8fbbb32016-02-11 17:17:57 +0000113 if (mController.isVolumeRestricted()) {
114 // Collapse the panels, so the user can see the toast.
115 mHost.collapsePanels();
116 SysUIToast.makeText(mContext, mContext.getString(
117 com.android.internal.R.string.error_message_change_not_allowed),
118 Toast.LENGTH_LONG).show();
119 return;
120 }
Chris Wren9e7283f2015-05-08 17:23:47 -0400121 MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
John Spurlock3c4076a2015-02-24 12:12:25 -0500122 if (mState.value) {
John Spurlockb2278d62015-04-07 12:47:12 -0400123 mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
John Spurlock3c4076a2015-02-24 12:12:25 -0500124 } else {
Jason Monk48e093e2016-07-15 10:37:07 -0400125 showDetail(true);
John Spurlockd9c75db2015-04-28 11:19:13 -0400126 int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
127 mController.setZen(zen, null, TAG);
John Spurlock3c4076a2015-02-24 12:12:25 -0500128 }
129 }
130
131 @Override
Jason Monk39c98e62016-03-16 09:18:35 -0400132 public CharSequence getTileLabel() {
133 return mContext.getString(R.string.quick_settings_dnd_label);
134 }
135
136 @Override
John Spurlock3c4076a2015-02-24 12:12:25 -0500137 protected void handleUpdateState(BooleanState state, Object arg) {
138 final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
John Spurlockb1688f62015-05-12 15:52:38 -0400139 final boolean newValue = zen != Global.ZEN_MODE_OFF;
140 final boolean valueChanged = state.value != newValue;
141 state.value = newValue;
Sudheer Shankaa8fbbb32016-02-11 17:17:57 +0000142 checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
John Spurlock3c4076a2015-02-24 12:12:25 -0500143 switch (zen) {
144 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
145 state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
146 state.label = mContext.getString(R.string.quick_settings_dnd_priority_label);
147 state.contentDescription = mContext.getString(
148 R.string.accessibility_quick_settings_dnd_priority_on);
149 break;
150 case Global.ZEN_MODE_NO_INTERRUPTIONS:
John Spurlock036e7cb2015-06-15 13:49:57 -0400151 state.icon = TOTAL_SILENCE;
John Spurlock3c4076a2015-02-24 12:12:25 -0500152 state.label = mContext.getString(R.string.quick_settings_dnd_none_label);
153 state.contentDescription = mContext.getString(
154 R.string.accessibility_quick_settings_dnd_none_on);
155 break;
John Spurlock4f1163c2015-04-02 17:41:21 -0400156 case Global.ZEN_MODE_ALARMS:
157 state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
158 state.label = mContext.getString(R.string.quick_settings_dnd_alarms_label);
159 state.contentDescription = mContext.getString(
160 R.string.accessibility_quick_settings_dnd_alarms_on);
161 break;
John Spurlock3c4076a2015-02-24 12:12:25 -0500162 default:
John Spurlock036e7cb2015-06-15 13:49:57 -0400163 state.icon = TOTAL_SILENCE.equals(state.icon) ? mDisableTotalSilence : mDisable;
John Spurlock3c4076a2015-02-24 12:12:25 -0500164 state.label = mContext.getString(R.string.quick_settings_dnd_label);
165 state.contentDescription = mContext.getString(
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400166 R.string.accessibility_quick_settings_dnd);
John Spurlock3c4076a2015-02-24 12:12:25 -0500167 break;
168 }
169 if (mShowingDetail && !state.value) {
170 showDetail(false);
171 }
John Spurlockb1688f62015-05-12 15:52:38 -0400172 if (valueChanged) {
173 fireToggleStateChanged(state.value);
174 }
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400175 state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
176 = Switch.class.getName();
John Spurlock3c4076a2015-02-24 12:12:25 -0500177 }
178
179 @Override
Chris Wren457a21c2015-05-06 17:50:34 -0400180 public int getMetricsCategory() {
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500181 return MetricsEvent.QS_DND;
Chris Wren457a21c2015-05-06 17:50:34 -0400182 }
183
184 @Override
John Spurlock3c4076a2015-02-24 12:12:25 -0500185 protected String composeChangeAnnouncement() {
186 if (mState.value) {
187 return mContext.getString(R.string.accessibility_quick_settings_dnd_changed_on);
188 } else {
189 return mContext.getString(R.string.accessibility_quick_settings_dnd_changed_off);
190 }
191 }
192
193 @Override
194 public void setListening(boolean listening) {
195 if (mListening == listening) return;
196 mListening = listening;
197 if (mListening) {
198 mController.addCallback(mZenCallback);
Andrew Flynn82862572015-04-01 14:22:37 -0400199 Prefs.registerListener(mContext, mPrefListener);
John Spurlock3c4076a2015-02-24 12:12:25 -0500200 } else {
201 mController.removeCallback(mZenCallback);
Andrew Flynn82862572015-04-01 14:22:37 -0400202 Prefs.unregisterListener(mContext, mPrefListener);
John Spurlock3c4076a2015-02-24 12:12:25 -0500203 }
204 }
205
Jason Monkc3f42c12016-02-05 12:33:13 -0500206 @Override
207 public boolean isAvailable() {
208 return isVisible(mContext);
209 }
210
John Spurlockcd863ad2015-04-07 14:01:28 -0400211 private final OnSharedPreferenceChangeListener mPrefListener
212 = new OnSharedPreferenceChangeListener() {
213 @Override
Andrew Flynn82862572015-04-01 14:22:37 -0400214 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
215 @Prefs.Key String key) {
216 if (Prefs.Key.DND_TILE_COMBINED_ICON.equals(key) ||
217 Prefs.Key.DND_TILE_VISIBLE.equals(key)) {
John Spurlockcd863ad2015-04-07 14:01:28 -0400218 refreshState();
219 }
220 }
221 };
222
John Spurlock3c4076a2015-02-24 12:12:25 -0500223 private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
224 public void onZenChanged(int zen) {
225 refreshState(zen);
226 }
227 };
228
John Spurlock3c4076a2015-02-24 12:12:25 -0500229 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
230 @Override
231 public void onReceive(Context context, Intent intent) {
John Spurlockcd863ad2015-04-07 14:01:28 -0400232 final boolean visible = intent.getBooleanExtra(EXTRA_VISIBLE, false);
233 setVisible(mContext, visible);
John Spurlock3c4076a2015-02-24 12:12:25 -0500234 refreshState();
235 }
236 };
237
238 private final class DndDetailAdapter implements DetailAdapter, OnAttachStateChangeListener {
239
240 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500241 public CharSequence getTitle() {
242 return mContext.getString(R.string.quick_settings_dnd_label);
John Spurlock3c4076a2015-02-24 12:12:25 -0500243 }
244
245 @Override
246 public Boolean getToggleState() {
247 return mState.value;
248 }
249
250 @Override
251 public Intent getSettingsIntent() {
252 return ZEN_SETTINGS;
253 }
254
255 @Override
256 public void setToggleState(boolean state) {
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500257 MetricsLogger.action(mContext, MetricsEvent.QS_DND_TOGGLE, state);
John Spurlock3c4076a2015-02-24 12:12:25 -0500258 if (!state) {
John Spurlockb2278d62015-04-07 12:47:12 -0400259 mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
John Spurlock3c4076a2015-02-24 12:12:25 -0500260 showDetail(false);
261 }
262 }
263
264 @Override
Chris Wren457a21c2015-05-06 17:50:34 -0400265 public int getMetricsCategory() {
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500266 return MetricsEvent.QS_DND_DETAILS;
Chris Wren457a21c2015-05-06 17:50:34 -0400267 }
268
269 @Override
John Spurlock3c4076a2015-02-24 12:12:25 -0500270 public View createDetailView(Context context, View convertView, ViewGroup parent) {
271 final ZenModePanel zmp = convertView != null ? (ZenModePanel) convertView
272 : (ZenModePanel) LayoutInflater.from(context).inflate(
273 R.layout.zen_mode_panel, parent, false);
274 if (convertView == null) {
275 zmp.init(mController);
John Spurlock3c4076a2015-02-24 12:12:25 -0500276 zmp.addOnAttachStateChangeListener(this);
John Spurlockd9c75db2015-04-28 11:19:13 -0400277 zmp.setCallback(mZenModePanelCallback);
John Spurlock3c4076a2015-02-24 12:12:25 -0500278 }
279 return zmp;
280 }
281
282 @Override
283 public void onViewAttachedToWindow(View v) {
284 mShowingDetail = true;
285 }
286
287 @Override
288 public void onViewDetachedFromWindow(View v) {
289 mShowingDetail = false;
290 }
291 }
John Spurlockd9c75db2015-04-28 11:19:13 -0400292
293 private final ZenModePanel.Callback mZenModePanelCallback = new ZenModePanel.Callback() {
294 @Override
295 public void onPrioritySettings() {
Jason Monkee43cdf2015-06-19 14:20:46 -0400296 mHost.startActivityDismissingKeyguard(ZEN_PRIORITY_SETTINGS);
John Spurlockd9c75db2015-04-28 11:19:13 -0400297 }
298
299 @Override
300 public void onInteraction() {
301 // noop
302 }
303
304 @Override
305 public void onExpanded(boolean expanded) {
306 // noop
307 }
308 };
309
John Spurlock3c4076a2015-02-24 12:12:25 -0500310}