blob: a051973efddaec4f3cbbbfc5053083a66b295b51 [file] [log] [blame]
Jorim Jaggid7daab72014-05-06 22:22:20 +02001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.systemui.statusbar.phone;
18
Jose Lima235510e2014-08-13 12:50:01 -070019import android.app.AlarmManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020020import android.app.PendingIntent;
Jorim Jaggid7daab72014-05-06 22:22:20 +020021import android.content.Context;
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +020022import android.content.Intent;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020023import android.content.res.Configuration;
24import android.content.res.Resources;
Jorim Jaggidb3e6ed2014-05-12 20:18:47 +020025import android.graphics.Outline;
26import android.graphics.Rect;
John Spurlock465cefa2014-08-16 10:39:33 -040027import android.graphics.drawable.Animatable;
Jorim Jaggi3f48f462014-07-08 16:53:29 +020028import android.graphics.drawable.Drawable;
Jorim Jaggib7303a32015-08-19 16:51:36 -070029import android.graphics.drawable.RippleDrawable;
Jorim Jaggid7daab72014-05-06 22:22:20 +020030import android.util.AttributeSet;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020031import android.util.MathUtils;
Jorim Jaggifc69f782014-08-14 16:55:35 +020032import android.util.TypedValue;
Jorim Jaggid7daab72014-05-06 22:22:20 +020033import android.view.View;
34import android.view.ViewGroup;
Chris Craik7b7ca3c2014-07-11 13:32:19 -070035import android.view.ViewOutlineProvider;
Jorim Jaggif056e352014-05-11 23:09:22 +020036import android.widget.ImageView;
Jorim Jaggid7daab72014-05-06 22:22:20 +020037import android.widget.LinearLayout;
38import android.widget.RelativeLayout;
John Spurlock7f8f22a2014-07-02 18:54:17 -040039import android.widget.Switch;
Adrian Roos59a61272014-06-06 19:07:24 +020040import android.widget.TextView;
Jason Monk431ad732015-07-16 08:58:15 -040041import android.widget.Toast;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020042import com.android.keyguard.KeyguardStatusView;
Jorim Jaggi06d551a2014-09-02 15:55:57 +020043import com.android.systemui.BatteryMeterView;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020044import com.android.systemui.FontSizeUtils;
Jorim Jaggid7daab72014-05-06 22:22:20 +020045import com.android.systemui.R;
John Spurlockaf8d6c42014-05-07 17:49:08 -040046import com.android.systemui.qs.QSPanel;
John Spurlock7f8f22a2014-07-02 18:54:17 -040047import com.android.systemui.qs.QSTile;
Jason Monk377e7ad2016-02-16 14:03:21 -050048import com.android.systemui.qs.QSTile.DetailAdapter;
Jorim Jaggi853b0702014-07-05 04:31:14 +020049import com.android.systemui.statusbar.policy.BatteryController;
Jason Monk46dbfb42016-02-25 14:59:20 -050050import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020051import com.android.systemui.statusbar.policy.NextAlarmController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +020052import com.android.systemui.statusbar.policy.UserInfoController;
Jason Monk431ad732015-07-16 08:58:15 -040053import com.android.systemui.tuner.TunerService;
Jorim Jaggid7daab72014-05-06 22:22:20 +020054
Elliott Hughes88d25512014-10-03 12:06:17 -070055import java.text.NumberFormat;
56
Jorim Jaggid7daab72014-05-06 22:22:20 +020057/**
58 * The view to manage the header area in the expanded status bar.
59 */
Jason Monk0e1101d2015-10-07 13:06:09 -040060public class StatusBarHeaderView extends BaseStatusBarHeader implements View.OnClickListener,
Jason Monkc6cc6262015-06-11 11:10:15 -040061 BatteryController.BatteryStateChangeCallback, NextAlarmController.NextAlarmChangeCallback,
Jason Monkdeba7a42015-12-08 16:14:10 -050062 EmergencyListener {
Jorim Jaggif62f2bb2014-05-25 22:28:41 +020063
Jorim Jaggid7daab72014-05-06 22:22:20 +020064 private boolean mExpanded;
Jorim Jaggie65e3102014-07-01 22:00:50 +020065 private boolean mListening;
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +020066
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +020067 private ViewGroup mSystemIconsContainer;
Jorim Jaggi605f1902014-06-25 05:23:42 +020068 private View mSystemIconsSuperContainer;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020069 private View mDateGroup;
70 private View mClock;
Jorim Jaggifc69f782014-08-14 16:55:35 +020071 private TextView mTime;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020072 private TextView mAmPm;
Jorim Jaggi3d878be2014-05-10 03:22:32 +020073 private MultiUserSwitch mMultiUserSwitch;
Jorim Jaggi3f48f462014-07-08 16:53:29 +020074 private ImageView mMultiUserAvatar;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020075 private TextView mDateCollapsed;
76 private TextView mDateExpanded;
Jorim Jaggi90e0df22014-07-30 01:10:35 +020077 private LinearLayout mSystemIcons;
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +020078 private View mSignalCluster;
Jason Monk431ad732015-07-16 08:58:15 -040079 private SettingsButton mSettingsButton;
80 private View mSettingsContainer;
John Spurlock7f8f22a2014-07-02 18:54:17 -040081 private View mQsDetailHeader;
John Spurlock486b78e2014-07-07 08:37:56 -040082 private TextView mQsDetailHeaderTitle;
83 private Switch mQsDetailHeaderSwitch;
John Spurlock465cefa2014-08-16 10:39:33 -040084 private ImageView mQsDetailHeaderProgress;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020085 private TextView mEmergencyCallsOnly;
Jorim Jaggi853b0702014-07-05 04:31:14 +020086 private TextView mBatteryLevel;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020087 private TextView mAlarmStatus;
Adrian Roos59a61272014-06-06 19:07:24 +020088
89 private boolean mShowEmergencyCallsOnly;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020090 private boolean mAlarmShowing;
Jose Lima235510e2014-08-13 12:50:01 -070091 private AlarmManager.AlarmClockInfo mNextAlarm;
Jorim Jaggid7daab72014-05-06 22:22:20 +020092
93 private int mCollapsedHeight;
94 private int mExpandedHeight;
Jorim Jaggi9054d942014-05-09 22:47:28 +020095
Jorim Jaggi129e7ac2014-06-10 22:03:48 +020096 private int mMultiUserExpandedMargin;
Jorim Jaggi3f48f462014-07-08 16:53:29 +020097 private int mMultiUserCollapsedMargin;
Jorim Jaggi4538027d2014-07-30 15:43:13 +020098
Jorim Jaggi3f48f462014-07-08 16:53:29 +020099 private int mClockMarginBottomExpanded;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200100 private int mClockMarginBottomCollapsed;
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200101 private int mMultiUserSwitchWidthCollapsed;
102 private int mMultiUserSwitchWidthExpanded;
103
Jorim Jaggifc69f782014-08-14 16:55:35 +0200104 private int mClockCollapsedSize;
105 private int mClockExpandedSize;
106
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200107 /**
108 * In collapsed QS, the clock and avatar are scaled down a bit post-layout to allow for a nice
109 * transition. These values determine that factor.
110 */
111 private float mClockCollapsedScaleFactor;
112 private float mAvatarCollapsedScaleFactor;
Jorim Jaggie18c2cd2014-05-08 19:16:49 +0200113
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200114 private ActivityStarter mActivityStarter;
Jorim Jaggi853b0702014-07-05 04:31:14 +0200115 private BatteryController mBatteryController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200116 private NextAlarmController mNextAlarmController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400117 private QSPanel mQSPanel;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200118
Jorim Jaggidb3e6ed2014-05-12 20:18:47 +0200119 private final Rect mClipBounds = new Rect();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200120
121 private boolean mCaptureValues;
122 private boolean mSignalClusterDetached;
123 private final LayoutValues mCollapsedValues = new LayoutValues();
124 private final LayoutValues mExpandedValues = new LayoutValues();
125 private final LayoutValues mCurrentValues = new LayoutValues();
126
127 private float mCurrentT;
Selim Cineke32010a2014-08-20 23:50:41 +0200128 private boolean mShowingDetail;
Jorim Jaggi2ba59792015-06-05 12:12:58 -0700129 private boolean mDetailTransitioning;
Jorim Jaggidb3e6ed2014-05-12 20:18:47 +0200130
Jason Monkca4b5362015-10-07 10:43:29 -0400131 private boolean mAllowExpand = true;
132
Jorim Jaggid7daab72014-05-06 22:22:20 +0200133 public StatusBarHeaderView(Context context, AttributeSet attrs) {
134 super(context, attrs);
135 }
136
137 @Override
138 protected void onFinishInflate() {
139 super.onFinishInflate();
Jorim Jaggi605f1902014-06-25 05:23:42 +0200140 mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container);
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200141 mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200142 mSystemIconsSuperContainer.setOnClickListener(this);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200143 mDateGroup = findViewById(R.id.date_group);
144 mClock = findViewById(R.id.clock);
Jorim Jaggifc69f782014-08-14 16:55:35 +0200145 mTime = (TextView) findViewById(R.id.time_view);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200146 mAmPm = (TextView) findViewById(R.id.am_pm_view);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200147 mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200148 mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200149 mDateCollapsed = (TextView) findViewById(R.id.date_collapsed);
150 mDateExpanded = (TextView) findViewById(R.id.date_expanded);
Jason Monk431ad732015-07-16 08:58:15 -0400151 mSettingsButton = (SettingsButton) findViewById(R.id.settings_button);
152 mSettingsContainer = findViewById(R.id.settings_button_container);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200153 mSettingsButton.setOnClickListener(this);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400154 mQsDetailHeader = findViewById(R.id.qs_detail_header);
155 mQsDetailHeader.setAlpha(0);
John Spurlock486b78e2014-07-07 08:37:56 -0400156 mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title);
157 mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle);
John Spurlock465cefa2014-08-16 10:39:33 -0400158 mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200159 mEmergencyCallsOnly = (TextView) findViewById(R.id.header_emergency_calls_only);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200160 mBatteryLevel = (TextView) findViewById(R.id.battery_level);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200161 mAlarmStatus = (TextView) findViewById(R.id.alarm_status);
162 mAlarmStatus.setOnClickListener(this);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200163 mSignalCluster = findViewById(R.id.signal_cluster);
164 mSystemIcons = (LinearLayout) findViewById(R.id.system_icons);
Jorim Jaggid7daab72014-05-06 22:22:20 +0200165 loadDimens();
John Spurlocke86ae852014-05-17 16:18:27 -0400166 updateVisibilities();
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200167 updateClockScale();
168 updateAvatarScale();
John Spurlockd9792b72014-05-21 23:50:13 -0400169 addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
170 @Override
171 public void onLayoutChange(View v, int left, int top, int right,
172 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
173 if ((right - left) != (oldRight - oldLeft)) {
174 // width changed, update clipping
175 setClipping(getHeight());
176 }
Jorim Jaggi329fa242014-07-11 21:42:00 +0200177 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
178 mTime.setPivotX(rtl ? mTime.getWidth() : 0);
179 mTime.setPivotY(mTime.getBaseline());
Jorim Jaggi329fa242014-07-11 21:42:00 +0200180 updateAmPmTranslation();
John Spurlockd9792b72014-05-21 23:50:13 -0400181 }
182 });
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700183 setOutlineProvider(new ViewOutlineProvider() {
184 @Override
Chris Craik31ba1922014-07-18 13:48:09 -0700185 public void getOutline(View view, Outline outline) {
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700186 outline.setRect(mClipBounds);
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700187 }
188 });
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200189 requestCaptureValues();
Jorim Jaggib7303a32015-08-19 16:51:36 -0700190
191 // RenderThread is doing more harm than good when touching the header (to expand quick
192 // settings), so disable it for this view
193 ((RippleDrawable) getBackground()).setForceSoftware(true);
194 ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
195 ((RippleDrawable) mSystemIconsSuperContainer.getBackground()).setForceSoftware(true);
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200196 }
197
198 @Override
199 protected void onLayout(boolean changed, int l, int t, int r, int b) {
200 super.onLayout(changed, l, t, r, b);
201 if (mCaptureValues) {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200202 if (mExpanded) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200203 captureLayoutValues(mExpandedValues);
204 } else {
205 captureLayoutValues(mCollapsedValues);
206 }
207 mCaptureValues = false;
208 updateLayoutValues(mCurrentT);
209 }
210 mAlarmStatus.setX(mDateGroup.getLeft() + mDateCollapsed.getRight());
211 }
212
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200213 @Override
214 protected void onConfigurationChanged(Configuration newConfig) {
215 super.onConfigurationChanged(newConfig);
216 FontSizeUtils.updateFontSize(mBatteryLevel, R.dimen.battery_level_text_size);
217 FontSizeUtils.updateFontSize(mEmergencyCallsOnly,
218 R.dimen.qs_emergency_calls_only_text_size);
219 FontSizeUtils.updateFontSize(mDateCollapsed, R.dimen.qs_date_collapsed_size);
220 FontSizeUtils.updateFontSize(mDateExpanded, R.dimen.qs_date_collapsed_size);
221 FontSizeUtils.updateFontSize(mAlarmStatus, R.dimen.qs_date_collapsed_size);
222 FontSizeUtils.updateFontSize(this, android.R.id.title, R.dimen.qs_detail_header_text_size);
223 FontSizeUtils.updateFontSize(this, android.R.id.toggle, R.dimen.qs_detail_header_text_size);
224 FontSizeUtils.updateFontSize(mAmPm, R.dimen.qs_time_collapsed_size);
225 FontSizeUtils.updateFontSize(this, R.id.empty_time_view, R.dimen.qs_time_expanded_size);
226
Adrian Roos54f934c2014-09-17 18:35:32 +0200227 mEmergencyCallsOnly.setText(com.android.internal.R.string.emergency_calls_only);
228
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200229 mClockCollapsedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size);
230 mClockExpandedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size);
231 mClockCollapsedScaleFactor = (float) mClockCollapsedSize / (float) mClockExpandedSize;
232
233 updateClockScale();
234 updateClockCollapsedMargin();
235 }
236
237 private void updateClockCollapsedMargin() {
238 Resources res = getResources();
239 int padding = res.getDimensionPixelSize(R.dimen.clock_collapsed_bottom_margin);
240 int largePadding = res.getDimensionPixelSize(
241 R.dimen.clock_collapsed_bottom_margin_large_text);
242 float largeFactor = (MathUtils.constrain(getResources().getConfiguration().fontScale, 1.0f,
243 FontSizeUtils.LARGE_TEXT_SCALE) - 1f) / (FontSizeUtils.LARGE_TEXT_SCALE - 1f);
244 mClockMarginBottomCollapsed = Math.round((1 - largeFactor) * padding + largeFactor * largePadding);
245 requestLayout();
246 }
247
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200248 private void requestCaptureValues() {
249 mCaptureValues = true;
250 requestLayout();
Jorim Jaggid7daab72014-05-06 22:22:20 +0200251 }
252
253 private void loadDimens() {
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200254 mCollapsedHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_header_height);
Jorim Jaggid7daab72014-05-06 22:22:20 +0200255 mExpandedHeight = getResources().getDimensionPixelSize(
256 R.dimen.status_bar_header_height_expanded);
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200257 mMultiUserExpandedMargin =
258 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_expanded_margin);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200259 mMultiUserCollapsedMargin =
260 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_collapsed_margin);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200261 mClockMarginBottomExpanded =
262 getResources().getDimensionPixelSize(R.dimen.clock_expanded_bottom_margin);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200263 updateClockCollapsedMargin();
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200264 mMultiUserSwitchWidthCollapsed =
265 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_collapsed);
266 mMultiUserSwitchWidthExpanded =
267 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_expanded);
268 mAvatarCollapsedScaleFactor =
269 getResources().getDimensionPixelSize(R.dimen.multi_user_avatar_collapsed_size)
270 / (float) mMultiUserAvatar.getLayoutParams().width;
Jorim Jaggifc69f782014-08-14 16:55:35 +0200271 mClockCollapsedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size);
272 mClockExpandedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size);
273 mClockCollapsedScaleFactor = (float) mClockCollapsedSize / (float) mClockExpandedSize;
274
Jorim Jaggid7daab72014-05-06 22:22:20 +0200275 }
276
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200277 public void setActivityStarter(ActivityStarter activityStarter) {
278 mActivityStarter = activityStarter;
279 }
280
Jorim Jaggi853b0702014-07-05 04:31:14 +0200281 public void setBatteryController(BatteryController batteryController) {
282 mBatteryController = batteryController;
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200283 ((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200284 }
285
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200286 public void setNextAlarmController(NextAlarmController nextAlarmController) {
287 mNextAlarmController = nextAlarmController;
288 }
289
Jorim Jaggid7daab72014-05-06 22:22:20 +0200290 public int getCollapsedHeight() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200291 return mCollapsedHeight;
Jorim Jaggid7daab72014-05-06 22:22:20 +0200292 }
293
294 public int getExpandedHeight() {
Jason Monkca4b5362015-10-07 10:43:29 -0400295 return mAllowExpand ? mExpandedHeight : mCollapsedHeight;
Jorim Jaggid7daab72014-05-06 22:22:20 +0200296 }
297
Jorim Jaggie65e3102014-07-01 22:00:50 +0200298 public void setListening(boolean listening) {
299 if (listening == mListening) {
300 return;
301 }
302 mListening = listening;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200303 updateListeners();
Jorim Jaggie65e3102014-07-01 22:00:50 +0200304 }
305
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200306 public void setExpanded(boolean expanded) {
Jason Monkca4b5362015-10-07 10:43:29 -0400307 if (!mAllowExpand) {
308 expanded = false;
309 }
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200310 boolean changed = expanded != mExpanded;
Jorim Jaggi9054d942014-05-09 22:47:28 +0200311 mExpanded = expanded;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200312 if (changed) {
John Spurlock7e6809a2014-08-06 16:03:14 -0400313 updateEverything();
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200314 }
Jorim Jaggi9054d942014-05-09 22:47:28 +0200315 }
316
John Spurlock7e6809a2014-08-06 16:03:14 -0400317 public void updateEverything() {
318 updateHeights();
319 updateVisibilities();
320 updateSystemIconsLayoutParams();
321 updateClickTargets();
322 updateMultiUserSwitch();
John Spurlock7e6809a2014-08-06 16:03:14 -0400323 updateClockScale();
324 updateAvatarScale();
325 updateClockLp();
326 requestCaptureValues();
327 }
328
Jorim Jaggi9054d942014-05-09 22:47:28 +0200329 private void updateHeights() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200330 int height = mExpanded ? mExpandedHeight : mCollapsedHeight;
Jorim Jaggi9054d942014-05-09 22:47:28 +0200331 ViewGroup.LayoutParams lp = getLayoutParams();
332 if (lp.height != height) {
333 lp.height = height;
Jorim Jaggid7daab72014-05-06 22:22:20 +0200334 setLayoutParams(lp);
Jorim Jaggi9054d942014-05-09 22:47:28 +0200335 }
Jorim Jaggie18c2cd2014-05-08 19:16:49 +0200336 }
337
Jorim Jaggi740beb52014-05-11 18:53:19 +0200338 private void updateVisibilities() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200339 mDateCollapsed.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE);
340 mDateExpanded.setVisibility(mExpanded && mAlarmShowing ? View.INVISIBLE : View.VISIBLE);
341 mAlarmStatus.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE);
Jason Monk431ad732015-07-16 08:58:15 -0400342 mSettingsContainer.setVisibility(mExpanded ? View.VISIBLE : View.INVISIBLE);
Selim Cineke32010a2014-08-20 23:50:41 +0200343 mQsDetailHeader.setVisibility(mExpanded && mShowingDetail? View.VISIBLE : View.INVISIBLE);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200344 if (mSignalCluster != null) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200345 updateSignalClusterDetachment();
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200346 }
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200347 mEmergencyCallsOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly ? VISIBLE : GONE);
348 mBatteryLevel.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
Jason Monk431ad732015-07-16 08:58:15 -0400349 mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
350 TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200351 }
352
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200353 private void updateSignalClusterDetachment() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200354 boolean detached = mExpanded;
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200355 if (detached != mSignalClusterDetached) {
356 if (detached) {
357 getOverlay().add(mSignalCluster);
358 } else {
Jorim Jaggi61d37f62014-07-30 17:26:55 +0200359 reattachSignalCluster();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200360 }
361 }
362 mSignalClusterDetached = detached;
363 }
364
Jorim Jaggi61d37f62014-07-30 17:26:55 +0200365 private void reattachSignalCluster() {
366 getOverlay().remove(mSignalCluster);
367 mSystemIcons.addView(mSignalCluster, 1);
368 }
369
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200370 private void updateSystemIconsLayoutParams() {
Jorim Jaggi605f1902014-06-25 05:23:42 +0200371 RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsSuperContainer.getLayoutParams();
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200372 int rule = mExpanded
Jason Monk431ad732015-07-16 08:58:15 -0400373 ? mSettingsContainer.getId()
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200374 : mMultiUserSwitch.getId();
375 if (rule != lp.getRules()[RelativeLayout.START_OF]) {
376 lp.addRule(RelativeLayout.START_OF, rule);
377 mSystemIconsSuperContainer.setLayoutParams(lp);
Adrian Roos59a61272014-06-06 19:07:24 +0200378 }
Jorim Jaggi740beb52014-05-11 18:53:19 +0200379 }
380
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200381 private void updateListeners() {
Jorim Jaggi853b0702014-07-05 04:31:14 +0200382 if (mListening) {
383 mBatteryController.addStateChangedCallback(this);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200384 mNextAlarmController.addStateChangedCallback(this);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200385 } else {
386 mBatteryController.removeStateChangedCallback(this);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200387 mNextAlarmController.removeStateChangedCallback(this);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200388 }
389 }
390
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200391 private void updateAvatarScale() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200392 if (mExpanded) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200393 mMultiUserAvatar.setScaleX(1f);
394 mMultiUserAvatar.setScaleY(1f);
Jorim Jaggi87d84d42014-07-28 12:14:48 +0200395 } else {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200396 mMultiUserAvatar.setScaleX(mAvatarCollapsedScaleFactor);
397 mMultiUserAvatar.setScaleY(mAvatarCollapsedScaleFactor);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200398 }
399 }
400
401 private void updateClockScale() {
Jorim Jaggifc69f782014-08-14 16:55:35 +0200402 mTime.setTextSize(TypedValue.COMPLEX_UNIT_PX, mExpanded
403 ? mClockExpandedSize
404 : mClockCollapsedSize);
405 mTime.setScaleX(1f);
406 mTime.setScaleY(1f);
Jorim Jaggi329fa242014-07-11 21:42:00 +0200407 updateAmPmTranslation();
408 }
409
410 private void updateAmPmTranslation() {
411 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
412 mAmPm.setTranslationX((rtl ? 1 : -1) * mTime.getWidth() * (1 - mTime.getScaleX()));
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200413 }
414
Jorim Jaggi853b0702014-07-05 04:31:14 +0200415 @Override
416 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
Elliott Hughes88d25512014-10-03 12:06:17 -0700417 String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
418 mBatteryLevel.setText(percentage);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200419 }
420
John Spurlock0ff62e02014-07-22 16:15:08 -0400421 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500422 public void onPowerSaveChanged(boolean isPowerSave) {
John Spurlock0ff62e02014-07-22 16:15:08 -0400423 // could not care less
424 }
425
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200426 @Override
Jose Lima235510e2014-08-13 12:50:01 -0700427 public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200428 mNextAlarm = nextAlarm;
429 if (nextAlarm != null) {
430 mAlarmStatus.setText(KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm));
431 }
432 mAlarmShowing = nextAlarm != null;
Jorim Jaggi11c071a2014-08-14 19:17:11 +0200433 updateEverything();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200434 requestCaptureValues();
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200435 }
436
Jorim Jaggi5d6957e2014-05-26 02:15:06 +0200437 private void updateClickTargets() {
Jorim Jaggi9d8ca0f2014-07-31 17:23:56 +0200438 mMultiUserSwitch.setClickable(mExpanded);
Selim Cineke32010a2014-08-20 23:50:41 +0200439 mMultiUserSwitch.setFocusable(mExpanded);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200440 mSystemIconsSuperContainer.setClickable(mExpanded);
Selim Cineke32010a2014-08-20 23:50:41 +0200441 mSystemIconsSuperContainer.setFocusable(mExpanded);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200442 mAlarmStatus.setClickable(mNextAlarm != null && mNextAlarm.getShowIntent() != null);
Jorim Jaggi5d6957e2014-05-26 02:15:06 +0200443 }
444
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200445 private void updateClockLp() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200446 int marginBottom = mExpanded
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200447 ? mClockMarginBottomExpanded
448 : mClockMarginBottomCollapsed;
449 LayoutParams lp = (LayoutParams) mDateGroup.getLayoutParams();
450 if (marginBottom != lp.bottomMargin) {
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200451 lp.bottomMargin = marginBottom;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200452 mDateGroup.setLayoutParams(lp);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200453 }
454 }
455
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200456 private void updateMultiUserSwitch() {
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200457 int marginEnd;
Jorim Jaggi87d84d42014-07-28 12:14:48 +0200458 int width;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200459 if (mExpanded) {
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200460 marginEnd = mMultiUserExpandedMargin;
Jorim Jaggi87d84d42014-07-28 12:14:48 +0200461 width = mMultiUserSwitchWidthExpanded;
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200462 } else {
463 marginEnd = mMultiUserCollapsedMargin;
Jorim Jaggi87d84d42014-07-28 12:14:48 +0200464 width = mMultiUserSwitchWidthCollapsed;
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200465 }
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200466 MarginLayoutParams lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams();
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200467 if (marginEnd != lp.getMarginEnd() || lp.width != width) {
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200468 lp.setMarginEnd(marginEnd);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200469 lp.width = width;
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200470 mMultiUserSwitch.setLayoutParams(lp);
471 }
472 }
473
Jorim Jaggi54045422014-07-03 18:30:40 +0200474 public void setExpansion(float t) {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200475 if (!mExpanded) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200476 t = 0f;
477 }
478 mCurrentT = t;
Jorim Jaggi54045422014-07-03 18:30:40 +0200479 float height = mCollapsedHeight + t * (mExpandedHeight - mCollapsedHeight);
Jorim Jaggid7daab72014-05-06 22:22:20 +0200480 if (height < mCollapsedHeight) {
481 height = mCollapsedHeight;
482 }
483 if (height > mExpandedHeight) {
484 height = mExpandedHeight;
485 }
Jorim Jaggidb3e6ed2014-05-12 20:18:47 +0200486 setClipping(height);
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200487 updateLayoutValues(t);
488 }
489
490 private void updateLayoutValues(float t) {
491 if (mCaptureValues) {
492 return;
493 }
494 mCurrentValues.interpoloate(mCollapsedValues, mExpandedValues, t);
495 applyLayoutValues(mCurrentValues);
Jorim Jaggidb3e6ed2014-05-12 20:18:47 +0200496 }
497
498 private void setClipping(float height) {
499 mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height);
500 setClipBounds(mClipBounds);
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700501 invalidateOutline();
Jorim Jaggid7daab72014-05-06 22:22:20 +0200502 }
503
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200504 public void setUserInfoController(UserInfoController userInfoController) {
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200505 userInfoController.addListener(new UserInfoController.OnUserInfoChangedListener() {
506 @Override
507 public void onUserInfoChanged(String name, Drawable picture) {
508 mMultiUserAvatar.setImageDrawable(picture);
509 }
510 });
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200511 }
512
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200513 @Override
514 public void onClick(View v) {
515 if (v == mSettingsButton) {
Jason Monk431ad732015-07-16 08:58:15 -0400516 if (mSettingsButton.isTunerClick()) {
517 if (TunerService.isTunerEnabled(mContext)) {
518 TunerService.showResetRequest(mContext, new Runnable() {
519 @Override
520 public void run() {
521 // Relaunch settings so that the tuner disappears.
522 startSettingsActivity();
523 }
524 });
525 } else {
526 Toast.makeText(getContext(), R.string.tuner_toast, Toast.LENGTH_LONG).show();
527 TunerService.setTunerEnabled(mContext, true);
528 }
529 }
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200530 startSettingsActivity();
Jorim Jaggi853b0702014-07-05 04:31:14 +0200531 } else if (v == mSystemIconsSuperContainer) {
532 startBatteryActivity();
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200533 } else if (v == mAlarmStatus && mNextAlarm != null) {
534 PendingIntent showIntent = mNextAlarm.getShowIntent();
Adrian Roos62692b22015-09-11 17:46:23 -0700535 if (showIntent != null) {
536 mActivityStarter.startPendingIntentDismissingKeyguard(showIntent);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200537 }
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200538 }
539 }
540
541 private void startSettingsActivity() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200542 mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200543 true /* dismissShade */);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200544 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400545
Jorim Jaggi853b0702014-07-05 04:31:14 +0200546 private void startBatteryActivity() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200547 mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY),
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200548 true /* dismissShade */);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200549 }
550
John Spurlockaf8d6c42014-05-07 17:49:08 -0400551 public void setQSPanel(QSPanel qsp) {
552 mQSPanel = qsp;
John Spurlock3e04cc82014-05-30 12:34:03 -0400553 if (mQSPanel != null) {
554 mQSPanel.setCallback(mQsPanelCallback);
555 }
Adrian Roos1ef80fe2014-07-14 22:53:54 +0200556 mMultiUserSwitch.setQsPanel(qsp);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400557 }
John Spurlock3e04cc82014-05-30 12:34:03 -0400558
Selim Cinekc0ce82d2014-06-10 13:21:15 +0200559 @Override
560 public boolean shouldDelayChildPressedState() {
561 return true;
562 }
Selim Cinek45f904a2014-06-11 11:42:53 +0200563
Jason Monkc6cc6262015-06-11 11:10:15 -0400564 @Override
565 public void setEmergencyCallsOnly(boolean show) {
Jorim Jaggi11c071a2014-08-14 19:17:11 +0200566 boolean changed = show != mShowEmergencyCallsOnly;
567 if (changed) {
568 mShowEmergencyCallsOnly = show;
569 if (mExpanded) {
570 updateEverything();
571 requestCaptureValues();
572 }
Adrian Roos59a61272014-06-06 19:07:24 +0200573 }
574 }
575
Jorim Jaggi266f6772014-07-10 19:13:17 +0200576 @Override
577 protected void dispatchSetPressed(boolean pressed) {
578 // We don't want that everything lights up when we click on the header, so block the request
579 // here.
580 }
581
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200582 private void captureLayoutValues(LayoutValues target) {
Jorim Jaggifc69f782014-08-14 16:55:35 +0200583 target.timeScale = mExpanded ? 1f : mClockCollapsedScaleFactor;
584 target.clockY = mClock.getBottom();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200585 target.dateY = mDateGroup.getTop();
586 target.emergencyCallsOnlyAlpha = getAlphaForVisibility(mEmergencyCallsOnly);
587 target.alarmStatusAlpha = getAlphaForVisibility(mAlarmStatus);
588 target.dateCollapsedAlpha = getAlphaForVisibility(mDateCollapsed);
589 target.dateExpandedAlpha = getAlphaForVisibility(mDateExpanded);
590 target.avatarScale = mMultiUserAvatar.getScaleX();
591 target.avatarX = mMultiUserSwitch.getLeft() + mMultiUserAvatar.getLeft();
592 target.avatarY = mMultiUserSwitch.getTop() + mMultiUserAvatar.getTop();
Jorim Jaggia8c97b32014-08-25 16:03:22 +0200593 if (getLayoutDirection() == LAYOUT_DIRECTION_LTR) {
594 target.batteryX = mSystemIconsSuperContainer.getLeft()
595 + mSystemIconsContainer.getRight();
596 } else {
597 target.batteryX = mSystemIconsSuperContainer.getLeft()
598 + mSystemIconsContainer.getLeft();
599 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200600 target.batteryY = mSystemIconsSuperContainer.getTop() + mSystemIconsContainer.getTop();
601 target.batteryLevelAlpha = getAlphaForVisibility(mBatteryLevel);
Jason Monk431ad732015-07-16 08:58:15 -0400602 target.settingsAlpha = getAlphaForVisibility(mSettingsContainer);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200603 target.settingsTranslation = mExpanded
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200604 ? 0
Jason Monk431ad732015-07-16 08:58:15 -0400605 : mMultiUserSwitch.getLeft() - mSettingsContainer.getLeft();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200606 target.signalClusterAlpha = mSignalClusterDetached ? 0f : 1f;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200607 target.settingsRotation = !mExpanded ? 90f : 0f;
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200608 }
John Spurlock07f6d3b2014-07-17 10:11:40 -0400609
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200610 private float getAlphaForVisibility(View v) {
611 return v == null || v.getVisibility() == View.VISIBLE ? 1f : 0f;
612 }
613
614 private void applyAlpha(View v, float alpha) {
Jorim Jaggi11c071a2014-08-14 19:17:11 +0200615 if (v == null || v.getVisibility() == View.GONE) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200616 return;
John Spurlock07f6d3b2014-07-17 10:11:40 -0400617 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200618 if (alpha == 0f) {
619 v.setVisibility(View.INVISIBLE);
620 } else {
621 v.setVisibility(View.VISIBLE);
622 v.setAlpha(alpha);
623 }
624 }
John Spurlock312b7922014-07-22 22:23:42 -0400625
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200626 private void applyLayoutValues(LayoutValues values) {
627 mTime.setScaleX(values.timeScale);
628 mTime.setScaleY(values.timeScale);
Jorim Jaggifc69f782014-08-14 16:55:35 +0200629 mClock.setY(values.clockY - mClock.getHeight());
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200630 mDateGroup.setY(values.dateY);
631 mAlarmStatus.setY(values.dateY - mAlarmStatus.getPaddingTop());
632 mMultiUserAvatar.setScaleX(values.avatarScale);
633 mMultiUserAvatar.setScaleY(values.avatarScale);
634 mMultiUserAvatar.setX(values.avatarX - mMultiUserSwitch.getLeft());
635 mMultiUserAvatar.setY(values.avatarY - mMultiUserSwitch.getTop());
Jorim Jaggia8c97b32014-08-25 16:03:22 +0200636 if (getLayoutDirection() == LAYOUT_DIRECTION_LTR) {
637 mSystemIconsSuperContainer.setX(values.batteryX - mSystemIconsContainer.getRight());
638 } else {
639 mSystemIconsSuperContainer.setX(values.batteryX - mSystemIconsContainer.getLeft());
640 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200641 mSystemIconsSuperContainer.setY(values.batteryY - mSystemIconsContainer.getTop());
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200642 if (mSignalCluster != null && mExpanded) {
Jorim Jaggia8c97b32014-08-25 16:03:22 +0200643 if (getLayoutDirection() == LAYOUT_DIRECTION_LTR) {
644 mSignalCluster.setX(mSystemIconsSuperContainer.getX()
645 - mSignalCluster.getWidth());
646 } else {
647 mSignalCluster.setX(mSystemIconsSuperContainer.getX()
648 + mSystemIconsSuperContainer.getWidth());
649 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200650 mSignalCluster.setY(
651 mSystemIconsSuperContainer.getY() + mSystemIconsSuperContainer.getHeight()/2
652 - mSignalCluster.getHeight()/2);
653 } else if (mSignalCluster != null) {
654 mSignalCluster.setTranslationX(0f);
655 mSignalCluster.setTranslationY(0f);
656 }
Jason Monk431ad732015-07-16 08:58:15 -0400657 if (!mSettingsButton.isAnimating()) {
658 mSettingsContainer.setTranslationY(mSystemIconsSuperContainer.getTranslationY());
659 mSettingsContainer.setTranslationX(values.settingsTranslation);
660 mSettingsButton.setRotation(values.settingsRotation);
661 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200662 applyAlpha(mEmergencyCallsOnly, values.emergencyCallsOnlyAlpha);
Jorim Jaggi2ba59792015-06-05 12:12:58 -0700663 if (!mShowingDetail && !mDetailTransitioning) {
Selim Cinekba5b3a02014-09-23 15:34:53 +0200664 // Otherwise it needs to stay invisible
665 applyAlpha(mAlarmStatus, values.alarmStatusAlpha);
666 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200667 applyAlpha(mDateCollapsed, values.dateCollapsedAlpha);
668 applyAlpha(mDateExpanded, values.dateExpandedAlpha);
669 applyAlpha(mBatteryLevel, values.batteryLevelAlpha);
Jason Monk431ad732015-07-16 08:58:15 -0400670 applyAlpha(mSettingsContainer, values.settingsAlpha);
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200671 applyAlpha(mSignalCluster, values.signalClusterAlpha);
Jorim Jaggifc69f782014-08-14 16:55:35 +0200672 if (!mExpanded) {
673 mTime.setScaleX(1f);
674 mTime.setScaleY(1f);
675 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200676 updateAmPmTranslation();
677 }
678
679 /**
680 * Captures all layout values (position, visibility) for a certain state. This is used for
681 * animations.
682 */
683 private static final class LayoutValues {
684
685 float dateExpandedAlpha;
686 float dateCollapsedAlpha;
687 float emergencyCallsOnlyAlpha;
688 float alarmStatusAlpha;
689 float timeScale = 1f;
690 float clockY;
691 float dateY;
692 float avatarScale;
693 float avatarX;
694 float avatarY;
695 float batteryX;
696 float batteryY;
697 float batteryLevelAlpha;
698 float settingsAlpha;
699 float settingsTranslation;
700 float signalClusterAlpha;
701 float settingsRotation;
702
703 public void interpoloate(LayoutValues v1, LayoutValues v2, float t) {
704 timeScale = v1.timeScale * (1 - t) + v2.timeScale * t;
705 clockY = v1.clockY * (1 - t) + v2.clockY * t;
706 dateY = v1.dateY * (1 - t) + v2.dateY * t;
707 avatarScale = v1.avatarScale * (1 - t) + v2.avatarScale * t;
708 avatarX = v1.avatarX * (1 - t) + v2.avatarX * t;
709 avatarY = v1.avatarY * (1 - t) + v2.avatarY * t;
710 batteryX = v1.batteryX * (1 - t) + v2.batteryX * t;
711 batteryY = v1.batteryY * (1 - t) + v2.batteryY * t;
712 settingsTranslation = v1.settingsTranslation * (1 - t) + v2.settingsTranslation * t;
713
714 float t1 = Math.max(0, t - 0.5f) * 2;
715 settingsRotation = v1.settingsRotation * (1 - t1) + v2.settingsRotation * t1;
716 emergencyCallsOnlyAlpha =
717 v1.emergencyCallsOnlyAlpha * (1 - t1) + v2.emergencyCallsOnlyAlpha * t1;
718
719 float t2 = Math.min(1, 2 * t);
720 signalClusterAlpha = v1.signalClusterAlpha * (1 - t2) + v2.signalClusterAlpha * t2;
721
722 float t3 = Math.max(0, t - 0.7f) / 0.3f;
723 batteryLevelAlpha = v1.batteryLevelAlpha * (1 - t3) + v2.batteryLevelAlpha * t3;
724 settingsAlpha = v1.settingsAlpha * (1 - t3) + v2.settingsAlpha * t3;
725 dateExpandedAlpha = v1.dateExpandedAlpha * (1 - t3) + v2.dateExpandedAlpha * t3;
726 dateCollapsedAlpha = v1.dateCollapsedAlpha * (1 - t3) + v2.dateCollapsedAlpha * t3;
727 alarmStatusAlpha = v1.alarmStatusAlpha * (1 - t3) + v2.alarmStatusAlpha * t3;
John Spurlock312b7922014-07-22 22:23:42 -0400728 }
729 }
John Spurlock07f6d3b2014-07-17 10:11:40 -0400730
John Spurlock7f8f22a2014-07-02 18:54:17 -0400731 private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
John Spurlock465cefa2014-08-16 10:39:33 -0400732 private boolean mScanState;
733
John Spurlock7f8f22a2014-07-02 18:54:17 -0400734 @Override
735 public void onToggleStateChanged(final boolean state) {
736 post(new Runnable() {
737 @Override
738 public void run() {
739 handleToggleStateChanged(state);
740 }
741 });
742 }
743
744 @Override
Jason Monk377e7ad2016-02-16 14:03:21 -0500745 public void onShowingDetail(final DetailAdapter detail, int x, int y) {
Jorim Jaggi2ba59792015-06-05 12:12:58 -0700746 mDetailTransitioning = true;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400747 post(new Runnable() {
748 @Override
749 public void run() {
750 handleShowingDetail(detail);
751 }
752 });
753 }
754
John Spurlock486b78e2014-07-07 08:37:56 -0400755 @Override
756 public void onScanStateChanged(final boolean state) {
757 post(new Runnable() {
758 @Override
759 public void run() {
760 handleScanStateChanged(state);
761 }
762 });
763 }
764
John Spurlock7f8f22a2014-07-02 18:54:17 -0400765 private void handleToggleStateChanged(boolean state) {
John Spurlock486b78e2014-07-07 08:37:56 -0400766 mQsDetailHeaderSwitch.setChecked(state);
767 }
768
769 private void handleScanStateChanged(boolean state) {
John Spurlock465cefa2014-08-16 10:39:33 -0400770 if (mScanState == state) return;
771 mScanState = state;
772 final Animatable anim = (Animatable) mQsDetailHeaderProgress.getDrawable();
773 if (state) {
774 mQsDetailHeaderProgress.animate().alpha(1f);
775 anim.start();
776 } else {
777 mQsDetailHeaderProgress.animate().alpha(0f);
778 anim.stop();
779 }
John Spurlock7f8f22a2014-07-02 18:54:17 -0400780 }
781
782 private void handleShowingDetail(final QSTile.DetailAdapter detail) {
783 final boolean showingDetail = detail != null;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200784 transition(mClock, !showingDetail);
785 transition(mDateGroup, !showingDetail);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200786 if (mAlarmShowing) {
787 transition(mAlarmStatus, !showingDetail);
788 }
John Spurlock7f8f22a2014-07-02 18:54:17 -0400789 transition(mQsDetailHeader, showingDetail);
Selim Cineke32010a2014-08-20 23:50:41 +0200790 mShowingDetail = showingDetail;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400791 if (showingDetail) {
Jason Monk6783bef2014-09-22 13:50:05 -0400792 mQsDetailHeaderTitle.setText(detail.getTitle());
John Spurlock7f8f22a2014-07-02 18:54:17 -0400793 final Boolean toggleState = detail.getToggleState();
794 if (toggleState == null) {
John Spurlock486b78e2014-07-07 08:37:56 -0400795 mQsDetailHeaderSwitch.setVisibility(INVISIBLE);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400796 mQsDetailHeader.setClickable(false);
797 } else {
John Spurlock486b78e2014-07-07 08:37:56 -0400798 mQsDetailHeaderSwitch.setVisibility(VISIBLE);
799 mQsDetailHeaderSwitch.setChecked(toggleState);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400800 mQsDetailHeader.setClickable(true);
801 mQsDetailHeader.setOnClickListener(new OnClickListener() {
802 @Override
803 public void onClick(View v) {
Jason Monkfc250622015-07-27 15:17:14 -0400804 boolean checked = !mQsDetailHeaderSwitch.isChecked();
805 mQsDetailHeaderSwitch.setChecked(checked);
806 detail.setToggleState(checked);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400807 }
808 });
809 }
810 } else {
811 mQsDetailHeader.setClickable(false);
812 }
813 }
814
815 private void transition(final View v, final boolean in) {
816 if (in) {
817 v.bringToFront();
Selim Cineke32010a2014-08-20 23:50:41 +0200818 v.setVisibility(VISIBLE);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400819 }
Jorim Jaggi43f43722014-12-10 22:17:44 +0100820 if (v.hasOverlappingRendering()) {
821 v.animate().withLayer();
822 }
Selim Cineke32010a2014-08-20 23:50:41 +0200823 v.animate()
824 .alpha(in ? 1 : 0)
Selim Cineke32010a2014-08-20 23:50:41 +0200825 .withEndAction(new Runnable() {
826 @Override
827 public void run() {
828 if (!in) {
829 v.setVisibility(INVISIBLE);
830 }
Jorim Jaggi2ba59792015-06-05 12:12:58 -0700831 mDetailTransitioning = false;
Selim Cineke32010a2014-08-20 23:50:41 +0200832 }
833 })
834 .start();
John Spurlock7f8f22a2014-07-02 18:54:17 -0400835 }
836 };
Jorim Jaggid7daab72014-05-06 22:22:20 +0200837}