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