Zen mode configuration panel. (packages/apps/Settings)

Read-only version of the configuration screen for
Limited Interruptions.  Defaults to the logic implemented
for this mode, namely block notifications except for
Calls & Alarms.

This settings panel will serve as a target for the
configure affordance in SystemUI.

Change-Id: I33fd1e11ab76dbb7044bb94cb096cd892945947d
This commit is contained in:
John Spurlock
2014-02-27 18:01:20 -05:00
parent 0f9ab45376
commit 7243806345
11 changed files with 385 additions and 4 deletions

View File

@@ -561,6 +561,23 @@
android:resource="@id/sound_settings" />
</activity-alias>
<activity android:name="Settings$ZenModeSettingsActivity"
android:label="@string/zen_mode_settings_title"
android:exported="true"
android:taskAffinity=""
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.ZEN_MODE_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.android.settings.SHORTCUT" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.ZenModeSettings" />
<meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
android:resource="@id/sound_settings" />
</activity>
<activity android:name="Settings$DisplaySettingsActivity"
android:label="@string/display_settings"
android:taskAffinity=""

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/configure_zen_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dip"
android:visibility="gone"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_bt_config"
android:contentDescription="@string/configure_zen_mode_description" />

View File

@@ -5014,4 +5014,8 @@
<string name="summary_zen_mode" translatable="false">%1$s</string>
<!-- [CHAR LIMIT=40] Sound settings screen, title of dialog for picking zen mode -->
<string name="dialog_title_zen_mode">Zen mode</string>
<!-- [CHAR LIMIT=30] Sound settings screen, description for configuring zen mode -->
<string name="configure_zen_mode_description">Configure Zen mode</string>
<!-- [CHAR LIMIT=30] Zen mode settings screen, activity title -->
<string name="zen_mode_settings_title">Limited Interruptions</string>
</resources>

View File

@@ -85,6 +85,7 @@ public class Settings extends SettingsActivity {
public static class PaymentSettingsActivity extends SettingsActivity { /* empty */ }
public static class PrintSettingsActivity extends SettingsActivity { /* empty */ }
public static class PrintJobSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenModeSettingsActivity extends SettingsActivity { /* empty */ }
public static class TopLevelSettings extends SettingsActivity { /* empty */ }
}

View File

@@ -278,7 +278,8 @@ public class SettingsActivity extends Activity
TrustedCredentialsSettings.class.getName(),
PaymentSettings.class.getName(),
KeyboardLayoutPickerFragment.class.getName(),
DashboardSummary.class.getName()
DashboardSummary.class.getName(),
ZenModeSettings.class.getName()
};
private SharedPreferences mDevelopmentPreferences;

View File

