ZenModePanel.java revision 8600534df66c2ff5846ed230b50c56229322d48a
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.systemui.volume; 18 19import android.content.Context; 20import android.content.Intent; 21import android.net.Uri; 22import android.os.Handler; 23import android.os.Looper; 24import android.os.Message; 25import android.provider.Settings; 26import android.service.notification.Condition; 27import android.util.AttributeSet; 28import android.view.ContextThemeWrapper; 29import android.view.LayoutInflater; 30import android.view.View; 31import android.widget.CompoundButton; 32import android.widget.CompoundButton.OnCheckedChangeListener; 33import android.widget.ImageView; 34import android.widget.LinearLayout; 35import android.widget.RadioButton; 36import android.widget.TextView; 37 38import com.android.systemui.R; 39import com.android.systemui.statusbar.policy.ZenModeController; 40 41import java.util.Arrays; 42import java.util.HashSet; 43 44public class ZenModePanel extends LinearLayout { 45 private static final int[] MINUTES = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 }; 46 public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS); 47 48 private final LayoutInflater mInflater; 49 private final HashSet<RadioButton> mRadioButtons = new HashSet<RadioButton>(); 50 private final H mHandler = new H(); 51 private LinearLayout mConditions; 52 private int mMinutesIndex = Arrays.binarySearch(MINUTES, 60); // default to one hour 53 private Callback mCallback; 54 private ZenModeController mController; 55 private boolean mRequestingConditions; 56 57 public ZenModePanel(Context context, AttributeSet attrs) { 58 super(context, attrs); 59 mInflater = LayoutInflater.from(new ContextThemeWrapper(context, R.style.QSWhiteTheme)); 60 } 61 62 @Override 63 protected void onFinishInflate() { 64 super.onFinishInflate(); 65 mConditions = (LinearLayout) findViewById(android.R.id.content); 66 findViewById(android.R.id.button2).setOnClickListener(new View.OnClickListener() { 67 @Override 68 public void onClick(View v) { 69 fireMoreSettings(); 70 } 71 }); 72 } 73 74 @Override 75 public void setVisibility(int visibility) { 76 super.setVisibility(visibility); 77 setRequestingConditions(visibility == VISIBLE); 78 } 79 80 /** Start or stop requesting relevant zen mode exit conditions */ 81 private void setRequestingConditions(boolean requesting) { 82 if (mRequestingConditions == requesting) return; 83 mRequestingConditions = requesting; 84 if (mRequestingConditions) { 85 mController.addCallback(mZenCallback); 86 } else { 87 mController.removeCallback(mZenCallback); 88 } 89 mController.requestConditions(mRequestingConditions); 90 } 91 92 public void init(ZenModeController controller) { 93 mController = controller; 94 mConditions.removeAllViews(); 95 bind(updateTimeCondition(), mConditions.getChildAt(0)); 96 handleUpdateConditions(new Condition[0]); 97 } 98 99 public void setCallback(Callback callback) { 100 mCallback = callback; 101 } 102 103 private Condition updateTimeCondition() { 104 final int minutes = MINUTES[mMinutesIndex]; 105 final long millis = System.currentTimeMillis() + minutes * 60 * 1000; 106 final Uri id = new Uri.Builder().scheme(Condition.SCHEME).authority("android") 107 .appendPath("countdown").appendPath(Long.toString(millis)).build(); 108 final int num = minutes < 60 ? minutes : minutes / 60; 109 final int resId = minutes < 60 110 ? R.plurals.zen_mode_duration_minutes 111 : R.plurals.zen_mode_duration_hours; 112 final String caption = mContext.getResources().getQuantityString(resId, num, num); 113 return new Condition(id, caption, "", "", 0, Condition.STATE_TRUE, 114 Condition.FLAG_RELEVANT_NOW); 115 } 116 117 private void handleUpdateConditions(Condition[] conditions) { 118 final int newCount = conditions == null ? 0 : conditions.length; 119 for (int i = mConditions.getChildCount() - 1; i > newCount; i--) { 120 mConditions.removeViewAt(i); 121 } 122 for (int i = 0; i < newCount; i++) { 123 bind(conditions[i], mConditions.getChildAt(i + 1)); 124 } 125 bind(null, mConditions.getChildAt(newCount + 1)); 126 } 127 128 private void editTimeCondition(int delta) { 129 final int i = mMinutesIndex + delta; 130 if (i < 0 || i >= MINUTES.length) return; 131 mMinutesIndex = i; 132 final Condition c = updateTimeCondition(); 133 bind(c, mConditions.getChildAt(0)); 134 } 135 136 private void bind(final Condition condition, View convertView) { 137 final boolean enabled = condition == null || condition.state == Condition.STATE_TRUE; 138 final View row; 139 if (convertView == null) { 140 row = mInflater.inflate(R.layout.zen_mode_condition, this, false); 141 mConditions.addView(row); 142 } else { 143 row = convertView; 144 } 145 final int position = mConditions.indexOfChild(row); 146 final RadioButton rb = (RadioButton) row.findViewById(android.R.id.checkbox); 147 mRadioButtons.add(rb); 148 rb.setEnabled(enabled); 149 rb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 150 @Override 151 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 152 if (isChecked) { 153 for (RadioButton otherButton : mRadioButtons) { 154 if (otherButton == rb) continue; 155 otherButton.setChecked(false); 156 } 157 mController.select(condition); 158 fireInteraction(); 159 } 160 } 161 }); 162 final TextView title = (TextView) row.findViewById(android.R.id.title); 163 if (condition == null) { 164 title.setText(R.string.zen_mode_forever); 165 } else { 166 title.setText(condition.summary); 167 } 168 title.setEnabled(enabled); 169 title.setAlpha(enabled ? 1 : .5f); 170 final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1); 171 button1.setOnClickListener(new OnClickListener() { 172 @Override 173 public void onClick(View v) { 174 rb.setChecked(true); 175 editTimeCondition(-1); 176 fireInteraction(); 177 } 178 }); 179 180 final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2); 181 button2.setOnClickListener(new OnClickListener() { 182 @Override 183 public void onClick(View v) { 184 rb.setChecked(true); 185 editTimeCondition(1); 186 fireInteraction(); 187 } 188 }); 189 title.setOnClickListener(new OnClickListener() { 190 @Override 191 public void onClick(View v) { 192 rb.setChecked(true); 193 fireInteraction(); 194 } 195 }); 196 if (position == 0) { 197 button1.setEnabled(mMinutesIndex > 0); 198 button2.setEnabled(mMinutesIndex < MINUTES.length - 1); 199 button1.setImageAlpha(button1.isEnabled() ? 0xff : 0x7f); 200 button2.setImageAlpha(button2.isEnabled() ? 0xff : 0x7f); 201 } else { 202 button1.setVisibility(View.GONE); 203 button2.setVisibility(View.GONE); 204 } 205 if (position == 0 && mConditions.getChildCount() == 1) { 206 rb.setChecked(true); 207 } 208 } 209 210 private void fireMoreSettings() { 211 if (mCallback != null) { 212 mCallback.onMoreSettings(); 213 } 214 } 215 216 private void fireInteraction() { 217 if (mCallback != null) { 218 mCallback.onInteraction(); 219 } 220 } 221 222 private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() { 223 @Override 224 public void onConditionsChanged(Condition[] conditions) { 225 mHandler.obtainMessage(H.UPDATE_CONDITIONS, conditions).sendToTarget(); 226 } 227 }; 228 229 private final class H extends Handler { 230 private static final int UPDATE_CONDITIONS = 1; 231 232 private H() { 233 super(Looper.getMainLooper()); 234 } 235 236 @Override 237 public void handleMessage(Message msg) { 238 if (msg.what == UPDATE_CONDITIONS) { 239 handleUpdateConditions((Condition[])msg.obj); 240 } 241 } 242 } 243 244 public interface Callback { 245 void onMoreSettings(); 246 void onInteraction(); 247 } 248} 249