ZenModeSettings.java revision 4a35051565b0ce6d29313c3e4ffe19e1dde78db0
1/*
2 * Copyright (C) 2014 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.ActionBar;
20import android.app.Activity;
21import android.content.Context;
22import android.content.res.Resources;
23import android.database.ContentObserver;
24import android.graphics.Typeface;
25import android.graphics.drawable.Drawable;
26import android.net.Uri;
27import android.os.AsyncTask;
28import android.os.Bundle;
29import android.os.Handler;
30import android.provider.Settings.Global;
31import android.provider.SearchIndexableResource;
32import android.util.Log;
33import android.util.TypedValue;
34import android.view.Gravity;
35import android.view.LayoutInflater;
36import android.view.Menu;
37import android.view.MenuInflater;
38import android.view.MenuItem;
39import android.view.View;
40import android.view.ViewGroup;
41import android.widget.CompoundButton;
42import android.widget.CompoundButton.OnCheckedChangeListener;
43import android.widget.LinearLayout;
44import android.widget.RelativeLayout;
45import android.widget.ScrollView;
46import android.widget.Switch;
47import android.widget.TextView;
48import com.android.settings.search.BaseSearchIndexProvider;
49
50import com.android.settings.R;
51import com.android.settings.SettingsPreferenceFragment;
52import com.android.settings.search.Indexable;
53import com.android.settings.search.SearchIndexableRaw;
54
55import java.util.ArrayList;
56import java.util.List;
57
58public class ZenModeSettings extends SettingsPreferenceFragment implements Indexable {
59    private static final String TAG = "ZenModeSettings";
60    private static final boolean DEBUG = false;
61
62    private final Handler mHandler = new Handler();
63    private final SettingsObserver mSettingsObserver = new SettingsObserver();
64
65    private ZenModeConfigView mConfig;
66    private Switch mSwitch;
67    private Activity mActivity;
68    private MenuItem mSearch;
69
70    @Override
71    public void onCreate(Bundle icicle) {
72        super.onCreate(icicle);
73        mActivity = getActivity();
74        mSwitch = new Switch(mActivity.getActionBar().getThemedContext());
75        final int p = getResources().getDimensionPixelSize(R.dimen.content_margin_left);
76        mSwitch.setPadding(0, 0, p, 0);
77        setHasOptionsMenu(true);
78    }
79
80    @Override
81    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
82        super.onCreateOptionsMenu(menu, inflater);
83        mSearch = menu.findItem(R.id.search);
84        if (mSearch != null) mSearch.setVisible(false);
85    }
86
87    @Override
88    public void onResume() {
89        super.onResume();
90        updateState();
91        mSettingsObserver.register();
92        mActivity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
93                ActionBar.DISPLAY_SHOW_CUSTOM);
94        mActivity.getActionBar().setCustomView(mSwitch, new ActionBar.LayoutParams(
95                ActionBar.LayoutParams.WRAP_CONTENT,
96                ActionBar.LayoutParams.WRAP_CONTENT,
97                Gravity.CENTER_VERTICAL | Gravity.END));
98        if (mSearch != null) mSearch.setVisible(false);
99    }
100
101    @Override
102    public void onPause() {
103        super.onPause();
104        mSettingsObserver.unregister();
105        mActivity.getActionBar().setDisplayOptions(0, ActionBar.DISPLAY_SHOW_CUSTOM);
106        if (mSearch != null) mSearch.setVisible(true);
107    }
108
109    private final class SettingsObserver extends ContentObserver {
110        private final Uri ZEN_MODE_URI = Global.getUriFor(Global.ZEN_MODE);
111
112        public SettingsObserver() {
113            super(mHandler);
114        }
115
116        public void register() {
117            getContentResolver().registerContentObserver(ZEN_MODE_URI, false, this);
118        }
119
120        public void unregister() {
121            getContentResolver().unregisterContentObserver(this);
122        }
123
124        @Override
125        public void onChange(boolean selfChange, Uri uri) {
126            super.onChange(selfChange, uri);
127            if (ZEN_MODE_URI.equals(uri)) {
128                updateState();
129            }
130        }
131    };
132
133    private void updateState() {
134        mSwitch.setOnCheckedChangeListener(null);
135        final boolean zenMode = Global.getInt(getContentResolver(),
136                Global.ZEN_MODE, Global.ZEN_MODE_OFF) != Global.ZEN_MODE_OFF;
137        mSwitch.setChecked(zenMode);
138        mSwitch.setOnCheckedChangeListener(mSwitchListener);
139    }
140
141    @Override
142    public View onCreateView(LayoutInflater inflater, ViewGroup container,
143            Bundle savedInstanceState) {
144        final Context context = getActivity();
145        final ScrollView sv = new ScrollView(context);
146        sv.setVerticalScrollBarEnabled(false);
147        sv.setHorizontalScrollBarEnabled(false);
148        mConfig = new ZenModeConfigView(context);
149        sv.addView(mConfig);
150        return sv;
151    }
152
153    @Override
154    public void onDestroyView() {
155        super.onDestroyView();
156        mConfig.resetBackground();
157    }
158
159    private final OnCheckedChangeListener mSwitchListener = new OnCheckedChangeListener() {
160        @Override
161        public void onCheckedChanged(CompoundButton buttonView, final boolean isChecked) {
162            AsyncTask.execute(new Runnable() {
163                @Override
164                public void run() {
165                    final int v = isChecked ? Global.ZEN_MODE_ON : Global.ZEN_MODE_OFF;
166                    Global.putInt(getContentResolver(), Global.ZEN_MODE, v);
167                }
168            });
169        }
170    };
171
172    public static final class ZenModeConfigView extends LinearLayout {
173        private static final Typeface LIGHT =
174                Typeface.create("sans-serif-light", Typeface.NORMAL);
175        private static final int BG_COLOR = 0xffe7e8e9;
176        private final Context mContext;
177
178        private Drawable mOldBackground;
179
180        public ZenModeConfigView(Context context) {
181            super(context);
182            mContext = context;
183            setOrientation(VERTICAL);
184
185            int p = getResources().getDimensionPixelSize(R.dimen.content_margin_left);
186            TextView tv = addHeader("When on");
187            tv.setPadding(0, p / 2, 0, p / 4);
188            addBuckets();
189            tv = addHeader("Automatically turn on");
190            tv.setPadding(0, p / 2, 0, p / 4);
191            addTriggers();
192        }
193
194        @Override
195        protected void onAttachedToWindow() {
196            super.onAttachedToWindow();
197            mOldBackground = getParentView().getBackground();
198            if (DEBUG) Log.d(TAG, "onAttachedToWindow mOldBackground=" + mOldBackground);
199            getParentView().setBackgroundColor(BG_COLOR);
200        }
201
202        public void resetBackground() {
203            if (DEBUG) Log.d(TAG, "resetBackground");
204            getParentView().setBackground(mOldBackground);
205        }
206
207        private View getParentView() {
208            return (View)getParent().getParent();
209        }
210
211        private TextView addHeader(String text) {
212            TextView tv = new TextView(mContext);
213            tv.setTypeface(LIGHT);
214            tv.setTextColor(0x7f000000);
215            tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.5f);
216            tv.setText(text);
217            addView(tv);
218            return tv;
219        }
220
221        private void addTriggers() {
222            addView(new TriggerView("Never"));
223        }
224
225        private void addBuckets() {
226            LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
227                    LayoutParams.WRAP_CONTENT);
228            BucketView callView = new BucketView("Phone calls", 0,
229                    "Block all", "Block all except...", "Allow all");
230            addView(callView, lp);
231            lp.topMargin = 4;
232            BucketView msgView = new BucketView("Texts, SMS, & other calls", 0,
233                    "Block all", "Block all except...", "Allow all");
234            addView(msgView, lp);
235            BucketView alarmView = new BucketView("Alarms & timers", 2,
236                    "Block all", "Block all except...", "Allow all");
237            addView(alarmView, lp);
238            BucketView otherView = new BucketView("Other interruptions", 0,
239                    "Block all", "Block all except...", "Allow all");
240            addView(otherView, lp);
241        }
242
243        private class BucketView extends RelativeLayout {
244            public BucketView(String category, int defaultValue, String... values) {
245                super(ZenModeConfigView.this.mContext);
246
247                setBackgroundColor(0xffffffff);
248                final int p = getResources().getDimensionPixelSize(R.dimen.content_margin_left);
249                final int lm = p * 3 / 4;
250                TextView title = new TextView(mContext);
251                title.setId(android.R.id.title);
252                title.setTextColor(0xff000000);
253                title.setTypeface(LIGHT);
254                title.setText(category);
255                title.setTextSize(TypedValue.COMPLEX_UNIT_PX, title.getTextSize() * 1.5f);
256                LayoutParams lp =
257                        new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
258                lp.topMargin = p / 2;
259                lp.leftMargin = lm;
260                addView(title, lp);
261
262                TextView subtitle = new TextView(mContext);
263                subtitle.setTextColor(0xff000000);
264                subtitle.setTypeface(LIGHT);
265                subtitle.setText(values[defaultValue]);
266                lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
267                lp.addRule(BELOW, title.getId());
268                lp.leftMargin = lm;
269                lp.bottomMargin = p / 2;
270                addView(subtitle, lp);
271            }
272        }
273
274        private class TriggerView extends RelativeLayout {
275            public TriggerView(String text) {
276                super(ZenModeConfigView.this.mContext);
277
278                setBackgroundColor(0xffffffff);
279                final int p = getResources().getDimensionPixelSize(R.dimen.content_margin_left);
280
281                final TextView tv = new TextView(mContext);
282                tv.setText(text);
283                tv.setTypeface(LIGHT);
284                tv.setTextColor(0xff000000);
285                tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.5f);
286                LayoutParams lp =
287                        new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
288                lp.addRule(CENTER_VERTICAL);
289                lp.bottomMargin = p / 2;
290                lp.topMargin = p / 2;
291                lp.leftMargin = p * 3 / 4;
292                addView(tv, lp);
293            }
294        }
295    }
296
297    // Enable indexing of searchable data
298    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
299        new BaseSearchIndexProvider() {
300            @Override
301            public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
302                final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
303                final Resources res = context.getResources();
304
305                SearchIndexableRaw data = new SearchIndexableRaw(context);
306                data.title = res.getString(R.string.zen_mode_settings_title);
307                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
308                result.add(data);
309
310                data = new SearchIndexableRaw(context);
311                data.title = "When on";
312                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
313                result.add(data);
314
315                data = new SearchIndexableRaw(context);
316                data.title = "Calls";
317                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
318                result.add(data);
319
320                data = new SearchIndexableRaw(context);
321                data.title = "Text & SMS Messages";
322                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
323                result.add(data);
324
325                data = new SearchIndexableRaw(context);
326                data.title = "Alarms & Timers";
327                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
328                result.add(data);
329
330                data = new SearchIndexableRaw(context);
331                data.title = "Other Interruptions";
332                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
333                result.add(data);
334
335                data = new SearchIndexableRaw(context);
336                data.title = "Automatically turn on";
337                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
338                result.add(data);
339
340                data = new SearchIndexableRaw(context);
341                data.title = "While driving";
342                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
343                result.add(data);
344
345                data = new SearchIndexableRaw(context);
346                data.title = "While in meetings";
347                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
348                result.add(data);
349
350                data = new SearchIndexableRaw(context);
351                data.title = "During a set time period";
352                data.screenTitle = res.getString(R.string.zen_mode_settings_title);
353                result.add(data);
354
355                return result;
356            }
357        };
358
359}
360