@@ -25,18 +25,28 @@ import android.preference.Preference;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
public class ZenModeListPreference extends ListPreference {
private static final String TAG = "ZenModeListPreference";
private static final boolean DEBUG = false;
private final Context mContext;
private final Handler mHandler = new Handler();
private final ContentResolver mResolver;
private ImageView mConfigure;
private int mMode;
public ZenModeListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
if (DEBUG) Log.d(TAG, "new ZenModeListPreference()");
mContext = context;
mResolver = context.getContentResolver();
setWidgetLayoutResource(R.layout.preference_zen_mode);
}
public void init() {
@@ -55,10 +65,38 @@ public class ZenModeListPreference extends ListPreference {
false, new SettingsObserver());
}
@Override
protected void onBindView(View view) {
if (DEBUG) Log.d(TAG, "onBindView");
super.onBindView(view);
mConfigure = (ImageView)view.findViewById(R.id.configure_zen_mode);
updateConfigureVisibility();
mConfigure.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if (mMode != Settings.Global.ZEN_MODE_LIMITED) return;
if (mContext instanceof SettingsActivity) {
SettingsActivity sa = (SettingsActivity)mContext;
sa.startPreferencePanel(ZenModeSettings.class.getName(),
null, R.string.zen_mode_settings_title, null, null, 0);
}
}
});
}
private void updateConfigureVisibility() {
if (mConfigure != null) {
final boolean limited = mMode == Settings.Global.ZEN_MODE_LIMITED;
mConfigure.setVisibility(limited ? View.VISIBLE : View.GONE);
}
}
private void loadZenModeSetting(String reason) {
if (DEBUG) Log.d(TAG, "loadZenModeSetting " + reason);
setValue(Integer.toString(Settings.Global.getInt(mResolver,
Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF)));
mMode = Settings.Global.getInt(mResolver,
Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
setValue(Integer.toString(mMode));
updateConfigureVisibility();
}
private boolean saveZenModeSetting(String value) {

View File

@@ -0,0 +1,294 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class ZenModeSettings extends SettingsPreferenceFragment {
private static final String TAG = "ZenModeSettings";
private static final boolean DEBUG = false;
private ZenModeConfigView mConfig;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final Context context = getActivity();
final ScrollView sv = new ScrollView(context);
sv.setVerticalScrollBarEnabled(false);
sv.setHorizontalScrollBarEnabled(false);
mConfig = new ZenModeConfigView(context);
sv.addView(mConfig);
return sv;
}
@Override
public void onDestroyView() {
super.onDestroyView();
mConfig.resetBackground();
}
public static final class ZenModeConfigView extends LinearLayout {
private static final Typeface LIGHT =
Typeface.create("sans-serif-light", Typeface.NORMAL);
private static final int BG_COLOR = 0xffe7e8e9;
private final Context mContext;
private Drawable mOldBackground;
private Toast mToast;
public ZenModeConfigView(Context context) {
super(context);
mContext = context;
setOrientation(VERTICAL);
int p = getResources().getDimensionPixelSize(R.dimen.content_margin_left);
TextView tv = addHeader("When on");
tv.setPadding(0, p / 2, 0, p / 4);
addBuckets();
tv = addHeader("Automatically turn on");
tv.setPadding(0, p / 2, 0, p / 4);
addTriggers();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mOldBackground = getParentView().getBackground();
if (DEBUG) Log.d(TAG, "onAttachedToWindow mOldBackground=" + mOldBackground);
getParentView().setBackgroundColor(BG_COLOR);
}
public void resetBackground() {
if (DEBUG) Log.d(TAG, "resetBackground");
getParentView().setBackground(mOldBackground);
}
private View getParentView() {
return (View)getParent().getParent();
}
private TextView addHeader(String text) {
TextView tv = new TextView(mContext);
tv.setTypeface(LIGHT);
tv.setTextColor(0x7f000000);
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.5f);
tv.setText(text);
addView(tv);
return tv;
}
private void addTriggers() {
addView(new TriggerView("While driving"));
addView(new TriggerView("While in meetings"));
addView(new TriggerView("During a set time period"));
}
private void addBuckets() {
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
BucketView callView = new BucketView(android.R.drawable.ic_menu_call, "Calls", 2,
"Block all", "Starred contacts only", "Allow all");
addView(callView, lp);
lp.topMargin = 4;
BucketView msgView = new BucketView(android.R.drawable.ic_menu_myplaces,
"Text & SMS Messages", 0,
"Block all", "Starred contacts only", "Allow all");
addView(msgView, lp);
BucketView alarmView = new BucketView(android.R.drawable.ic_menu_agenda,
"Alarms & Timers", 1,
"Block all", "Allow all");
addView(alarmView, lp);
BucketView otherView = new BucketView(android.R.drawable.ic_menu_info_details,
"Other Interruptions", 0,
"Block all", "Block all except...");
addView(otherView, lp);
}
private void notImplemented() {
if (mToast != null) mToast.cancel();
mToast = Toast.makeText(mContext, "Not implemented", Toast.LENGTH_SHORT);
mToast.show();
}
private class BucketView extends RelativeLayout {
private final BucketSpinner mSpinner;
public BucketView(int icon, String category, int defaultValue, String... values) {
super(ZenModeConfigView.this.mContext);
setBackgroundColor(0xffffffff);
final int p = getResources().getDimensionPixelSize(R.dimen.content_margin_left);
final ImageView iv = new ImageView(mContext);
iv.setId(android.R.id.icon);
iv.setImageResource(icon);
iv.setAlpha(.5f);
final int size = mContext.getResources()
.getDimensionPixelSize(R.dimen.app_icon_size);
LayoutParams lp = new LayoutParams(size, size);
lp.addRule(CENTER_VERTICAL);
lp.leftMargin = 16;
lp.rightMargin = 16;
addView(iv, lp);
TextView tv = new TextView(mContext);
tv.setPadding(4, 0, 0, 0);
tv.setId(android.R.id.title);
tv.setTextColor(0xff000000);
tv.setText(category);
tv.setAllCaps(true);
lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RIGHT_OF, iv.getId());
lp.topMargin = p / 2;
addView(tv, lp);
mSpinner = new BucketSpinner(defaultValue, values);
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RIGHT_OF, iv.getId());
lp.addRule(BELOW, tv.getId());
addView(mSpinner, lp);
}
}
private class BucketSpinner extends Spinner {
private final Bitmap mArrow;
public BucketSpinner(int defaultValue, String... values) {
super(ZenModeConfigView.this.mContext);
setGravity(Gravity.LEFT);
mArrow = BitmapFactory.decodeResource(getResources(),
R.drawable.spinner_default_holo_dark_am_no_underline);
setPadding(0, 0, getPaddingRight(), getPaddingBottom());
setBackgroundColor(0x00000000);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, 0) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getDropDownView(position, convertView, parent);
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
final TextView tv = convertView != null ? (TextView) convertView
: new TextView(ZenModeConfigView.this.mContext);
tv.setText(getItem(position));
if (convertView == null) {
tv.setTypeface(LIGHT);
tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
tv.setTextColor(0xff000000);
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.5f);
final int p = (int) tv.getTextSize() / 2;
if (parent instanceof ListView) {
final ListView lv = (ListView)parent;
lv.setDividerHeight(0);
tv.setBackgroundColor(BG_COLOR);
tv.setPadding(p, p, p, p);
} else {
tv.setPadding(0, 0, p, 0);
}
}
return tv;
}
};
adapter.addAll(values);
setAdapter(adapter);
setSelection(defaultValue, true);
}
@Override
protected void onDraw(Canvas canvas) {
final TextView tv = (TextView)getSelectedView();
final int w = (int)tv.getLayout().getLineWidth(0);
final int left = w - mArrow.getWidth() / 4;
final int top = getHeight() - mArrow.getHeight();
canvas.drawBitmap(mArrow, left, top, null);
super.onDraw(canvas);
}
@Override
public void setSelection(int position) {
if (position != getSelectedItemPosition()) {
notImplemented();
}
}
}
private class TriggerView extends RelativeLayout {
public TriggerView(String text) {
super(ZenModeConfigView.this.mContext);
setBackgroundColor(0xffffffff);
final int p = getResources().getDimensionPixelSize(R.dimen.content_margin_left);
final int p2 = p / 4;
setPadding(p2, p2, p2, p2);
final CheckBox cb = new CheckBox(mContext);
cb.setId(android.R.id.checkbox);
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
cb.setChecked(false);
notImplemented();
}
}
});
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
lp.addRule(ALIGN_PARENT_RIGHT);
addView(cb, lp);
final TextView tv = new TextView(mContext);
tv.setText(text);
tv.setTypeface(LIGHT);
tv.setTextColor(0xff000000);
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.5f);
final int p3 = p / 2;
tv.setPadding(p3, 0, p3, 0);
lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
lp.addRule(LEFT_OF, cb.getId());
lp.addRule(CENTER_VERTICAL);
addView(tv, lp);
}
}
}
}