ZenModePanel.java revision 89f060a1e0fa48c497855d061b5c9ec44bb576c8
18600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock/*
28600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock * Copyright (C) 2014 The Android Open Source Project
38600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock *
48600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License");
58600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock * you may not use this file except in compliance with the License.
68600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock * You may obtain a copy of the License at
78600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock *
88600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock *      http://www.apache.org/licenses/LICENSE-2.0
98600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock *
108600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock * Unless required by applicable law or agreed to in writing, software
118600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS,
128600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock * See the License for the specific language governing permissions and
148600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock * limitations under the License.
158600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock */
168600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
178600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockpackage com.android.systemui.volume;
188600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
19ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlockimport android.animation.Animator;
20ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlockimport android.animation.AnimatorListenerAdapter;
218600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.content.Context;
228600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.content.Intent;
23856edebad73560e9b1cce021a7de9a0470d07176John Spurlockimport android.content.SharedPreferences;
24856edebad73560e9b1cce021a7de9a0470d07176John Spurlockimport android.content.SharedPreferences.OnSharedPreferenceChangeListener;
258600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.net.Uri;
268600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.os.Handler;
278600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.os.Looper;
288600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.os.Message;
298600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.provider.Settings;
30ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlockimport android.provider.Settings.Global;
318600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.service.notification.Condition;
32856edebad73560e9b1cce021a7de9a0470d07176John Spurlockimport android.service.notification.ZenModeConfig;
3389f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlockimport android.text.format.DateFormat;
3489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlockimport android.text.format.Time;
358600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.util.AttributeSet;
36856edebad73560e9b1cce021a7de9a0470d07176John Spurlockimport android.util.Log;
378600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.view.LayoutInflater;
388600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.view.View;
39ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlockimport android.view.animation.AnimationUtils;
40ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlockimport android.view.animation.Interpolator;
418600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.CompoundButton;
428600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.CompoundButton.OnCheckedChangeListener;
438600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.ImageView;
448600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.LinearLayout;
458600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.RadioButton;
468600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.TextView;
478600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
488600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport com.android.systemui.R;
498600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport com.android.systemui.statusbar.policy.ZenModeController;
508600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
5189f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlockimport java.text.SimpleDateFormat;
528600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport java.util.Arrays;
5389f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlockimport java.util.Date;
5489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlockimport java.util.Locale;
55856edebad73560e9b1cce021a7de9a0470d07176John Spurlockimport java.util.Objects;
568600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
578600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockpublic class ZenModePanel extends LinearLayout {
58ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private static final String TAG = "ZenModePanel";
59ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
60856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
6150806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock    private static final int SECONDS_MS = 1000;
6250806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock    private static final int MINUTES_MS = 60 * SECONDS_MS;
6350806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock
64ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private static final int[] MINUTE_BUCKETS = DEBUG
6550806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock            ? new int[] { 0, 1, 2, 5, 15, 30, 45, 60, 120, 180, 240, 480 }
66ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            : new int[] { 15, 30, 45, 60, 120, 180, 240, 480 };
67856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
68856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private static final int MAX_BUCKET_MINUTES = MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
69856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
70ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private static final int FOREVER_CONDITION_INDEX = 0;
71ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private static final int TIME_CONDITION_INDEX = 1;
72ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private static final int FIRST_CONDITION_INDEX = 2;
73ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private static final float SILENT_HINT_PULSE_SCALE = 1.1f;
7450806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock    private static final int ZERO_VALUE_MS = 20 * SECONDS_MS;
75856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
768600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
778600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
787f1df5e98578f8532a5e009009e7c1f82ed5885cJohn Spurlock    private final Context mContext;
798600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private final LayoutInflater mInflater;
808600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private final H mHandler = new H();
81856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private final Favorites mFavorites;
82ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private final Interpolator mFastOutSlowInInterpolator;
8389f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    private final int mTextColor;
8489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    private final int mAccentColor;
85856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
86856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private char mLogTag = '?';
87856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private String mTag;
88ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
89ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private SegmentedButtons mZenButtons;
90ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private View mZenSubhead;
91ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private TextView mZenSubheadCollapsed;
92ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private TextView mZenSubheadExpanded;
937f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock    private View mMoreSettings;
94ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private LinearLayout mZenConditions;
9589f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    private TextView mAlarmWarning;
96ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
978600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private Callback mCallback;
988600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private ZenModeController mController;
998600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private boolean mRequestingConditions;
100856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private Uri mExitConditionId;
101856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private int mBucketIndex = -1;
102ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private boolean mExpanded;
103ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private int mAttachedZen;
104ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private String mExitConditionText;
10589f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    private long mNextAlarm;
1068600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
1078600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    public ZenModePanel(Context context, AttributeSet attrs) {
1088600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        super(context, attrs);
1097f1df5e98578f8532a5e009009e7c1f82ed5885cJohn Spurlock        mContext = context;
110856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        mFavorites = new Favorites();
111f7d22132c2c9b83134b05aaed63a89f61c639fd9John Spurlock        mInflater = LayoutInflater.from(mContext.getApplicationContext());
112ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(mContext,
113ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                android.R.interpolator.fast_out_slow_in);
11489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        mTextColor = mContext.getResources().getColor(R.color.qs_text);
11589f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        mAccentColor = mContext.getResources().getColor(R.color.system_accent_color);
116856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        updateTag();
117856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (DEBUG) Log.d(mTag, "new ZenModePanel");
118856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
119856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
120856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private void updateTag() {
121ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mTag = TAG + "/" + mLogTag + "/" + Integer.toHexString(System.identityHashCode(this));
1228600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
1238600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
1248600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    @Override
1258600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    protected void onFinishInflate() {
1268600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        super.onFinishInflate();
127ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
128ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons);
129ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenButtons.addButton(R.string.interruption_level_none, Global.ZEN_MODE_NO_INTERRUPTIONS);
130ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenButtons.addButton(R.string.interruption_level_priority,
131ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
132ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenButtons.addButton(R.string.interruption_level_all, Global.ZEN_MODE_OFF);
133ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenButtons.setCallback(mZenButtonsCallback);
134ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
135ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenSubhead = findViewById(R.id.zen_subhead);
136ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
137ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenSubheadCollapsed = (TextView) findViewById(R.id.zen_subhead_collapsed);
138ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenSubheadCollapsed.setOnClickListener(new View.OnClickListener() {
139ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            @Override
140ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            public void onClick(View v) {
141ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                setExpanded(true);
142ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                fireInteraction();
143ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            }
144ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        });
145ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
146ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenSubheadExpanded = (TextView) findViewById(R.id.zen_subhead_expanded);
147ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
148ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mMoreSettings = findViewById(R.id.zen_more_settings);
1497f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock        mMoreSettings.setOnClickListener(new View.OnClickListener() {
1508600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            @Override
1518600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            public void onClick(View v) {
1528600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock                fireMoreSettings();
153ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                fireInteraction();
1548600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            }
1558600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        });
156ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
157ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions);
15889f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        mAlarmWarning = (TextView) findViewById(R.id.zen_alarm_warning);
1598600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
1608600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
1618600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    @Override
162856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    protected void onAttachedToWindow() {
163856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        super.onAttachedToWindow();
164856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (DEBUG) Log.d(mTag, "onAttachedToWindow");
165ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mAttachedZen = getSelectedZen(-1);
166ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        refreshExitConditionText();
16789f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        refreshNextAlarm();
16850806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock        updateWidgets();
169856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
170856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
171856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    @Override
172856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    protected void onDetachedFromWindow() {
173856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        super.onDetachedFromWindow();
174856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (DEBUG) Log.d(mTag, "onDetachedFromWindow");
175ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mAttachedZen = -1;
176ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        setExpanded(false);
177856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
178856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
179ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private void setExpanded(boolean expanded) {
180ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (expanded == mExpanded) return;
181ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mExpanded = expanded;
182ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        updateWidgets();
183ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        setRequestingConditions(mExpanded);
184ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        fireExpanded();
1858600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
1868600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
1878600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    /** Start or stop requesting relevant zen mode exit conditions */
1888600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private void setRequestingConditions(boolean requesting) {
1898600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        if (mRequestingConditions == requesting) return;
190856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (DEBUG) Log.d(mTag, "setRequestingConditions " + requesting);
1918600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        mRequestingConditions = requesting;
192856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (mController != null) {
193856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            mController.requestConditions(mRequestingConditions);
194856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
1958600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        if (mRequestingConditions) {
196856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            Condition timeCondition = parseExistingTimeCondition(mExitConditionId);
197856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            if (timeCondition != null) {
198856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                mBucketIndex = -1;
199856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            } else {
200856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                mBucketIndex = DEFAULT_BUCKET_INDEX;
201856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                timeCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]);
202856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            }
203856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            if (DEBUG) Log.d(mTag, "Initial bucket index: " + mBucketIndex);
204ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            handleUpdateConditions(new Condition[0]);  // ensures forever exists
205ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            bind(timeCondition, mZenConditions.getChildAt(TIME_CONDITION_INDEX));
206ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            checkForDefault();
2078600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        } else {
208ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mZenConditions.removeAllViews();
2098600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
2108600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
2118600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
212ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    public void init(ZenModeController controller, char logTag) {
2138600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        mController = controller;
214856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        mLogTag = logTag;
215856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        updateTag();
216ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        setExitConditionId(mController.getExitConditionId());
217ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        refreshExitConditionText();
218ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mAttachedZen = getSelectedZen(-1);
219ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        handleUpdateZen(mController.getZen());
220856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (DEBUG) Log.d(mTag, "init mExitConditionId=" + mExitConditionId);
221ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenConditions.removeAllViews();
222856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        mController.addCallback(mZenCallback);
223ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    }
224ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
225ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private void setExitConditionId(Uri exitConditionId) {
226ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (Objects.equals(mExitConditionId, exitConditionId)) return;
227ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mExitConditionId = exitConditionId;
228ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        refreshExitConditionText();
22989f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        updateWidgets();
230ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    }
231ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
232ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private void refreshExitConditionText() {
233bc5858f4893558ae6fee24c14489be56e6c3f528John Spurlock        final String forever = mContext.getString(R.string.zen_mode_forever);
234ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (mExitConditionId == null) {
235bc5858f4893558ae6fee24c14489be56e6c3f528John Spurlock            mExitConditionText = forever;
236ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        } else if (ZenModeConfig.isValidCountdownConditionId(mExitConditionId)) {
237bc5858f4893558ae6fee24c14489be56e6c3f528John Spurlock            final Condition condition = parseExistingTimeCondition(mExitConditionId);
238bc5858f4893558ae6fee24c14489be56e6c3f528John Spurlock            mExitConditionText = condition != null ? condition.summary : forever;
239ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        } else {
240ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mExitConditionText = "(until condition ends)";  // TODO persist current description
241856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
2428600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
2438600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
2448600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    public void setCallback(Callback callback) {
2458600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        mCallback = callback;
2468600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
2478600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
248ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    public void showSilentHint() {
249ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (DEBUG) Log.d(mTag, "showSilentHint");
250ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (mZenButtons == null || mZenButtons.getChildCount() == 0) return;
251ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        final View noneButton = mZenButtons.getChildAt(0);
252ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (noneButton.getScaleX() != 1) return;  // already running
253ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        noneButton.animate().cancel();
254ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        noneButton.animate().scaleX(SILENT_HINT_PULSE_SCALE).scaleY(SILENT_HINT_PULSE_SCALE)
255ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                .setInterpolator(mFastOutSlowInInterpolator)
256ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                .setListener(new AnimatorListenerAdapter() {
257ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                    @Override
258ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                    public void onAnimationEnd(Animator animation) {
259ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                        noneButton.animate().scaleX(1).scaleY(1).setListener(null);
260ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                    }
261ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                });
262ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    }
263ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
264ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private void handleUpdateZen(int zen) {
265ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (mAttachedZen != -1 && mAttachedZen != zen) {
266ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            setExpanded(zen != Global.ZEN_MODE_OFF);
267ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mAttachedZen = zen;
268ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        }
269ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenButtons.setSelectedValue(zen);
270ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        updateWidgets();
271ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    }
272ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
273ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private int getSelectedZen(int defValue) {
274ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        final Object zen = mZenButtons.getSelectedValue();
275ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        return zen != null ? (Integer) zen : defValue;
276ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    }
277ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
278ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private void updateWidgets() {
279ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        final int zen = getSelectedZen(Global.ZEN_MODE_OFF);
280ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        final boolean zenOff = zen == Global.ZEN_MODE_OFF;
281ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        final boolean zenImportant = zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
282ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
2838263c3e0647e0d9622585f1c196ceb8d2fde695eJohn Spurlock        final boolean foreverSelected = mExitConditionId == null;
28489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        final boolean hasNextAlarm = mNextAlarm != 0;
285ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
2868263c3e0647e0d9622585f1c196ceb8d2fde695eJohn Spurlock        mZenSubhead.setVisibility(!zenOff && (mExpanded || !foreverSelected) ? VISIBLE : GONE);
287ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenSubheadExpanded.setVisibility(mExpanded ? VISIBLE : GONE);
288ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenSubheadCollapsed.setVisibility(!mExpanded ? VISIBLE : GONE);
289ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mMoreSettings.setVisibility(zenImportant && mExpanded ? VISIBLE : GONE);
290ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        mZenConditions.setVisibility(!zenOff && mExpanded ? VISIBLE : GONE);
29189f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        mAlarmWarning.setVisibility(zenNone && mExpanded && hasNextAlarm ? VISIBLE : GONE);
29289f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock
29389f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        if (zenNone && mExpanded && hasNextAlarm) {
29489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            final long exitTime = ZenModeConfig.tryParseCountdownConditionId(mExitConditionId);
29589f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            final long now = System.currentTimeMillis();
29689f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            final boolean alarmToday = time(mNextAlarm).yearDay == time(now).yearDay;
29789f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            final String skeleton = (alarmToday ? "" : "E")
29889f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                    + (DateFormat.is24HourFormat(mContext) ? "Hm" : "hma");
29989f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
30089f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            final String alarm = new SimpleDateFormat(pattern).format(new Date(mNextAlarm));
30189f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            final boolean isWarning = exitTime > 0 && mNextAlarm > now && mNextAlarm < exitTime;
30289f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            if (isWarning) {
30389f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                mAlarmWarning.setText(mContext.getString(R.string.zen_alarm_warning, alarm));
30489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                mAlarmWarning.setTextColor(mAccentColor);
30589f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            } else {
30689f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                mAlarmWarning.setText(mContext.getString(alarmToday
30789f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                        ? R.string.zen_alarm_information_time
30889f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                        : R.string.zen_alarm_information_day_time, alarm));
30989f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                mAlarmWarning.setTextColor(mTextColor);
31089f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            }
31189f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        }
312ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
313ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (zenNone) {
31486d04fdaa1853cf7ff8ec9aba1dd925dd098167eJohn Spurlock            mZenSubheadExpanded.setText(R.string.zen_no_interruptions_with_warning);
315ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mZenSubheadCollapsed.setText(mExitConditionText);
316ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        } else if (zenImportant) {
317ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mZenSubheadExpanded.setText(R.string.zen_important_interruptions);
318ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mZenSubheadCollapsed.setText(mExitConditionText);
319ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        }
320ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    }
321ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
32289f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    private static Time time(long millis) {
32389f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        final Time t = new Time();
32489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        t.set(millis);
32589f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        return t;
32689f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    }
32789f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock
328856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private Condition parseExistingTimeCondition(Uri conditionId) {
329856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
330856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (time == 0) return null;
331856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        final long span = time - System.currentTimeMillis();
332856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (span <= 0 || span > MAX_BUCKET_MINUTES * MINUTES_MS) return null;
333856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        return timeCondition(time, Math.round(span / (float)MINUTES_MS));
334856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
335856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
336856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private Condition newTimeCondition(int minutesFromNow) {
337856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        final long now = System.currentTimeMillis();
33850806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock        final long millis = minutesFromNow == 0 ? ZERO_VALUE_MS : minutesFromNow * MINUTES_MS;
33950806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock        return timeCondition(now + millis, minutesFromNow);
340856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
341856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
342856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private Condition timeCondition(long time, int minutes) {
343856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        final int num = minutes < 60 ? minutes : Math.round(minutes / 60f);
3448600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        final int resId = minutes < 60
3458600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock                ? R.plurals.zen_mode_duration_minutes
3468600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock                : R.plurals.zen_mode_duration_hours;
3478600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        final String caption = mContext.getResources().getQuantityString(resId, num, num);
348856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        final Uri id = ZenModeConfig.toCountdownConditionId(time);
3498600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        return new Condition(id, caption, "", "", 0, Condition.STATE_TRUE,
3508600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock                Condition.FLAG_RELEVANT_NOW);
3518600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
3528600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
35389f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    private void refreshNextAlarm() {
35489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        mNextAlarm = mController.getNextAlarm();
35589f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    }
35689f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock
35789f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    private void handleNextAlarmChanged() {
35889f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        refreshNextAlarm();
35989f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        updateWidgets();
36089f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock    }
36189f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock
3628600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private void handleUpdateConditions(Condition[] conditions) {
3638600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        final int newCount = conditions == null ? 0 : conditions.length;
364ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (DEBUG) Log.d(mTag, "handleUpdateConditions newCount=" + newCount);
365ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        for (int i = mZenConditions.getChildCount(); i >= newCount + FIRST_CONDITION_INDEX; i--) {
366ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mZenConditions.removeViewAt(i);
3678600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
368ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        bind(null, mZenConditions.getChildAt(FOREVER_CONDITION_INDEX));
3698600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        for (int i = 0; i < newCount; i++) {
370ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            bind(conditions[i], mZenConditions.getChildAt(FIRST_CONDITION_INDEX + i));
3718600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
372856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
373856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
374856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private ConditionTag getConditionTagAt(int index) {
375ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        return (ConditionTag) mZenConditions.getChildAt(index).getTag();
376856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
377856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
378856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private void checkForDefault() {
379856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        // are we left without anything selected?  if so, set a default
380ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        for (int i = 0; i < mZenConditions.getChildCount(); i++) {
381856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            if (getConditionTagAt(i).rb.isChecked()) {
382856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                return;
383856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            }
384856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
385856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (DEBUG) Log.d(mTag, "Selecting a default");
386856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        final int favoriteIndex = mFavorites.getMinuteIndex();
387856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (favoriteIndex == -1) {
388ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            getConditionTagAt(FOREVER_CONDITION_INDEX).rb.setChecked(true);
389856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        } else {
390856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            final Condition c = newTimeCondition(MINUTE_BUCKETS[favoriteIndex]);
391856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            mBucketIndex = favoriteIndex;
392ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            bind(c, mZenConditions.getChildAt(TIME_CONDITION_INDEX));
393ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            getConditionTagAt(TIME_CONDITION_INDEX).rb.setChecked(true);
394856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
3958600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
3968600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
397856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private void handleExitConditionChanged(Uri exitCondition) {
398ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        setExitConditionId(exitCondition);
399856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (DEBUG) Log.d(mTag, "handleExitConditionChanged " + mExitConditionId);
400ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        final int N = mZenConditions.getChildCount();
401856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        for (int i = 0; i < N; i++) {
402856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            final ConditionTag tag = getConditionTagAt(i);
403856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            tag.rb.setChecked(Objects.equals(tag.conditionId, exitCondition));
404856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
4058600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
4068600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
4078600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private void bind(final Condition condition, View convertView) {
4088600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        final boolean enabled = condition == null || condition.state == Condition.STATE_TRUE;
4098600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        final View row;
4108600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        if (convertView == null) {
4118600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            row = mInflater.inflate(R.layout.zen_mode_condition, this, false);
412856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            if (DEBUG) Log.d(mTag, "Adding new condition view for: " + condition);
413ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mZenConditions.addView(row);
4148600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        } else {
4158600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            row = convertView;
4168600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
417856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        final ConditionTag tag =
418856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                row.getTag() != null ? (ConditionTag) row.getTag() : new ConditionTag();
419856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        row.setTag(tag);
420856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (tag.rb == null) {
421856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            tag.rb = (RadioButton) row.findViewById(android.R.id.checkbox);
422856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
423856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        tag.conditionId = condition != null ? condition.id : null;
424856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        tag.rb.setEnabled(enabled);
42550806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock        if (Objects.equals(tag.conditionId, mExitConditionId)) {
42650806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock            tag.rb.setChecked(true);
42750806fc4ceff4bb093a18bdecb506163e68b9cbbJohn Spurlock        }
428856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        tag.rb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
4298600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            @Override
4308600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
431ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                if (mExpanded && isChecked) {
432856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                    if (DEBUG) Log.d(mTag, "onCheckedChanged " + tag.conditionId);
433ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                    final int N = mZenConditions.getChildCount();
434856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                    for (int i = 0; i < N; i++) {
435856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                        ConditionTag childTag = getConditionTagAt(i);
436856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                        if (childTag == tag) continue;
437856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                        childTag.rb.setChecked(false);
4388600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock                    }
439856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                    select(tag.conditionId);
4408600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock                    fireInteraction();
4418600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock                }
4428600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            }
4438600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        });
4448600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        final TextView title = (TextView) row.findViewById(android.R.id.title);
4458600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        if (condition == null) {
4468600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            title.setText(R.string.zen_mode_forever);
4478600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        } else {
4488600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            title.setText(condition.summary);
4498600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
4508600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        title.setEnabled(enabled);
451ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        title.setAlpha(enabled ? 1 : .4f);
4528600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1);
4538600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        button1.setOnClickListener(new OnClickListener() {
4548600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            @Override
4558600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            public void onClick(View v) {
456856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                onClickTimeButton(row, tag, false /*down*/);
4578600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            }
4588600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        });
4598600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
4608600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2);
4618600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        button2.setOnClickListener(new OnClickListener() {
4628600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            @Override
4638600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            public void onClick(View v) {
464856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                onClickTimeButton(row, tag, true /*up*/);
4658600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            }
4668600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        });
4678600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        title.setOnClickListener(new OnClickListener() {
4688600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            @Override
4698600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            public void onClick(View v) {
470856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                tag.rb.setChecked(true);
4718600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock                fireInteraction();
4728600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            }
4738600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        });
474856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
475856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        final long time = ZenModeConfig.tryParseCountdownConditionId(tag.conditionId);
476856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (time > 0) {
477856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            if (mBucketIndex > -1) {
478856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                button1.setEnabled(mBucketIndex > 0);
479856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                button2.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1);
480856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            } else {
481856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                final long span = time - System.currentTimeMillis();
482856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                button1.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS);
483856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                final Condition maxCondition = newTimeCondition(MAX_BUCKET_MINUTES);
484856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                button2.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));
485856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            }
486856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
487856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            button1.setAlpha(button1.isEnabled() ? 1f : .5f);
488856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            button2.setAlpha(button2.isEnabled() ? 1f : .5f);
4898600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        } else {
4908600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            button1.setVisibility(View.GONE);
4918600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            button2.setVisibility(View.GONE);
4928600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
493856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
494856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
495856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private void onClickTimeButton(View row, ConditionTag tag, boolean up) {
496856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        Condition newCondition = null;
497856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        final int N = MINUTE_BUCKETS.length;
498856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (mBucketIndex == -1) {
499856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            // not on a known index, search for the next or prev bucket by time
500856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            final long time = ZenModeConfig.tryParseCountdownConditionId(tag.conditionId);
501856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            final long now = System.currentTimeMillis();
502856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            for (int i = 0; i < N; i++) {
503856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                int j = up ? i : N - 1 - i;
504856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                final int bucketMinutes = MINUTE_BUCKETS[j];
505856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                final long bucketTime = now + bucketMinutes * MINUTES_MS;
506856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                if (up && bucketTime > time || !up && bucketTime < time) {
507856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                    mBucketIndex = j;
508856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                    newCondition = timeCondition(bucketTime, bucketMinutes);
509856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                    break;
510856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                }
511856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            }
512856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            if (newCondition == null) {
513856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                mBucketIndex = DEFAULT_BUCKET_INDEX;
514856edebad73560e9b1cce021a7de9a0470d07176John Spurlock                newCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]);
515856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            }
516856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        } else {
517856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            // on a known index, simply increment or decrement
518856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            mBucketIndex = Math.max(0, Math.min(N - 1, mBucketIndex + (up ? 1 : -1)));
519856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            newCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]);
520856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
521856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        bind(newCondition, row);
522856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        tag.rb.setChecked(true);
523856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        select(newCondition.id);
524856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        fireInteraction();
525856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
526856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
527856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private void select(Uri conditionId) {
528856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (DEBUG) Log.d(mTag, "select " + conditionId);
529856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (mController != null) {
530856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            mController.setExitConditionId(conditionId);
531856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
532ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        setExitConditionId(conditionId);
533856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        if (conditionId == null) {
534856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            mFavorites.setMinuteIndex(-1);
535856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        } else if (ZenModeConfig.isValidCountdownConditionId(conditionId) && mBucketIndex != -1) {
536856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            mFavorites.setMinuteIndex(mBucketIndex);
5378600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
5388600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
5398600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
5408600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private void fireMoreSettings() {
5418600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        if (mCallback != null) {
5428600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            mCallback.onMoreSettings();
5438600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
5448600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
5458600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
5468600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private void fireInteraction() {
5478600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        if (mCallback != null) {
5488600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            mCallback.onInteraction();
5498600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
5508600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
5518600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
552ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private void fireExpanded() {
553ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        if (mCallback != null) {
554ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mCallback.onExpanded(mExpanded);
555ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        }
556ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    }
557ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
5588600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
5598600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        @Override
560ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        public void onZenChanged(int zen) {
561ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            mHandler.obtainMessage(H.UPDATE_ZEN, zen, 0).sendToTarget();
562ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        }
563ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        @Override
5648600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        public void onConditionsChanged(Condition[] conditions) {
5658600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            mHandler.obtainMessage(H.UPDATE_CONDITIONS, conditions).sendToTarget();
5668600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
567856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
568856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        @Override
569856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        public void onExitConditionChanged(Uri exitConditionId) {
570856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            mHandler.obtainMessage(H.EXIT_CONDITION_CHANGED, exitConditionId).sendToTarget();
571856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
57289f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock
57389f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        @Override
57489f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        public void onNextAlarmChanged() {
57589f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            mHandler.sendEmptyMessage(H.NEXT_ALARM_CHANGED);
57689f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        }
5778600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    };
5788600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
5798600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    private final class H extends Handler {
5808600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        private static final int UPDATE_CONDITIONS = 1;
581856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        private static final int EXIT_CONDITION_CHANGED = 2;
582ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        private static final int UPDATE_ZEN = 3;
58389f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock        private static final int NEXT_ALARM_CHANGED = 4;
5848600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
5858600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        private H() {
5868600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            super(Looper.getMainLooper());
5878600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
5888600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
5898600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        @Override
5908600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        public void handleMessage(Message msg) {
5918600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            if (msg.what == UPDATE_CONDITIONS) {
59289f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                handleUpdateConditions((Condition[]) msg.obj);
593ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                checkForDefault();
594856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            } else if (msg.what == EXIT_CONDITION_CHANGED) {
59589f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                handleExitConditionChanged((Uri) msg.obj);
596ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            } else if (msg.what == UPDATE_ZEN) {
597ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                handleUpdateZen(msg.arg1);
59889f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock            } else if (msg.what == NEXT_ALARM_CHANGED) {
59989f060a1e0fa48c497855d061b5c9ec44bb576c8John Spurlock                handleNextAlarmChanged();
6008600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock            }
6018600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        }
6028600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
6038600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock
6048600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    public interface Callback {
6058600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        void onMoreSettings();
6068600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock        void onInteraction();
607ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        void onExpanded(boolean expanded);
6088600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock    }
609856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
610856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    // used as the view tag on condition rows
611856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private static class ConditionTag {
612856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        RadioButton rb;
613856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        Uri conditionId;
614856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
615856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
616856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    private final class Favorites implements OnSharedPreferenceChangeListener {
617856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        private static final String KEY_MINUTE_INDEX = "minuteIndex";
618856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
619856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        private int mMinuteIndex;
620856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
621856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        private Favorites() {
622856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            prefs().registerOnSharedPreferenceChangeListener(this);
623856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            updateMinuteIndex();
624856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
625856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
626856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        public int getMinuteIndex() {
627856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            return mMinuteIndex;
628856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
629856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
630856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        public void setMinuteIndex(int minuteIndex) {
631856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            minuteIndex = clamp(minuteIndex);
632856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            if (minuteIndex == mMinuteIndex) return;
633856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            mMinuteIndex = clamp(minuteIndex);
634856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            if (DEBUG) Log.d(mTag, "Setting favorite minute index: " + mMinuteIndex);
635856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            prefs().edit().putInt(KEY_MINUTE_INDEX, mMinuteIndex).apply();
636856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
637856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
638856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        @Override
639856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
640856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            updateMinuteIndex();
641856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
642856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
643856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        private SharedPreferences prefs() {
644856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            return mContext.getSharedPreferences(ZenModePanel.class.getSimpleName(), 0);
645856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
646856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
647856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        private void updateMinuteIndex() {
648856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            mMinuteIndex = clamp(prefs().getInt(KEY_MINUTE_INDEX, DEFAULT_BUCKET_INDEX));
649856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            if (DEBUG) Log.d(mTag, "Favorite minute index: " + mMinuteIndex);
650856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
651856edebad73560e9b1cce021a7de9a0470d07176John Spurlock
652856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        private int clamp(int index) {
653856edebad73560e9b1cce021a7de9a0470d07176John Spurlock            return Math.max(-1, Math.min(MINUTE_BUCKETS.length - 1, index));
654856edebad73560e9b1cce021a7de9a0470d07176John Spurlock        }
655856edebad73560e9b1cce021a7de9a0470d07176John Spurlock    }
656ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock
657ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    private final SegmentedButtons.Callback mZenButtonsCallback = new SegmentedButtons.Callback() {
658ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        @Override
659ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        public void onSelected(Object value) {
660ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            if (value != null && mZenButtons.isShown()) {
661ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + value);
662ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                mController.setZen((Integer) value);
663ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock                mController.setExitConditionId(null);
664ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock            }
665ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock        }
666ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock    };
6678600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock}
668