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