DndTile.java revision 457a21cdeac04565a0c40ad8c43a928c1182ddd1
1/*
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;
24import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
25import android.provider.Settings;
26import android.provider.Settings.Global;
27import android.view.LayoutInflater;
28import android.view.View;
29import android.view.View.OnAttachStateChangeListener;
30import android.view.ViewGroup;
31
32import com.android.internal.logging.MetricsLogger;
33import com.android.systemui.Prefs;
34import com.android.systemui.R;
35import com.android.systemui.qs.QSTile;
36import com.android.systemui.statusbar.policy.ZenModeController;
37import com.android.systemui.volume.ZenModePanel;
38
39/** Quick settings tile: Do not disturb **/
40public class DndTile extends QSTile<QSTile.BooleanState> {
41    private static final Intent ZEN_SETTINGS =
42            new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
43
44    private static final Intent ZEN_PRIORITY_SETTINGS =
45            new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS);
46
47    private static final String ACTION_SET_VISIBLE = "com.android.systemui.dndtile.SET_VISIBLE";
48    private static final String EXTRA_VISIBLE = "visible";
49
50    private final ZenModeController mController;
51    private final DndDetailAdapter mDetailAdapter;
52
53    private boolean mListening;
54    private boolean mShowingDetail;
55
56    public DndTile(Host host) {
57        super(host);
58        mController = host.getZenModeController();
59        mDetailAdapter = new DndDetailAdapter();
60        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_SET_VISIBLE));
61    }
62
63    public static void setVisible(Context context, boolean visible) {
64        Prefs.putBoolean(context, Prefs.Key.DND_TILE_VISIBLE, visible);
65    }
66
67    public static boolean isVisible(Context context) {
68        return Prefs.getBoolean(context, Prefs.Key.DND_TILE_VISIBLE, false /* defaultValue */);
69    }
70
71    public static void setCombinedIcon(Context context, boolean combined) {
72        Prefs.putBoolean(context, Prefs.Key.DND_TILE_COMBINED_ICON, combined);
73    }
74
75    public static boolean isCombinedIcon(Context context) {
76        return Prefs.getBoolean(context, Prefs.Key.DND_TILE_COMBINED_ICON,
77                false /* defaultValue */);
78    }
79
80    @Override
81    public DetailAdapter getDetailAdapter() {
82        return mDetailAdapter;
83    }
84
85    @Override
86    protected BooleanState newTileState() {
87        return new BooleanState();
88    }
89
90    @Override
91    public void handleClick() {
92        super.handleClick();
93        if (mState.value) {
94            mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
95        } else {
96            int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
97            mController.setZen(zen, null, TAG);
98            refreshState(zen); // this one's optimistic
99            showDetail(true);
100        }
101    }
102
103    @Override
104    protected void handleUpdateState(BooleanState state, Object arg) {
105        final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
106        state.value = zen != Global.ZEN_MODE_OFF;
107        state.visible = isVisible(mContext);
108        switch (zen) {
109            case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
110                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
111                state.label = mContext.getString(R.string.quick_settings_dnd_priority_label);
112                state.contentDescription = mContext.getString(
113                        R.string.accessibility_quick_settings_dnd_priority_on);
114                break;
115            case Global.ZEN_MODE_NO_INTERRUPTIONS:
116                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
117                state.label = mContext.getString(R.string.quick_settings_dnd_none_label);
118                state.contentDescription = mContext.getString(
119                        R.string.accessibility_quick_settings_dnd_none_on);
120                break;
121            case Global.ZEN_MODE_ALARMS:
122                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
123                state.label = mContext.getString(R.string.quick_settings_dnd_alarms_label);
124                state.contentDescription = mContext.getString(
125                        R.string.accessibility_quick_settings_dnd_alarms_on);
126                break;
127            default:
128                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_off);
129                state.label = mContext.getString(R.string.quick_settings_dnd_label);
130                state.contentDescription =  mContext.getString(
131                        R.string.accessibility_quick_settings_dnd_off);
132                break;
133        }
134        if (mShowingDetail && !state.value) {
135            showDetail(false);
136        }
137    }
138
139    @Override
140    public int getMetricsCategory() {
141        return MetricsLogger.QS_DND;
142    }
143
144    @Override
145    protected String composeChangeAnnouncement() {
146        if (mState.value) {
147            return mContext.getString(R.string.accessibility_quick_settings_dnd_changed_on);
148        } else {
149            return mContext.getString(R.string.accessibility_quick_settings_dnd_changed_off);
150        }
151    }
152
153    @Override
154    public void setListening(boolean listening) {
155        if (mListening == listening) return;
156        mListening = listening;
157        if (mListening) {
158            mController.addCallback(mZenCallback);
159            Prefs.registerListener(mContext, mPrefListener);
160        } else {
161            mController.removeCallback(mZenCallback);
162            Prefs.unregisterListener(mContext, mPrefListener);
163        }
164    }
165
166    private final OnSharedPreferenceChangeListener mPrefListener
167            = new OnSharedPreferenceChangeListener() {
168        @Override
169        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
170                @Prefs.Key String key) {
171            if (Prefs.Key.DND_TILE_COMBINED_ICON.equals(key) ||
172                    Prefs.Key.DND_TILE_VISIBLE.equals(key)) {
173                refreshState();
174            }
175        }
176    };
177
178    private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
179        public void onZenChanged(int zen) {
180            refreshState(zen);
181        }
182    };
183
184    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
185        @Override
186        public void onReceive(Context context, Intent intent) {
187            final boolean visible = intent.getBooleanExtra(EXTRA_VISIBLE, false);
188            setVisible(mContext, visible);
189            refreshState();
190        }
191    };
192
193    private final class DndDetailAdapter implements DetailAdapter, OnAttachStateChangeListener {
194
195        @Override
196        public int getTitle() {
197            return R.string.quick_settings_dnd_label;
198        }
199
200        @Override
201        public Boolean getToggleState() {
202            return mState.value;
203        }
204
205        @Override
206        public Intent getSettingsIntent() {
207            return ZEN_SETTINGS;
208        }
209
210        @Override
211        public void setToggleState(boolean state) {
212            if (!state) {
213                mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
214                showDetail(false);
215            }
216        }
217
218        @Override
219        public int getMetricsCategory() {
220            return MetricsLogger.QS_DND_DETAILS;
221        }
222
223        @Override
224        public View createDetailView(Context context, View convertView, ViewGroup parent) {
225            final ZenModePanel zmp = convertView != null ? (ZenModePanel) convertView
226                    : (ZenModePanel) LayoutInflater.from(context).inflate(
227                            R.layout.zen_mode_panel, parent, false);
228            if (convertView == null) {
229                zmp.init(mController);
230                zmp.addOnAttachStateChangeListener(this);
231                zmp.setCallback(mZenModePanelCallback);
232            }
233            return zmp;
234        }
235
236        @Override
237        public void onViewAttachedToWindow(View v) {
238            mShowingDetail = true;
239        }
240
241        @Override
242        public void onViewDetachedFromWindow(View v) {
243            mShowingDetail = false;
244        }
245    }
246
247    private final ZenModePanel.Callback mZenModePanelCallback = new ZenModePanel.Callback() {
248        @Override
249        public void onPrioritySettings() {
250            mHost.startSettingsActivity(ZEN_PRIORITY_SETTINGS);
251        }
252
253        @Override
254        public void onInteraction() {
255            // noop
256        }
257
258        @Override
259        public void onExpanded(boolean expanded) {
260            // noop
261        }
262    };
263
264}
265