blob: 3e3b16922f7a6052e54f640c88be7bdcf4fa00de [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 Jaggid7daab72014-05-06 22:22:20 +020042
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020043import com.android.keyguard.KeyguardStatusView;
Jorim Jaggi06d551a2014-09-02 15:55:57 +020044import com.android.systemui.BatteryMeterView;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020045import com.android.systemui.FontSizeUtils;
Jorim Jaggid7daab72014-05-06 22:22:20 +020046import com.android.systemui.R;
John Spurlockaf8d6c42014-05-07 17:49:08 -040047import com.android.systemui.qs.QSPanel;
John Spurlock7f8f22a2014-07-02 18:54:17 -040048import com.android.systemui.qs.QSTile;
Jason Monk377e7ad2016-02-16 14:03:21 -050049import com.android.systemui.qs.QSTile.DetailAdapter;
Jorim Jaggi853b0702014-07-05 04:31:14 +020050import com.android.systemui.statusbar.policy.BatteryController;
Jason Monkc6cc6262015-06-11 11:10:15 -040051import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020052import com.android.systemui.statusbar.policy.NextAlarmController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +020053import com.android.systemui.statusbar.policy.UserInfoController;
Jason Monk431ad732015-07-16 08:58:15 -040054import com.android.systemui.tuner.TunerService;
Jorim Jaggid7daab72014-05-06 22:22:20 +020055
Elliott Hughes88d25512014-10-03 12:06:17 -070056import java.text.NumberFormat;
57
Jorim Jaggid7daab72014-05-06 22:22:20 +020058/**
59 * The view to manage the header area in the expanded status bar.
60 */
Jason Monk0e1101d2015-10-07 13:06:09 -040061public class StatusBarHeaderView extends BaseStatusBarHeader implements View.OnClickListener,
Jason Monkc6cc6262015-06-11 11:10:15 -040062 BatteryController.BatteryStateChangeCallback, NextAlarmController.NextAlarmChangeCallback,
Jason Monkdeba7a42015-12-08 16:14:10 -050063 EmergencyListener {
Jorim Jaggif62f2bb2014-05-25 22:28:41 +020064
Jorim Jaggid7daab72014-05-06 22:22:20 +020065 private boolean mExpanded;
Jorim Jaggie65e3102014-07-01 22:00:50 +020066 private boolean mListening;
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +020067
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +020068 private ViewGroup mSystemIconsContainer;
Jorim Jaggi605f1902014-06-25 05:23:42 +020069 private View mSystemIconsSuperContainer;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020070 private View mDateGroup;
71 private View mClock;
Jorim Jaggifc69f782014-08-14 16:55:35 +020072 private TextView mTime;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020073 private TextView mAmPm;
Jorim Jaggi3d878be2014-05-10 03:22:32 +020074 private MultiUserSwitch mMultiUserSwitch;
Jorim Jaggi3f48f462014-07-08 16:53:29 +020075 private ImageView mMultiUserAvatar;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020076 private TextView mDateCollapsed;
77 private TextView mDateExpanded;
Jorim Jaggi90e0df22014-07-30 01:10:35 +020078 private LinearLayout mSystemIcons;
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +020079 private View mSignalCluster;
Jason Monk431ad732015-07-16 08:58:15 -040080 private SettingsButton mSettingsButton;
81 private View mSettingsContainer;
John Spurlock7f8f22a2014-07-02 18:54:17 -040082 private View mQsDetailHeader;
John Spurlock486b78e2014-07-07 08:37:56 -040083 private TextView mQsDetailHeaderTitle;
84 private Switch mQsDetailHeaderSwitch;
John Spurlock465cefa2014-08-16 10:39:33 -040085 private ImageView mQsDetailHeaderProgress;
Jorim Jaggie17c4b42014-08-26 17:27:31 +020086 private TextView mEmergencyCallsOnly;
Jorim Jaggi853b0702014-07-05 04:31:14 +020087 private TextView mBatteryLevel;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020088 private TextView mAlarmStatus;
Adrian Roos59a61272014-06-06 19:07:24 +020089
90 private boolean mShowEmergencyCallsOnly;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020091 private boolean mAlarmShowing;
Jose Lima235510e2014-08-13 12:50:01 -070092 private AlarmManager.AlarmClockInfo mNextAlarm;
Jorim Jaggid7daab72014-05-06 22:22:20 +020093
94 private int mCollapsedHeight;
95 private int mExpandedHeight;
Jorim Jaggi9054d942014-05-09 22:47:28 +020096
Jorim Jaggi129e7ac2014-06-10 22:03:48 +020097 private int mMultiUserExpandedMargin;
Jorim Jaggi3f48f462014-07-08 16:53:29 +020098 private int mMultiUserCollapsedMargin;
Jorim Jaggi4538027d2014-07-30 15:43:13 +020099
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200100 private int mClockMarginBottomExpanded;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200101 private int mClockMarginBottomCollapsed;
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200102 private int mMultiUserSwitchWidthCollapsed;
103 private int mMultiUserSwitchWidthExpanded;
104
Jorim Jaggifc69f782014-08-14 16:55:35 +0200105 private int mClockCollapsedSize;
106 private int mClockExpandedSize;
107
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200108 /**
109 * In collapsed QS, the clock and avatar are scaled down a bit post-layout to allow for a nice
110 * transition. These values determine that factor.
111 */
112 private float mClockCollapsedScaleFactor;
113 private float mAvatarCollapsedScaleFactor;
Jorim Jaggie18c2cd2014-05-08 19:16:49 +0200114
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200115 private ActivityStarter mActivityStarter;
Jorim Jaggi853b0702014-07-05 04:31:14 +0200116 private BatteryController mBatteryController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200117 private NextAlarmController mNextAlarmController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400118 private QSPanel mQSPanel;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200119
Jorim Jaggidb3e6ed2014-05-12 20:18:47 +0200120 private final Rect mClipBounds = new Rect();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200121
122 private boolean mCaptureValues;
123 private boolean mSignalClusterDetached;
124 private final LayoutValues mCollapsedValues = new LayoutValues();
125 private final LayoutValues mExpandedValues = new LayoutValues();
126 private final LayoutValues mCurrentValues = new LayoutValues();
127
128 private float mCurrentT;
Selim Cineke32010a2014-08-20 23:50:41 +0200129 private boolean mShowingDetail;
Jorim Jaggi2ba59792015-06-05 12:12:58 -0700130 private boolean mDetailTransitioning;
Jorim Jaggidb3e6ed2014-05-12 20:18:47 +0200131
Jason Monkca4b5362015-10-07 10:43:29 -0400132 private boolean mAllowExpand = true;
133
Jorim Jaggid7daab72014-05-06 22:22:20 +0200134 public StatusBarHeaderView(Context context, AttributeSet attrs) {
135 super(context, attrs);
136 }
137
138 @Override
139 protected void onFinishInflate() {
140 super.onFinishInflate();
Jorim Jaggi605f1902014-06-25 05:23:42 +0200141 mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container);
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200142 mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200143 mSystemIconsSuperContainer.setOnClickListener(this);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200144 mDateGroup = findViewById(R.id.date_group);
145 mClock = findViewById(R.id.clock);
Jorim Jaggifc69f782014-08-14 16:55:35 +0200146 mTime = (TextView) findViewById(R.id.time_view);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200147 mAmPm = (TextView) findViewById(R.id.am_pm_view);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200148 mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200149 mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200150 mDateCollapsed = (TextView) findViewById(R.id.date_collapsed);
151 mDateExpanded = (TextView) findViewById(R.id.date_expanded);
Jason Monk431ad732015-07-16 08:58:15 -0400152 mSettingsButton = (SettingsButton) findViewById(R.id.settings_button);
153 mSettingsContainer = findViewById(R.id.settings_button_container);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200154 mSettingsButton.setOnClickListener(this);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400155 mQsDetailHeader = findViewById(R.id.qs_detail_header);
156 mQsDetailHeader.setAlpha(0);
John Spurlock486b78e2014-07-07 08:37:56 -0400157 mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title);
158 mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle);
John Spurlock465cefa2014-08-16 10:39:33 -0400159 mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200160 mEmergencyCallsOnly = (TextView) findViewById(R.id.header_emergency_calls_only);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200161 mBatteryLevel = (TextView) findViewById(R.id.battery_level);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200162 mAlarmStatus = (TextView) findViewById(R.id.alarm_status);
163 mAlarmStatus.setOnClickListener(this);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200164 mSignalCluster = findViewById(R.id.signal_cluster);
165 mSystemIcons = (LinearLayout) findViewById(R.id.system_icons);
Jorim Jaggid7daab72014-05-06 22:22:20 +0200166 loadDimens();
John Spurlocke86ae852014-05-17 16:18:27 -0400167 updateVisibilities();
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200168 updateClockScale();
169 updateAvatarScale();
John Spurlockd9792b72014-05-21 23:50:13 -0400170 addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
171 @Override
172 public void onLayoutChange(View v, int left, int top, int right,
173 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
174 if ((right - left) != (oldRight - oldLeft)) {
175 // width changed, update clipping
176 setClipping(getHeight());
177 }
Jorim Jaggi329fa242014-07-11 21:42:00 +0200178 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
179 mTime.setPivotX(rtl ? mTime.getWidth() : 0);
180 mTime.setPivotY(mTime.getBaseline());
Jorim Jaggi329fa242014-07-11 21:42:00 +0200181 updateAmPmTranslation();
John Spurlockd9792b72014-05-21 23:50:13 -0400182 }
183 });
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700184 setOutlineProvider(new ViewOutlineProvider() {
185 @Override
Chris Craik31ba1922014-07-18 13:48:09 -0700186 public void getOutline(View view, Outline outline) {
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700187 outline.setRect(mClipBounds);
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700188 }
189 });
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200190 requestCaptureValues();
Jorim Jaggib7303a32015-08-19 16:51:36 -0700191
192 // RenderThread is doing more harm than good when touching the header (to expand quick
193 // settings), so disable it for this view
194 ((RippleDrawable) getBackground()).setForceSoftware(true);
195 ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
196 ((RippleDrawable) mSystemIconsSuperContainer.getBackground()).setForceSoftware(true);
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200197 }
198
199 @Override
200 protected void onLayout(boolean changed, int l, int t, int r, int b) {
201 super.onLayout(changed, l, t, r, b);
202 if (mCaptureValues) {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200203 if (mExpanded) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200204 captureLayoutValues(mExpandedValues);
205 } else {
206 captureLayoutValues(mCollapsedValues);
207 }
208 mCaptureValues = false;
209 updateLayoutValues(mCurrentT);
210 }
211 mAlarmStatus.setX(mDateGroup.getLeft() + mDateCollapsed.getRight());
212 }
213
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200214 @Override
215 protected void onConfigurationChanged(Configuration newConfig) {
216 super.onConfigurationChanged(newConfig);
217 FontSizeUtils.updateFontSize(mBatteryLevel, R.dimen.battery_level_text_size);
218 FontSizeUtils.updateFontSize(mEmergencyCallsOnly,
219 R.dimen.qs_emergency_calls_only_text_size);
220 FontSizeUtils.updateFontSize(mDateCollapsed, R.dimen.qs_date_collapsed_size);
221 FontSizeUtils.updateFontSize(mDateExpanded, R.dimen.qs_date_collapsed_size);
222 FontSizeUtils.updateFontSize(mAlarmStatus, R.dimen.qs_date_collapsed_size);
223 FontSizeUtils.updateFontSize(this, android.R.id.title, R.dimen.qs_detail_header_text_size);
224 FontSizeUtils.updateFontSize(this, android.R.id.toggle, R.dimen.qs_detail_header_text_size);
225 FontSizeUtils.updateFontSize(mAmPm, R.dimen.qs_time_collapsed_size);
226 FontSizeUtils.updateFontSize(this, R.id.empty_time_view, R.dimen.qs_time_expanded_size);
227
Adrian Roos54f934c2014-09-17 18:35:32 +0200228 mEmergencyCallsOnly.setText(com.android.internal.R.string.emergency_calls_only);
229
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200230 mClockCollapsedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size);
231 mClockExpandedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size);
232 mClockCollapsedScaleFactor = (float) mClockCollapsedSize / (float) mClockExpandedSize;
233
234 updateClockScale();
235 updateClockCollapsedMargin();
236 }
237
238 private void updateClockCollapsedMargin() {
239 Resources res = getResources();
240 int padding = res.getDimensionPixelSize(R.dimen.clock_collapsed_bottom_margin);
241 int largePadding = res.getDimensionPixelSize(
242 R.dimen.clock_collapsed_bottom_margin_large_text);
243 float largeFactor = (MathUtils.constrain(getResources().getConfiguration().fontScale, 1.0f,
244 FontSizeUtils.LARGE_TEXT_SCALE) - 1f) / (FontSizeUtils.LARGE_TEXT_SCALE - 1f);
245 mClockMarginBottomCollapsed = Math.round((1 - largeFactor) * padding + largeFactor * largePadding);
246 requestLayout();
247 }
248
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200249 private void requestCaptureValues() {
250 mCaptureValues = true;
251 requestLayout();
Jorim Jaggid7daab72014-05-06 22:22:20 +0200252 }
253
254 private void loadDimens() {
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200255 mCollapsedHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_header_height);
Jorim Jaggid7daab72014-05-06 22:22:20 +0200256 mExpandedHeight = getResources().getDimensionPixelSize(
257 R.dimen.status_bar_header_height_expanded);
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200258 mMultiUserExpandedMargin =
259 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_expanded_margin);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200260 mMultiUserCollapsedMargin =
261 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_collapsed_margin);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200262 mClockMarginBottomExpanded =
263 getResources().getDimensionPixelSize(R.dimen.clock_expanded_bottom_margin);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200264 updateClockCollapsedMargin();
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200265 mMultiUserSwitchWidthCollapsed =
266 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_collapsed);
267 mMultiUserSwitchWidthExpanded =
268 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_expanded);
269 mAvatarCollapsedScaleFactor =
270 getResources().getDimensionPixelSize(R.dimen.multi_user_avatar_collapsed_size)
271 / (float) mMultiUserAvatar.getLayoutParams().width;
Jorim Jaggifc69f782014-08-14 16:55:35 +0200272 mClockCollapsedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size);
273 mClockExpandedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size);
274 mClockCollapsedScaleFactor = (float) mClockCollapsedSize / (float) mClockExpandedSize;
275
Jorim Jaggid7daab72014-05-06 22:22:20 +0200276 }
277
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200278 public void setActivityStarter(ActivityStarter activityStarter) {
279 mActivityStarter = activityStarter;
280 }
281
Jorim Jaggi853b0702014-07-05 04:31:14 +0200282 public void setBatteryController(BatteryController batteryController) {
283 mBatteryController = batteryController;
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200284 ((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200285 }
286
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200287 public void setNextAlarmController(NextAlarmController nextAlarmController) {
288 mNextAlarmController = nextAlarmController;
289 }
290
Jorim Jaggid7daab72014-05-06 22:22:20 +0200291 public int getCollapsedHeight() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200292 return mCollapsedHeight;
Jorim Jaggid7daab72014-05-06 22:22:20 +0200293 }
294
295 public int getExpandedHeight() {
Jason Monkca4b5362015-10-07 10:43:29 -0400296 return mAllowExpand ? mExpandedHeight : mCollapsedHeight;
Jorim Jaggid7daab72014-05-06 22:22:20 +0200297 }
298
Jorim Jaggie65e3102014-07-01 22:00:50 +0200299 public void setListening(boolean listening) {
300 if (listening == mListening) {
301 return;
302 }
303 mListening = listening;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200304 updateListeners();
Jorim Jaggie65e3102014-07-01 22:00:50 +0200305 }
306
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200307 public void setExpanded(boolean expanded) {
Jason Monkca4b5362015-10-07 10:43:29 -0400308 if (!mAllowExpand) {
309 expanded = false;
310 }
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200311 boolean changed = expanded != mExpanded;
Jorim Jaggi9054d942014-05-09 22:47:28 +0200312 mExpanded = expanded;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200313 if (changed) {
John Spurlock7e6809a2014-08-06 16:03:14 -0400314 updateEverything();
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200315 }
Jorim Jaggi9054d942014-05-09 22:47:28 +0200316 }
317
John Spurlock7e6809a2014-08-06 16:03:14 -0400318 public void updateEverything() {
319 updateHeights();
320 updateVisibilities();
321 updateSystemIconsLayoutParams();
322 updateClickTargets();
323 updateMultiUserSwitch();
John Spurlock7e6809a2014-08-06 16:03:14 -0400324 updateClockScale();
325 updateAvatarScale();
326 updateClockLp();
327 requestCaptureValues();
328 }
329
Jorim Jaggi9054d942014-05-09 22:47:28 +0200330 private void updateHeights() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200331 int height = mExpanded ? mExpandedHeight : mCollapsedHeight;
Jorim Jaggi9054d942014-05-09 22:47:28 +0200332 ViewGroup.LayoutParams lp = getLayoutParams();
333 if (lp.height != height) {
334 lp.height = height;
Jorim Jaggid7daab72014-05-06 22:22:20 +0200335 setLayoutParams(lp);
Jorim Jaggi9054d942014-05-09 22:47:28 +0200336 }
Jorim Jaggie18c2cd2014-05-08 19:16:49 +0200337 }
338
Jorim Jaggi740beb52014-05-11 18:53:19 +0200339 private void updateVisibilities() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200340 mDateCollapsed.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE);
341 mDateExpanded.setVisibility(mExpanded && mAlarmShowing ? View.INVISIBLE : View.VISIBLE);
342 mAlarmStatus.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE);
Jason Monk431ad732015-07-16 08:58:15 -0400343 mSettingsContainer.setVisibility(mExpanded ? View.VISIBLE : View.INVISIBLE);
Selim Cineke32010a2014-08-20 23:50:41 +0200344 mQsDetailHeader.setVisibility(mExpanded && mShowingDetail? View.VISIBLE : View.INVISIBLE);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200345 if (mSignalCluster != null) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200346 updateSignalClusterDetachment();
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200347 }
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200348 mEmergencyCallsOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly ? VISIBLE : GONE);
349 mBatteryLevel.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
Jason Monk431ad732015-07-16 08:58:15 -0400350 mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
351 TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200352 }
353
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200354 private void updateSignalClusterDetachment() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200355 boolean detached = mExpanded;
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200356 if (detached != mSignalClusterDetached) {
357 if (detached) {
358 getOverlay().add(mSignalCluster);
359 } else {
Jorim Jaggi61d37f62014-07-30 17:26:55 +0200360 reattachSignalCluster();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200361 }
362 }
363 mSignalClusterDetached = detached;
364 }
365
Jorim Jaggi61d37f62014-07-30 17:26:55 +0200366 private void reattachSignalCluster() {
367 getOverlay().remove(mSignalCluster);
368 mSystemIcons.addView(mSignalCluster, 1);
369 }
370
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200371 private void updateSystemIconsLayoutParams() {
Jorim Jaggi605f1902014-06-25 05:23:42 +0200372 RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsSuperContainer.getLayoutParams();
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200373 int rule = mExpanded
Jason Monk431ad732015-07-16 08:58:15 -0400374 ? mSettingsContainer.getId()
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200375 : mMultiUserSwitch.getId();
376 if (rule != lp.getRules()[RelativeLayout.START_OF]) {
377 lp.addRule(RelativeLayout.START_OF, rule);
378 mSystemIconsSuperContainer.setLayoutParams(lp);
Adrian Roos59a61272014-06-06 19:07:24 +0200379 }
Jorim Jaggi740beb52014-05-11 18:53:19 +0200380 }
381
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200382 private void updateListeners() {
Jorim Jaggi853b0702014-07-05 04:31:14 +0200383 if (mListening) {
384 mBatteryController.addStateChangedCallback(this);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200385 mNextAlarmController.addStateChangedCallback(this);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200386 } else {
387 mBatteryController.removeStateChangedCallback(this);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200388 mNextAlarmController.removeStateChangedCallback(this);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200389 }
390 }
391
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200392 private void updateAvatarScale() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200393 if (mExpanded) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200394 mMultiUserAvatar.setScaleX(1f);
395 mMultiUserAvatar.setScaleY(1f);
Jorim Jaggi87d84d42014-07-28 12:14:48 +0200396 } else {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200397 mMultiUserAvatar.setScaleX(mAvatarCollapsedScaleFactor);
398 mMultiUserAvatar.setScaleY(mAvatarCollapsedScaleFactor);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200399 }
400 }
401
402 private void updateClockScale() {
Jorim Jaggifc69f782014-08-14 16:55:35 +0200403 mTime.setTextSize(TypedValue.COMPLEX_UNIT_PX, mExpanded
404 ? mClockExpandedSize
405 : mClockCollapsedSize);
406 mTime.setScaleX(1f);
407 mTime.setScaleY(1f);
Jorim Jaggi329fa242014-07-11 21:42:00 +0200408 updateAmPmTranslation();
409 }
410
411 private void updateAmPmTranslation() {
412 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
413 mAmPm.setTranslationX((rtl ? 1 : -1) * mTime.getWidth() * (1 - mTime.getScaleX()));
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200414 }
415
Jorim Jaggi853b0702014-07-05 04:31:14 +0200416 @Override
417 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
Elliott Hughes88d25512014-10-03 12:06:17 -0700418 String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
419 mBatteryLevel.setText(percentage);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200420 }
421
John Spurlock0ff62e02014-07-22 16:15:08 -0400422 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500423 public void onPowerSaveChanged(boolean isPowerSave) {
John Spurlock0ff62e02014-07-22 16:15:08 -0400424 // could not care less
425 }
426
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200427 @Override
Jose Lima235510e2014-08-13 12:50:01 -0700428 public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200429 mNextAlarm = nextAlarm;
430 if (nextAlarm != null) {
431 mAlarmStatus.setText(KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm));
432 }
433 mAlarmShowing = nextAlarm != null;
Jorim Jaggi11c071a2014-08-14 19:17:11 +0200434 updateEverything();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200435 requestCaptureValues();
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200436 }
437
Jorim Jaggi5d6957e2014-05-26 02:15:06 +0200438 private void updateClickTargets() {
Jorim Jaggi9d8ca0f2014-07-31 17:23:56 +0200439 mMultiUserSwitch.setClickable(mExpanded);
Selim Cineke32010a2014-08-20 23:50:41 +0200440 mMultiUserSwitch.setFocusable(mExpanded);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200441 mSystemIconsSuperContainer.setClickable(mExpanded);
Selim Cineke32010a2014-08-20 23:50:41 +0200442 mSystemIconsSuperContainer.setFocusable(mExpanded);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200443 mAlarmStatus.setClickable(mNextAlarm != null && mNextAlarm.getShowIntent() != null);
Jorim Jaggi5d6957e2014-05-26 02:15:06 +0200444 }
445
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200446 private void updateClockLp() {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200447 int marginBottom = mExpanded
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200448 ? mClockMarginBottomExpanded
449 : mClockMarginBottomCollapsed;
450 LayoutParams lp = (LayoutParams) mDateGroup.getLayoutParams();
451 if (marginBottom != lp.bottomMargin) {
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200452 lp.bottomMargin = marginBottom;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200453 mDateGroup.setLayoutParams(lp);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200454 }
455 }
456
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200457 private void updateMultiUserSwitch() {
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200458 int marginEnd;
Jorim Jaggi87d84d42014-07-28 12:14:48 +0200459 int width;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200460 if (mExpanded) {
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200461 marginEnd = mMultiUserExpandedMargin;
Jorim Jaggi87d84d42014-07-28 12:14:48 +0200462 width = mMultiUserSwitchWidthExpanded;
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200463 } else {
464 marginEnd = mMultiUserCollapsedMargin;
Jorim Jaggi87d84d42014-07-28 12:14:48 +0200465 width = mMultiUserSwitchWidthCollapsed;
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200466 }
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200467 MarginLayoutParams lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams();
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200468 if (marginEnd != lp.getMarginEnd() || lp.width != width) {
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200469 lp.setMarginEnd(marginEnd);
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200470 lp.width = width;
Jorim Jaggi129e7ac2014-06-10 22:03:48 +0200471 mMultiUserSwitch.setLayoutParams(lp);
472 }
473 }
474
Jorim Jaggi54045422014-07-03 18:30:40 +0200475 public void setExpansion(float t) {
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200476 if (!mExpanded) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200477 t = 0f;
478 }
479 mCurrentT = t;
Jorim Jaggi54045422014-07-03 18:30:40 +0200480 float height = mCollapsedHeight + t * (mExpandedHeight - mCollapsedHeight);
Jorim Jaggid7daab72014-05-06 22:22:20 +0200481 if (height < mCollapsedHeight) {
482 height = mCollapsedHeight;
483 }
484 if (height > mExpandedHeight) {
485 height = mExpandedHeight;
486 }
Jorim Jaggidb3e6ed2014-05-12 20:18:47 +0200487 setClipping(height);
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200488 updateLayoutValues(t);
489 }
490
491 private void updateLayoutValues(float t) {
492 if (mCaptureValues) {
493 return;
494 }
495 mCurrentValues.interpoloate(mCollapsedValues, mExpandedValues, t);
496 applyLayoutValues(mCurrentValues);
Jorim Jaggidb3e6ed2014-05-12 20:18:47 +0200497 }
498
499 private void setClipping(float height) {
500 mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height);
501 setClipBounds(mClipBounds);
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700502 invalidateOutline();
Jorim Jaggid7daab72014-05-06 22:22:20 +0200503 }
504
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200505 public void setUserInfoController(UserInfoController userInfoController) {
Jorim Jaggi3f48f462014-07-08 16:53:29 +0200506 userInfoController.addListener(new UserInfoController.OnUserInfoChangedListener() {
507 @Override
508 public void onUserInfoChanged(String name, Drawable picture) {
509 mMultiUserAvatar.setImageDrawable(picture);
510 }
511 });
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200512 }
513
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200514 @Override
515 public void onClick(View v) {
516 if (v == mSettingsButton) {
Jason Monk431ad732015-07-16 08:58:15 -0400517 if (mSettingsButton.isTunerClick()) {
518 if (TunerService.isTunerEnabled(mContext)) {
519 TunerService.showResetRequest(mContext, new Runnable() {
520 @Override
521 public void run() {
522 // Relaunch settings so that the tuner disappears.
523 startSettingsActivity();
524 }
525 });
526 } else {
527 Toast.makeText(getContext(), R.string.tuner_toast, Toast.LENGTH_LONG).show();
528 TunerService.setTunerEnabled(mContext, true);
529 }
530 }
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200531 startSettingsActivity();
Jorim Jaggi853b0702014-07-05 04:31:14 +0200532 } else if (v == mSystemIconsSuperContainer) {
533 startBatteryActivity();
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200534 } else if (v == mAlarmStatus && mNextAlarm != null) {
535 PendingIntent showIntent = mNextAlarm.getShowIntent();
Adrian Roos62692b22015-09-11 17:46:23 -0700536 if (showIntent != null) {
537 mActivityStarter.startPendingIntentDismissingKeyguard(showIntent);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200538 }
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200539 }
540 }
541
542 private void startSettingsActivity() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200543 mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200544 true /* dismissShade */);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200545 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400546
Jorim Jaggi853b0702014-07-05 04:31:14 +0200547 private void startBatteryActivity() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200548 mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY),
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200549 true /* dismissShade */);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200550 }
551
John Spurlockaf8d6c42014-05-07 17:49:08 -0400552 public void setQSPanel(QSPanel qsp) {
553 mQSPanel = qsp;
John Spurlock3e04cc82014-05-30 12:34:03 -0400554 if (mQSPanel != null) {
555 mQSPanel.setCallback(mQsPanelCallback);
556 }
Adrian Roos1ef80fe2014-07-14 22:53:54 +0200557 mMultiUserSwitch.setQsPanel(qsp);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400558 }
John Spurlock3e04cc82014-05-30 12:34:03 -0400559
Selim Cinekc0ce82d2014-06-10 13:21:15 +0200560 @Override
561 public boolean shouldDelayChildPressedState() {
562 return true;
563 }
Selim Cinek45f904a2014-06-11 11:42:53 +0200564
Jason Monkc6cc6262015-06-11 11:10:15 -0400565 @Override
566 public void setEmergencyCallsOnly(boolean show) {
Jorim Jaggi11c071a2014-08-14 19:17:11 +0200567 boolean changed = show != mShowEmergencyCallsOnly;
568 if (changed) {
569 mShowEmergencyCallsOnly = show;
570 if (mExpanded) {
571 updateEverything();
572 requestCaptureValues();
573 }
Adrian Roos59a61272014-06-06 19:07:24 +0200574 }
575 }
576
Jorim Jaggi266f6772014-07-10 19:13:17 +0200577 @Override
578 protected void dispatchSetPressed(boolean pressed) {
579 // We don't want that everything lights up when we click on the header, so block the request
580 // here.
581 }
582
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200583 private void captureLayoutValues(LayoutValues target) {
Jorim Jaggifc69f782014-08-14 16:55:35 +0200584 target.timeScale = mExpanded ? 1f : mClockCollapsedScaleFactor;
585 target.clockY = mClock.getBottom();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200586 target.dateY = mDateGroup.getTop();
587 target.emergencyCallsOnlyAlpha = getAlphaForVisibility(mEmergencyCallsOnly);
588 target.alarmStatusAlpha = getAlphaForVisibility(mAlarmStatus);
589 target.dateCollapsedAlpha = getAlphaForVisibility(mDateCollapsed);
590 target.dateExpandedAlpha = getAlphaForVisibility(mDateExpanded);
591 target.avatarScale = mMultiUserAvatar.getScaleX();
592 target.avatarX = mMultiUserSwitch.getLeft() + mMultiUserAvatar.getLeft();
593 target.avatarY = mMultiUserSwitch.getTop() + mMultiUserAvatar.getTop();
Jorim Jaggia8c97b32014-08-25 16:03:22 +0200594 if (getLayoutDirection() == LAYOUT_DIRECTION_LTR) {
595 target.batteryX = mSystemIconsSuperContainer.getLeft()
596 + mSystemIconsContainer.getRight();
597 } else {
598 target.batteryX = mSystemIconsSuperContainer.getLeft()
599 + mSystemIconsContainer.getLeft();
600 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200601 target.batteryY = mSystemIconsSuperContainer.getTop() + mSystemIconsContainer.getTop();
602 target.batteryLevelAlpha = getAlphaForVisibility(mBatteryLevel);
Jason Monk431ad732015-07-16 08:58:15 -0400603 target.settingsAlpha = getAlphaForVisibility(mSettingsContainer);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200604 target.settingsTranslation = mExpanded
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200605 ? 0
Jason Monk431ad732015-07-16 08:58:15 -0400606 : mMultiUserSwitch.getLeft() - mSettingsContainer.getLeft();
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200607 target.signalClusterAlpha = mSignalClusterDetached ? 0f : 1f;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200608 target.settingsRotation = !mExpanded ? 90f : 0f;
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200609 }
John Spurlock07f6d3b2014-07-17 10:11:40 -0400610
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200611 private float getAlphaForVisibility(View v) {
612 return v == null || v.getVisibility() == View.VISIBLE ? 1f : 0f;
613 }
614
615 private void applyAlpha(View v, float alpha) {
Jorim Jaggi11c071a2014-08-14 19:17:11 +0200616 if (v == null || v.getVisibility() == View.GONE) {
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200617 return;
John Spurlock07f6d3b2014-07-17 10:11:40 -0400618 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200619 if (alpha == 0f) {
620 v.setVisibility(View.INVISIBLE);
621 } else {
622 v.setVisibility(View.VISIBLE);
623 v.setAlpha(alpha);
624 }
625 }
John Spurlock312b7922014-07-22 22:23:42 -0400626
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200627 private void applyLayoutValues(LayoutValues values) {
628 mTime.setScaleX(values.timeScale);
629 mTime.setScaleY(values.timeScale);
Jorim Jaggifc69f782014-08-14 16:55:35 +0200630 mClock.setY(values.clockY - mClock.getHeight());
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200631 mDateGroup.setY(values.dateY);
632 mAlarmStatus.setY(values.dateY - mAlarmStatus.getPaddingTop());
633 mMultiUserAvatar.setScaleX(values.avatarScale);
634 mMultiUserAvatar.setScaleY(values.avatarScale);
635 mMultiUserAvatar.setX(values.avatarX - mMultiUserSwitch.getLeft());
636 mMultiUserAvatar.setY(values.avatarY - mMultiUserSwitch.getTop());
Jorim Jaggia8c97b32014-08-25 16:03:22 +0200637 if (getLayoutDirection() == LAYOUT_DIRECTION_LTR) {
638 mSystemIconsSuperContainer.setX(values.batteryX - mSystemIconsContainer.getRight());
639 } else {
640 mSystemIconsSuperContainer.setX(values.batteryX - mSystemIconsContainer.getLeft());
641 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200642 mSystemIconsSuperContainer.setY(values.batteryY - mSystemIconsContainer.getTop());
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200643 if (mSignalCluster != null && mExpanded) {
Jorim Jaggia8c97b32014-08-25 16:03:22 +0200644 if (getLayoutDirection() == LAYOUT_DIRECTION_LTR) {
645 mSignalCluster.setX(mSystemIconsSuperContainer.getX()
646 - mSignalCluster.getWidth());
647 } else {
648 mSignalCluster.setX(mSystemIconsSuperContainer.getX()
649 + mSystemIconsSuperContainer.getWidth());
650 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200651 mSignalCluster.setY(
652 mSystemIconsSuperContainer.getY() + mSystemIconsSuperContainer.getHeight()/2
653 - mSignalCluster.getHeight()/2);
654 } else if (mSignalCluster != null) {
655 mSignalCluster.setTranslationX(0f);
656 mSignalCluster.setTranslationY(0f);
657 }
Jason Monk431ad732015-07-16 08:58:15 -0400658 if (!mSettingsButton.isAnimating()) {
659 mSettingsContainer.setTranslationY(mSystemIconsSuperContainer.getTranslationY());
660 mSettingsContainer.setTranslationX(values.settingsTranslation);
661 mSettingsButton.setRotation(values.settingsRotation);
662 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200663 applyAlpha(mEmergencyCallsOnly, values.emergencyCallsOnlyAlpha);
Jorim Jaggi2ba59792015-06-05 12:12:58 -0700664 if (!mShowingDetail && !mDetailTransitioning) {
Selim Cinekba5b3a02014-09-23 15:34:53 +0200665 // Otherwise it needs to stay invisible
666 applyAlpha(mAlarmStatus, values.alarmStatusAlpha);
667 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200668 applyAlpha(mDateCollapsed, values.dateCollapsedAlpha);
669 applyAlpha(mDateExpanded, values.dateExpandedAlpha);
670 applyAlpha(mBatteryLevel, values.batteryLevelAlpha);
Jason Monk431ad732015-07-16 08:58:15 -0400671 applyAlpha(mSettingsContainer, values.settingsAlpha);
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200672 applyAlpha(mSignalCluster, values.signalClusterAlpha);
Jorim Jaggifc69f782014-08-14 16:55:35 +0200673 if (!mExpanded) {
674 mTime.setScaleX(1f);
675 mTime.setScaleY(1f);
676 }
Jorim Jaggi90e0df22014-07-30 01:10:35 +0200677 updateAmPmTranslation();
678 }
679
680 /**
681 * Captures all layout values (position, visibility) for a certain state. This is used for
682 * animations.
683 */
684 private static final class LayoutValues {
685
686 float dateExpandedAlpha;
687 float dateCollapsedAlpha;
688 float emergencyCallsOnlyAlpha;
689 float alarmStatusAlpha;
690 float timeScale = 1f;
691 float clockY;
692 float dateY;
693 float avatarScale;
694 float avatarX;
695 float avatarY;
696 float batteryX;
697 float batteryY;
698 float batteryLevelAlpha;
699 float settingsAlpha;
700 float settingsTranslation;
701 float signalClusterAlpha;
702 float settingsRotation;
703
704 public void interpoloate(LayoutValues v1, LayoutValues v2, float t) {
705 timeScale = v1.timeScale * (1 - t) + v2.timeScale * t;
706 clockY = v1.clockY * (1 - t) + v2.clockY * t;
707 dateY = v1.dateY * (1 - t) + v2.dateY * t;
708 avatarScale = v1.avatarScale * (1 - t) + v2.avatarScale * t;
709 avatarX = v1.avatarX * (1 - t) + v2.avatarX * t;
710 avatarY = v1.avatarY * (1 - t) + v2.avatarY * t;
711 batteryX = v1.batteryX * (1 - t) + v2.batteryX * t;
712 batteryY = v1.batteryY * (1 - t) + v2.batteryY * t;
713 settingsTranslation = v1.settingsTranslation * (1 - t) + v2.settingsTranslation * t;
714
715 float t1 = Math.max(0, t - 0.5f) * 2;
716 settingsRotation = v1.settingsRotation * (1 - t1) + v2.settingsRotation * t1;
717 emergencyCallsOnlyAlpha =
718 v1.emergencyCallsOnlyAlpha * (1 - t1) + v2.emergencyCallsOnlyAlpha * t1;
719
720 float t2 = Math.min(1, 2 * t);
721 signalClusterAlpha = v1.signalClusterAlpha * (1 - t2) + v2.signalClusterAlpha * t2;
722
723 float t3 = Math.max(0, t - 0.7f) / 0.3f;
724 batteryLevelAlpha = v1.batteryLevelAlpha * (1 - t3) + v2.batteryLevelAlpha * t3;
725 settingsAlpha = v1.settingsAlpha * (1 - t3) + v2.settingsAlpha * t3;
726 dateExpandedAlpha = v1.dateExpandedAlpha * (1 - t3) + v2.dateExpandedAlpha * t3;
727 dateCollapsedAlpha = v1.dateCollapsedAlpha * (1 - t3) + v2.dateCollapsedAlpha * t3;
728 alarmStatusAlpha = v1.alarmStatusAlpha * (1 - t3) + v2.alarmStatusAlpha * t3;
John Spurlock312b7922014-07-22 22:23:42 -0400729 }
730 }
John Spurlock07f6d3b2014-07-17 10:11:40 -0400731
John Spurlock7f8f22a2014-07-02 18:54:17 -0400732 private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
John Spurlock465cefa2014-08-16 10:39:33 -0400733 private boolean mScanState;
734
John Spurlock7f8f22a2014-07-02 18:54:17 -0400735 @Override
736 public void onToggleStateChanged(final boolean state) {
737 post(new Runnable() {
738 @Override
739 public void run() {
740 handleToggleStateChanged(state);
741 }
742 });
743 }
744
745 @Override
Jason Monk377e7ad2016-02-16 14:03:21 -0500746 public void onShowingDetail(final DetailAdapter detail, int x, int y) {
Jorim Jaggi2ba59792015-06-05 12:12:58 -0700747 mDetailTransitioning = true;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400748 post(new Runnable() {
749 @Override
750 public void run() {
751 handleShowingDetail(detail);
752 }
753 });
754 }
755
John Spurlock486b78e2014-07-07 08:37:56 -0400756 @Override
757 public void onScanStateChanged(final boolean state) {
758 post(new Runnable() {
759 @Override
760 public void run() {
761 handleScanStateChanged(state);
762 }
763 });
764 }
765
John Spurlock7f8f22a2014-07-02 18:54:17 -0400766 private void handleToggleStateChanged(boolean state) {
John Spurlock486b78e2014-07-07 08:37:56 -0400767 mQsDetailHeaderSwitch.setChecked(state);
768 }
769
770 private void handleScanStateChanged(boolean state) {
John Spurlock465cefa2014-08-16 10:39:33 -0400771 if (mScanState == state) return;
772 mScanState = state;
773 final Animatable anim = (Animatable) mQsDetailHeaderProgress.getDrawable();
774 if (state) {
775 mQsDetailHeaderProgress.animate().alpha(1f);
776 anim.start();
777 } else {
778 mQsDetailHeaderProgress.animate().alpha(0f);
779 anim.stop();
780 }
John Spurlock7f8f22a2014-07-02 18:54:17 -0400781 }
782
783 private void handleShowingDetail(final QSTile.DetailAdapter detail) {
784 final boolean showingDetail = detail != null;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200785 transition(mClock, !showingDetail);
786 transition(mDateGroup, !showingDetail);
Jorim Jaggie17c4b42014-08-26 17:27:31 +0200787 if (mAlarmShowing) {
788 transition(mAlarmStatus, !showingDetail);
789 }
John Spurlock7f8f22a2014-07-02 18:54:17 -0400790 transition(mQsDetailHeader, showingDetail);
Selim Cineke32010a2014-08-20 23:50:41 +0200791 mShowingDetail = showingDetail;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400792 if (showingDetail) {
Jason Monk6783bef2014-09-22 13:50:05 -0400793 mQsDetailHeaderTitle.setText(detail.getTitle());
John Spurlock7f8f22a2014-07-02 18:54:17 -0400794 final Boolean toggleState = detail.getToggleState();
795 if (toggleState == null) {
John Spurlock486b78e2014-07-07 08:37:56 -0400796 mQsDetailHeaderSwitch.setVisibility(INVISIBLE);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400797 mQsDetailHeader.setClickable(false);
798 } else {
John Spurlock486b78e2014-07-07 08:37:56 -0400799 mQsDetailHeaderSwitch.setVisibility(VISIBLE);
800 mQsDetailHeaderSwitch.setChecked(toggleState);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400801 mQsDetailHeader.setClickable(true);
802 mQsDetailHeader.setOnClickListener(new OnClickListener() {
803 @Override
804 public void onClick(View v) {
Jason Monkfc250622015-07-27 15:17:14 -0400805 boolean checked = !mQsDetailHeaderSwitch.isChecked();
806 mQsDetailHeaderSwitch.setChecked(checked);
807 detail.setToggleState(checked);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400808 }
809 });
810 }
811 } else {
812 mQsDetailHeader.setClickable(false);
813 }
814 }
815
816 private void transition(final View v, final boolean in) {
817 if (in) {
818 v.bringToFront();
Selim Cineke32010a2014-08-20 23:50:41 +0200819 v.setVisibility(VISIBLE);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400820 }
Jorim Jaggi43f43722014-12-10 22:17:44 +0100821 if (v.hasOverlappingRendering()) {
822 v.animate().withLayer();
823 }
Selim Cineke32010a2014-08-20 23:50:41 +0200824 v.animate()
825 .alpha(in ? 1 : 0)
Selim Cineke32010a2014-08-20 23:50:41 +0200826 .withEndAction(new Runnable() {
827 @Override
828 public void run() {
829 if (!in) {
830 v.setVisibility(INVISIBLE);
831 }
Jorim Jaggi2ba59792015-06-05 12:12:58 -0700832 mDetailTransitioning = false;
Selim Cineke32010a2014-08-20 23:50:41 +0200833 }
834 })
835 .start();
John Spurlock7f8f22a2014-07-02 18:54:17 -0400836 }
837 };
Jorim Jaggid7daab72014-05-06 22:22:20 +0200838}