ZenModePanel.java revision 8263c3e0647e0d9622585f1c196ceb8d2fde695e
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; 338600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.util.AttributeSet; 34856edebad73560e9b1cce021a7de9a0470d07176John Spurlockimport android.util.Log; 358600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.view.ContextThemeWrapper; 368600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.view.LayoutInflater; 378600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.view.View; 38ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlockimport android.view.animation.AnimationUtils; 39ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlockimport android.view.animation.Interpolator; 408600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.CompoundButton; 418600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.CompoundButton.OnCheckedChangeListener; 428600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.ImageView; 438600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.LinearLayout; 448600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.RadioButton; 458600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport android.widget.TextView; 468600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 478600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport com.android.systemui.R; 488600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport com.android.systemui.statusbar.policy.ZenModeController; 498600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 508600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockimport java.util.Arrays; 51856edebad73560e9b1cce021a7de9a0470d07176John Spurlockimport java.util.Objects; 528600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 538600534df66c2ff5846ed230b50c56229322d48aJohn Spurlockpublic class ZenModePanel extends LinearLayout { 54ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private static final String TAG = "ZenModePanel"; 55ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 56856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 57ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private static final int[] MINUTE_BUCKETS = DEBUG 58ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock ? new int[] { 1, 2, 5, 15, 30, 45, 60, 120, 180, 240, 480 } 59ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock : new int[] { 15, 30, 45, 60, 120, 180, 240, 480 }; 60856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0]; 61856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private static final int MAX_BUCKET_MINUTES = MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1]; 62856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60); 63ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private static final int FOREVER_CONDITION_INDEX = 0; 64ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private static final int TIME_CONDITION_INDEX = 1; 65ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private static final int FIRST_CONDITION_INDEX = 2; 66ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private static final float SILENT_HINT_PULSE_SCALE = 1.1f; 67856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 68856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private static final int SECONDS_MS = 1000; 69856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private static final int MINUTES_MS = 60 * SECONDS_MS; 70856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 718600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS); 728600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 737f1df5e98578f8532a5e009009e7c1f82ed5885cJohn Spurlock private final Context mContext; 748600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private final LayoutInflater mInflater; 758600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private final H mHandler = new H(); 76856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private final Favorites mFavorites; 77ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private final Interpolator mFastOutSlowInInterpolator; 78856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 79856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private char mLogTag = '?'; 80856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private String mTag; 81ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 82ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private SegmentedButtons mZenButtons; 83ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private View mZenSubhead; 84ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private TextView mZenSubheadCollapsed; 85ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private TextView mZenSubheadExpanded; 867f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock private View mMoreSettings; 87ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private LinearLayout mZenConditions; 88ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 898600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private Callback mCallback; 908600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private ZenModeController mController; 918600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private boolean mRequestingConditions; 92856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private Uri mExitConditionId; 93856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private int mBucketIndex = -1; 94ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private boolean mExpanded; 95ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private int mAttachedZen; 96ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private String mExitConditionText; 978600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 988600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public ZenModePanel(Context context, AttributeSet attrs) { 998600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock super(context, attrs); 1007f1df5e98578f8532a5e009009e7c1f82ed5885cJohn Spurlock mContext = context; 101856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mFavorites = new Favorites(); 102f7d22132c2c9b83134b05aaed63a89f61c639fd9John Spurlock mInflater = LayoutInflater.from(mContext.getApplicationContext()); 103ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(mContext, 104ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock android.R.interpolator.fast_out_slow_in); 105856edebad73560e9b1cce021a7de9a0470d07176John Spurlock updateTag(); 106856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "new ZenModePanel"); 107856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 108856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 109856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private void updateTag() { 110ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mTag = TAG + "/" + mLogTag + "/" + Integer.toHexString(System.identityHashCode(this)); 1118600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 1128600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 1138600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 1148600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock protected void onFinishInflate() { 1158600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock super.onFinishInflate(); 116ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 117ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons); 118ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenButtons.addButton(R.string.interruption_level_none, Global.ZEN_MODE_NO_INTERRUPTIONS); 119ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenButtons.addButton(R.string.interruption_level_priority, 120ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); 121ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenButtons.addButton(R.string.interruption_level_all, Global.ZEN_MODE_OFF); 122ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenButtons.setCallback(mZenButtonsCallback); 123ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 124ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenSubhead = findViewById(R.id.zen_subhead); 125ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 126ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenSubheadCollapsed = (TextView) findViewById(R.id.zen_subhead_collapsed); 127ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenSubheadCollapsed.setOnClickListener(new View.OnClickListener() { 128ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock @Override 129ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock public void onClick(View v) { 130ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock setExpanded(true); 131ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock fireInteraction(); 132ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 133ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock }); 134ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 135ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenSubheadExpanded = (TextView) findViewById(R.id.zen_subhead_expanded); 136ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 137ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mMoreSettings = findViewById(R.id.zen_more_settings); 1387f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock mMoreSettings.setOnClickListener(new View.OnClickListener() { 1398600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 1408600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public void onClick(View v) { 1418600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock fireMoreSettings(); 142ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock fireInteraction(); 1438600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 1448600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock }); 145ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 146ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions); 1478600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 1488600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 1498600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 150856edebad73560e9b1cce021a7de9a0470d07176John Spurlock protected void onAttachedToWindow() { 151856edebad73560e9b1cce021a7de9a0470d07176John Spurlock super.onAttachedToWindow(); 152856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "onAttachedToWindow"); 153ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mAttachedZen = getSelectedZen(-1); 154ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock refreshExitConditionText(); 155856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 156856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 157856edebad73560e9b1cce021a7de9a0470d07176John Spurlock @Override 158856edebad73560e9b1cce021a7de9a0470d07176John Spurlock protected void onDetachedFromWindow() { 159856edebad73560e9b1cce021a7de9a0470d07176John Spurlock super.onDetachedFromWindow(); 160856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "onDetachedFromWindow"); 161ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mAttachedZen = -1; 162ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock setExpanded(false); 163856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 164856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 165ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private void setExpanded(boolean expanded) { 166ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (expanded == mExpanded) return; 167ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mExpanded = expanded; 168ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock updateWidgets(); 169ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock setRequestingConditions(mExpanded); 170ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock fireExpanded(); 1718600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 1728600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 1738600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock /** Start or stop requesting relevant zen mode exit conditions */ 1748600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private void setRequestingConditions(boolean requesting) { 1758600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock if (mRequestingConditions == requesting) return; 176856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "setRequestingConditions " + requesting); 1778600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock mRequestingConditions = requesting; 178856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (mController != null) { 179856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mController.requestConditions(mRequestingConditions); 180856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 1818600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock if (mRequestingConditions) { 182856edebad73560e9b1cce021a7de9a0470d07176John Spurlock Condition timeCondition = parseExistingTimeCondition(mExitConditionId); 183856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (timeCondition != null) { 184856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mBucketIndex = -1; 185856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } else { 186856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mBucketIndex = DEFAULT_BUCKET_INDEX; 187856edebad73560e9b1cce021a7de9a0470d07176John Spurlock timeCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]); 188856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 189856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "Initial bucket index: " + mBucketIndex); 190ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock handleUpdateConditions(new Condition[0]); // ensures forever exists 191ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock bind(timeCondition, mZenConditions.getChildAt(TIME_CONDITION_INDEX)); 192ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock checkForDefault(); 1938600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } else { 194ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenConditions.removeAllViews(); 1958600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 1968600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 1978600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 198ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock public void init(ZenModeController controller, char logTag) { 1998600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock mController = controller; 200856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mLogTag = logTag; 201856edebad73560e9b1cce021a7de9a0470d07176John Spurlock updateTag(); 202ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock setExitConditionId(mController.getExitConditionId()); 203ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock refreshExitConditionText(); 204ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mAttachedZen = getSelectedZen(-1); 205ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock handleUpdateZen(mController.getZen()); 206856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "init mExitConditionId=" + mExitConditionId); 207ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenConditions.removeAllViews(); 208856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mController.addCallback(mZenCallback); 209ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 210ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 211ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private void setExitConditionId(Uri exitConditionId) { 212ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (Objects.equals(mExitConditionId, exitConditionId)) return; 213ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mExitConditionId = exitConditionId; 214ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock refreshExitConditionText(); 215ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 216ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 217ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private void refreshExitConditionText() { 218ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (mExitConditionId == null) { 219ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mExitConditionText = mContext.getString(R.string.zen_mode_forever); 220ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } else if (ZenModeConfig.isValidCountdownConditionId(mExitConditionId)) { 221ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mExitConditionText = parseExistingTimeCondition(mExitConditionId).summary; 222ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } else { 223ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mExitConditionText = "(until condition ends)"; // TODO persist current description 224856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 2258600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 2268600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 2278600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public void setCallback(Callback callback) { 2288600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock mCallback = callback; 2298600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 2308600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 231ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock public void showSilentHint() { 232ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (DEBUG) Log.d(mTag, "showSilentHint"); 233ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (mZenButtons == null || mZenButtons.getChildCount() == 0) return; 234ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock final View noneButton = mZenButtons.getChildAt(0); 235ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (noneButton.getScaleX() != 1) return; // already running 236ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock noneButton.animate().cancel(); 237ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock noneButton.animate().scaleX(SILENT_HINT_PULSE_SCALE).scaleY(SILENT_HINT_PULSE_SCALE) 238ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock .setInterpolator(mFastOutSlowInInterpolator) 239ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock .setListener(new AnimatorListenerAdapter() { 240ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock @Override 241ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock public void onAnimationEnd(Animator animation) { 242ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock noneButton.animate().scaleX(1).scaleY(1).setListener(null); 243ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 244ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock }); 245ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 246ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 247ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private void handleUpdateZen(int zen) { 248ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (mAttachedZen != -1 && mAttachedZen != zen) { 249ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock setExpanded(zen != Global.ZEN_MODE_OFF); 250ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mAttachedZen = zen; 251ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 252ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenButtons.setSelectedValue(zen); 253ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock updateWidgets(); 254ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 255ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 256ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private int getSelectedZen(int defValue) { 257ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock final Object zen = mZenButtons.getSelectedValue(); 258ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock return zen != null ? (Integer) zen : defValue; 259ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 260ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 261ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private void updateWidgets() { 262ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock final int zen = getSelectedZen(Global.ZEN_MODE_OFF); 263ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock final boolean zenOff = zen == Global.ZEN_MODE_OFF; 264ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock final boolean zenImportant = zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; 265ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS; 2668263c3e0647e0d9622585f1c196ceb8d2fde695eJohn Spurlock final boolean foreverSelected = mExitConditionId == null; 267ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 2688263c3e0647e0d9622585f1c196ceb8d2fde695eJohn Spurlock mZenSubhead.setVisibility(!zenOff && (mExpanded || !foreverSelected) ? VISIBLE : GONE); 269ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenSubheadExpanded.setVisibility(mExpanded ? VISIBLE : GONE); 270ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenSubheadCollapsed.setVisibility(!mExpanded ? VISIBLE : GONE); 271ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mMoreSettings.setVisibility(zenImportant && mExpanded ? VISIBLE : GONE); 272ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenConditions.setVisibility(!zenOff && mExpanded ? VISIBLE : GONE); 273ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 274ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (zenNone) { 27586d04fdaa1853cf7ff8ec9aba1dd925dd098167eJohn Spurlock mZenSubheadExpanded.setText(R.string.zen_no_interruptions_with_warning); 276ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenSubheadCollapsed.setText(mExitConditionText); 277ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } else if (zenImportant) { 278ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenSubheadExpanded.setText(R.string.zen_important_interruptions); 279ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenSubheadCollapsed.setText(mExitConditionText); 280ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 281ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 282ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 283856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private Condition parseExistingTimeCondition(Uri conditionId) { 284856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId); 285856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (time == 0) return null; 286856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final long span = time - System.currentTimeMillis(); 287856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (span <= 0 || span > MAX_BUCKET_MINUTES * MINUTES_MS) return null; 288856edebad73560e9b1cce021a7de9a0470d07176John Spurlock return timeCondition(time, Math.round(span / (float)MINUTES_MS)); 289856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 290856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 291856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private Condition newTimeCondition(int minutesFromNow) { 292856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final long now = System.currentTimeMillis(); 293856edebad73560e9b1cce021a7de9a0470d07176John Spurlock return timeCondition(now + minutesFromNow * MINUTES_MS, minutesFromNow); 294856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 295856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 296856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private Condition timeCondition(long time, int minutes) { 297856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final int num = minutes < 60 ? minutes : Math.round(minutes / 60f); 2988600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock final int resId = minutes < 60 2998600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock ? R.plurals.zen_mode_duration_minutes 3008600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock : R.plurals.zen_mode_duration_hours; 3018600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock final String caption = mContext.getResources().getQuantityString(resId, num, num); 302856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final Uri id = ZenModeConfig.toCountdownConditionId(time); 3038600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock return new Condition(id, caption, "", "", 0, Condition.STATE_TRUE, 3048600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock Condition.FLAG_RELEVANT_NOW); 3058600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 3068600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 3078600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private void handleUpdateConditions(Condition[] conditions) { 3088600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock final int newCount = conditions == null ? 0 : conditions.length; 309ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (DEBUG) Log.d(mTag, "handleUpdateConditions newCount=" + newCount); 310ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock for (int i = mZenConditions.getChildCount(); i >= newCount + FIRST_CONDITION_INDEX; i--) { 311ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenConditions.removeViewAt(i); 3128600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 313ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock bind(null, mZenConditions.getChildAt(FOREVER_CONDITION_INDEX)); 3148600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock for (int i = 0; i < newCount; i++) { 315ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock bind(conditions[i], mZenConditions.getChildAt(FIRST_CONDITION_INDEX + i)); 3168600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 317856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 318856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 319856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private ConditionTag getConditionTagAt(int index) { 320ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock return (ConditionTag) mZenConditions.getChildAt(index).getTag(); 321856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 322856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 323856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private void checkForDefault() { 324856edebad73560e9b1cce021a7de9a0470d07176John Spurlock // are we left without anything selected? if so, set a default 325ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock for (int i = 0; i < mZenConditions.getChildCount(); i++) { 326856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (getConditionTagAt(i).rb.isChecked()) { 327856edebad73560e9b1cce021a7de9a0470d07176John Spurlock return; 328856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 329856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 330856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "Selecting a default"); 331856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final int favoriteIndex = mFavorites.getMinuteIndex(); 332856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (favoriteIndex == -1) { 333ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock getConditionTagAt(FOREVER_CONDITION_INDEX).rb.setChecked(true); 334856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } else { 335856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final Condition c = newTimeCondition(MINUTE_BUCKETS[favoriteIndex]); 336856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mBucketIndex = favoriteIndex; 337ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock bind(c, mZenConditions.getChildAt(TIME_CONDITION_INDEX)); 338ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock getConditionTagAt(TIME_CONDITION_INDEX).rb.setChecked(true); 339856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 3408600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 3418600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 342856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private void handleExitConditionChanged(Uri exitCondition) { 343ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock setExitConditionId(exitCondition); 344856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "handleExitConditionChanged " + mExitConditionId); 345ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock final int N = mZenConditions.getChildCount(); 346856edebad73560e9b1cce021a7de9a0470d07176John Spurlock for (int i = 0; i < N; i++) { 347856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final ConditionTag tag = getConditionTagAt(i); 348856edebad73560e9b1cce021a7de9a0470d07176John Spurlock tag.rb.setChecked(Objects.equals(tag.conditionId, exitCondition)); 349856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 3508600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 3518600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 3528600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private void bind(final Condition condition, View convertView) { 3538600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock final boolean enabled = condition == null || condition.state == Condition.STATE_TRUE; 3548600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock final View row; 3558600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock if (convertView == null) { 3568600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock row = mInflater.inflate(R.layout.zen_mode_condition, this, false); 357856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "Adding new condition view for: " + condition); 358ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mZenConditions.addView(row); 3598600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } else { 3608600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock row = convertView; 3618600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 362856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final ConditionTag tag = 363856edebad73560e9b1cce021a7de9a0470d07176John Spurlock row.getTag() != null ? (ConditionTag) row.getTag() : new ConditionTag(); 364856edebad73560e9b1cce021a7de9a0470d07176John Spurlock row.setTag(tag); 365856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (tag.rb == null) { 366856edebad73560e9b1cce021a7de9a0470d07176John Spurlock tag.rb = (RadioButton) row.findViewById(android.R.id.checkbox); 367856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 368856edebad73560e9b1cce021a7de9a0470d07176John Spurlock tag.conditionId = condition != null ? condition.id : null; 369856edebad73560e9b1cce021a7de9a0470d07176John Spurlock tag.rb.setEnabled(enabled); 370856edebad73560e9b1cce021a7de9a0470d07176John Spurlock tag.rb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 3718600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 3728600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 373ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (mExpanded && isChecked) { 374856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "onCheckedChanged " + tag.conditionId); 375ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock final int N = mZenConditions.getChildCount(); 376856edebad73560e9b1cce021a7de9a0470d07176John Spurlock for (int i = 0; i < N; i++) { 377856edebad73560e9b1cce021a7de9a0470d07176John Spurlock ConditionTag childTag = getConditionTagAt(i); 378856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (childTag == tag) continue; 379856edebad73560e9b1cce021a7de9a0470d07176John Spurlock childTag.rb.setChecked(false); 3808600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 381856edebad73560e9b1cce021a7de9a0470d07176John Spurlock select(tag.conditionId); 3828600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock fireInteraction(); 3838600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 3848600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 3858600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock }); 3868600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock final TextView title = (TextView) row.findViewById(android.R.id.title); 3878600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock if (condition == null) { 3888600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock title.setText(R.string.zen_mode_forever); 3898600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } else { 3908600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock title.setText(condition.summary); 3918600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 3928600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock title.setEnabled(enabled); 393ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock title.setAlpha(enabled ? 1 : .4f); 3948600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1); 3958600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock button1.setOnClickListener(new OnClickListener() { 3968600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 3978600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public void onClick(View v) { 398856edebad73560e9b1cce021a7de9a0470d07176John Spurlock onClickTimeButton(row, tag, false /*down*/); 3998600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 4008600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock }); 4018600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 4028600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2); 4038600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock button2.setOnClickListener(new OnClickListener() { 4048600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 4058600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public void onClick(View v) { 406856edebad73560e9b1cce021a7de9a0470d07176John Spurlock onClickTimeButton(row, tag, true /*up*/); 4078600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 4088600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock }); 4098600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock title.setOnClickListener(new OnClickListener() { 4108600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 4118600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public void onClick(View v) { 412856edebad73560e9b1cce021a7de9a0470d07176John Spurlock tag.rb.setChecked(true); 4138600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock fireInteraction(); 4148600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 4158600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock }); 416856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 417856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final long time = ZenModeConfig.tryParseCountdownConditionId(tag.conditionId); 418856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (time > 0) { 419856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (mBucketIndex > -1) { 420856edebad73560e9b1cce021a7de9a0470d07176John Spurlock button1.setEnabled(mBucketIndex > 0); 421856edebad73560e9b1cce021a7de9a0470d07176John Spurlock button2.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1); 422856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } else { 423856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final long span = time - System.currentTimeMillis(); 424856edebad73560e9b1cce021a7de9a0470d07176John Spurlock button1.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS); 425856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final Condition maxCondition = newTimeCondition(MAX_BUCKET_MINUTES); 426856edebad73560e9b1cce021a7de9a0470d07176John Spurlock button2.setEnabled(!Objects.equals(condition.summary, maxCondition.summary)); 427856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 428856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 429856edebad73560e9b1cce021a7de9a0470d07176John Spurlock button1.setAlpha(button1.isEnabled() ? 1f : .5f); 430856edebad73560e9b1cce021a7de9a0470d07176John Spurlock button2.setAlpha(button2.isEnabled() ? 1f : .5f); 4318600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } else { 4328600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock button1.setVisibility(View.GONE); 4338600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock button2.setVisibility(View.GONE); 4348600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 435856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 436856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 437856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private void onClickTimeButton(View row, ConditionTag tag, boolean up) { 438856edebad73560e9b1cce021a7de9a0470d07176John Spurlock Condition newCondition = null; 439856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final int N = MINUTE_BUCKETS.length; 440856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (mBucketIndex == -1) { 441856edebad73560e9b1cce021a7de9a0470d07176John Spurlock // not on a known index, search for the next or prev bucket by time 442856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final long time = ZenModeConfig.tryParseCountdownConditionId(tag.conditionId); 443856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final long now = System.currentTimeMillis(); 444856edebad73560e9b1cce021a7de9a0470d07176John Spurlock for (int i = 0; i < N; i++) { 445856edebad73560e9b1cce021a7de9a0470d07176John Spurlock int j = up ? i : N - 1 - i; 446856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final int bucketMinutes = MINUTE_BUCKETS[j]; 447856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final long bucketTime = now + bucketMinutes * MINUTES_MS; 448856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (up && bucketTime > time || !up && bucketTime < time) { 449856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mBucketIndex = j; 450856edebad73560e9b1cce021a7de9a0470d07176John Spurlock newCondition = timeCondition(bucketTime, bucketMinutes); 451856edebad73560e9b1cce021a7de9a0470d07176John Spurlock break; 452856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 453856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 454856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (newCondition == null) { 455856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mBucketIndex = DEFAULT_BUCKET_INDEX; 456856edebad73560e9b1cce021a7de9a0470d07176John Spurlock newCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]); 457856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 458856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } else { 459856edebad73560e9b1cce021a7de9a0470d07176John Spurlock // on a known index, simply increment or decrement 460856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mBucketIndex = Math.max(0, Math.min(N - 1, mBucketIndex + (up ? 1 : -1))); 461856edebad73560e9b1cce021a7de9a0470d07176John Spurlock newCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]); 462856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 463856edebad73560e9b1cce021a7de9a0470d07176John Spurlock bind(newCondition, row); 464856edebad73560e9b1cce021a7de9a0470d07176John Spurlock tag.rb.setChecked(true); 465856edebad73560e9b1cce021a7de9a0470d07176John Spurlock select(newCondition.id); 466856edebad73560e9b1cce021a7de9a0470d07176John Spurlock fireInteraction(); 467856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 468856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 469856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private void select(Uri conditionId) { 470856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "select " + conditionId); 471856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (mController != null) { 472856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mController.setExitConditionId(conditionId); 473856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 474ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock setExitConditionId(conditionId); 475856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (conditionId == null) { 476856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mFavorites.setMinuteIndex(-1); 477856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } else if (ZenModeConfig.isValidCountdownConditionId(conditionId) && mBucketIndex != -1) { 478856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mFavorites.setMinuteIndex(mBucketIndex); 4798600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 4808600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 4818600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 4828600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private void fireMoreSettings() { 4838600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock if (mCallback != null) { 4848600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock mCallback.onMoreSettings(); 4858600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 4868600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 4878600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 4888600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private void fireInteraction() { 4898600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock if (mCallback != null) { 4908600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock mCallback.onInteraction(); 4918600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 4928600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 4938600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 494ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private void fireExpanded() { 495ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (mCallback != null) { 496ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mCallback.onExpanded(mExpanded); 497ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 498ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 499ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 5008600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() { 5018600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 502ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock public void onZenChanged(int zen) { 503ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mHandler.obtainMessage(H.UPDATE_ZEN, zen, 0).sendToTarget(); 504ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 505ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock @Override 5068600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public void onConditionsChanged(Condition[] conditions) { 5078600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock mHandler.obtainMessage(H.UPDATE_CONDITIONS, conditions).sendToTarget(); 5088600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 509856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 510856edebad73560e9b1cce021a7de9a0470d07176John Spurlock @Override 511856edebad73560e9b1cce021a7de9a0470d07176John Spurlock public void onExitConditionChanged(Uri exitConditionId) { 512856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mHandler.obtainMessage(H.EXIT_CONDITION_CHANGED, exitConditionId).sendToTarget(); 513856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 5148600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock }; 5158600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 5168600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private final class H extends Handler { 5178600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private static final int UPDATE_CONDITIONS = 1; 518856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private static final int EXIT_CONDITION_CHANGED = 2; 519ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private static final int UPDATE_ZEN = 3; 5208600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 5218600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock private H() { 5228600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock super(Looper.getMainLooper()); 5238600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 5248600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 5258600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 5268600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public void handleMessage(Message msg) { 5278600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock if (msg.what == UPDATE_CONDITIONS) { 5288600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock handleUpdateConditions((Condition[])msg.obj); 529ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock checkForDefault(); 530856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } else if (msg.what == EXIT_CONDITION_CHANGED) { 531856edebad73560e9b1cce021a7de9a0470d07176John Spurlock handleExitConditionChanged((Uri)msg.obj); 532ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } else if (msg.what == UPDATE_ZEN) { 533ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock handleUpdateZen(msg.arg1); 5348600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 5358600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 5368600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 5378600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 5388600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock public interface Callback { 5398600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock void onMoreSettings(); 5408600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock void onInteraction(); 541ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock void onExpanded(boolean expanded); 5428600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 543856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 544856edebad73560e9b1cce021a7de9a0470d07176John Spurlock // used as the view tag on condition rows 545856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private static class ConditionTag { 546856edebad73560e9b1cce021a7de9a0470d07176John Spurlock RadioButton rb; 547856edebad73560e9b1cce021a7de9a0470d07176John Spurlock Uri conditionId; 548856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 549856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 550856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private final class Favorites implements OnSharedPreferenceChangeListener { 551856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private static final String KEY_MINUTE_INDEX = "minuteIndex"; 552856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 553856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private int mMinuteIndex; 554856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 555856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private Favorites() { 556856edebad73560e9b1cce021a7de9a0470d07176John Spurlock prefs().registerOnSharedPreferenceChangeListener(this); 557856edebad73560e9b1cce021a7de9a0470d07176John Spurlock updateMinuteIndex(); 558856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 559856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 560856edebad73560e9b1cce021a7de9a0470d07176John Spurlock public int getMinuteIndex() { 561856edebad73560e9b1cce021a7de9a0470d07176John Spurlock return mMinuteIndex; 562856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 563856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 564856edebad73560e9b1cce021a7de9a0470d07176John Spurlock public void setMinuteIndex(int minuteIndex) { 565856edebad73560e9b1cce021a7de9a0470d07176John Spurlock minuteIndex = clamp(minuteIndex); 566856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (minuteIndex == mMinuteIndex) return; 567856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mMinuteIndex = clamp(minuteIndex); 568856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "Setting favorite minute index: " + mMinuteIndex); 569856edebad73560e9b1cce021a7de9a0470d07176John Spurlock prefs().edit().putInt(KEY_MINUTE_INDEX, mMinuteIndex).apply(); 570856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 571856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 572856edebad73560e9b1cce021a7de9a0470d07176John Spurlock @Override 573856edebad73560e9b1cce021a7de9a0470d07176John Spurlock public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { 574856edebad73560e9b1cce021a7de9a0470d07176John Spurlock updateMinuteIndex(); 575856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 576856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 577856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private SharedPreferences prefs() { 578856edebad73560e9b1cce021a7de9a0470d07176John Spurlock return mContext.getSharedPreferences(ZenModePanel.class.getSimpleName(), 0); 579856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 580856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 581856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private void updateMinuteIndex() { 582856edebad73560e9b1cce021a7de9a0470d07176John Spurlock mMinuteIndex = clamp(prefs().getInt(KEY_MINUTE_INDEX, DEFAULT_BUCKET_INDEX)); 583856edebad73560e9b1cce021a7de9a0470d07176John Spurlock if (DEBUG) Log.d(mTag, "Favorite minute index: " + mMinuteIndex); 584856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 585856edebad73560e9b1cce021a7de9a0470d07176John Spurlock 586856edebad73560e9b1cce021a7de9a0470d07176John Spurlock private int clamp(int index) { 587856edebad73560e9b1cce021a7de9a0470d07176John Spurlock return Math.max(-1, Math.min(MINUTE_BUCKETS.length - 1, index)); 588856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 589856edebad73560e9b1cce021a7de9a0470d07176John Spurlock } 590ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock 591ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock private final SegmentedButtons.Callback mZenButtonsCallback = new SegmentedButtons.Callback() { 592ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock @Override 593ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock public void onSelected(Object value) { 594ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (value != null && mZenButtons.isShown()) { 595ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + value); 596ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mController.setZen((Integer) value); 597ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock mController.setExitConditionId(null); 598ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 599ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock } 600ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlock }; 6018600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock} 602