StatusBarHeaderView.java revision 87d84d4d9533814e92bc7b1b0f91347a4982c1d0
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package com.android.systemui.statusbar.phone; 18 19import android.app.AlarmClockInfo; 20import android.app.PendingIntent; 21import android.content.Context; 22import android.content.Intent; 23import android.graphics.Outline; 24import android.graphics.Rect; 25import android.graphics.drawable.Drawable; 26import android.util.AttributeSet; 27import android.view.View; 28import android.view.ViewGroup; 29import android.view.ViewOutlineProvider; 30import android.widget.ImageView; 31import android.widget.LinearLayout; 32import android.widget.RelativeLayout; 33import android.widget.Switch; 34import android.widget.TextView; 35 36import com.android.keyguard.KeyguardStatusView; 37import com.android.systemui.R; 38import com.android.systemui.qs.QSPanel; 39import com.android.systemui.qs.QSTile; 40import com.android.systemui.statusbar.policy.BatteryController; 41import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; 42import com.android.systemui.statusbar.policy.NextAlarmController; 43import com.android.systemui.statusbar.policy.UserInfoController; 44 45/** 46 * The view to manage the header area in the expanded status bar. 47 */ 48public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener, 49 BatteryController.BatteryStateChangeCallback, NextAlarmController.NextAlarmChangeCallback { 50 51 private boolean mExpanded; 52 private boolean mListening; 53 private boolean mOverscrolled; 54 private boolean mKeyguardShowing; 55 private boolean mCharging; 56 57 private ViewGroup mSystemIconsContainer; 58 private View mSystemIconsSuperContainer; 59 private View mDateGroup; 60 private View mClock; 61 private View mTime; 62 private View mAmPm; 63 private View mKeyguardCarrierText; 64 private MultiUserSwitch mMultiUserSwitch; 65 private ImageView mMultiUserAvatar; 66 private View mDateCollapsed; 67 private View mDateExpanded; 68 private View mStatusIcons; 69 private View mSignalCluster; 70 private View mSettingsButton; 71 private View mQsDetailHeader; 72 private TextView mQsDetailHeaderTitle; 73 private Switch mQsDetailHeaderSwitch; 74 private View mEmergencyCallsOnly; 75 private TextView mBatteryLevel; 76 private TextView mAlarmStatus; 77 78 private boolean mShowEmergencyCallsOnly; 79 private boolean mKeyguardUserSwitcherShowing; 80 private boolean mAlarmShowing; 81 private AlarmClockInfo mNextAlarm; 82 83 private int mCollapsedHeight; 84 private int mExpandedHeight; 85 private int mKeyguardHeight; 86 87 private int mKeyguardWidth = ViewGroup.LayoutParams.MATCH_PARENT; 88 private int mNormalWidth; 89 private int mPadding; 90 private int mMultiUserExpandedMargin; 91 private int mMultiUserCollapsedMargin; 92 private int mMultiUserKeyguardMargin; 93 private int mSystemIconsSwitcherHiddenExpandedMargin; 94 private int mClockMarginBottomExpanded; 95 private int mClockMarginBottomCollapsed; 96 private int mMultiUserSwitchWidthCollapsed; 97 private int mMultiUserSwitchWidthExpanded; 98 private int mMultiUserSwitchWidthKeyguard; 99 private int mBatteryPaddingEnd; 100 private int mBatteryMarginExpanded; 101 private int mBatteryMarginKeyguard; 102 103 /** 104 * In collapsed QS, the clock and avatar are scaled down a bit post-layout to allow for a nice 105 * transition. These values determine that factor. 106 */ 107 private float mClockCollapsedScaleFactor; 108 private float mAvatarCollapsedScaleFactor; 109 private float mAvatarKeyguardScaleFactor; 110 111 private ActivityStarter mActivityStarter; 112 private BatteryController mBatteryController; 113 private NextAlarmController mNextAlarmController; 114 private QSPanel mQSPanel; 115 private KeyguardUserSwitcher mKeyguardUserSwitcher; 116 117 private final Rect mClipBounds = new Rect(); 118 private final StatusIconClipper mStatusIconClipper = new StatusIconClipper(); 119 120 public StatusBarHeaderView(Context context, AttributeSet attrs) { 121 super(context, attrs); 122 } 123 124 @Override 125 protected void onFinishInflate() { 126 super.onFinishInflate(); 127 mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container); 128 mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container); 129 mSystemIconsSuperContainer.setOnClickListener(this); 130 mDateGroup = findViewById(R.id.date_group); 131 mClock = findViewById(R.id.clock); 132 mTime = findViewById(R.id.time_view); 133 mAmPm = findViewById(R.id.am_pm_view); 134 mKeyguardCarrierText = findViewById(R.id.keyguard_carrier_text); 135 mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch); 136 mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar); 137 mDateCollapsed = findViewById(R.id.date_collapsed); 138 mDateExpanded = findViewById(R.id.date_expanded); 139 mSettingsButton = findViewById(R.id.settings_button); 140 mSettingsButton.setOnClickListener(this); 141 mQsDetailHeader = findViewById(R.id.qs_detail_header); 142 mQsDetailHeader.setAlpha(0); 143 mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title); 144 mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle); 145 mEmergencyCallsOnly = findViewById(R.id.header_emergency_calls_only); 146 mBatteryLevel = (TextView) findViewById(R.id.battery_level); 147 mAlarmStatus = (TextView) findViewById(R.id.alarm_status); 148 mAlarmStatus.setOnClickListener(this); 149 loadDimens(); 150 updateVisibilities(); 151 updateClockScale(); 152 updateAvatarScale(); 153 addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 154 @Override 155 public void onLayoutChange(View v, int left, int top, int right, 156 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 157 if ((right - left) != (oldRight - oldLeft)) { 158 // width changed, update clipping 159 setClipping(getHeight()); 160 } 161 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 162 mTime.setPivotX(rtl ? mTime.getWidth() : 0); 163 mTime.setPivotY(mTime.getBaseline()); 164 mAmPm.setPivotX(rtl ? mAmPm.getWidth() : 0); 165 mAmPm.setPivotY(mAmPm.getBaseline()); 166 updateAmPmTranslation(); 167 } 168 }); 169 setOutlineProvider(new ViewOutlineProvider() { 170 @Override 171 public void getOutline(View view, Outline outline) { 172 outline.setRect(mClipBounds); 173 } 174 }); 175 } 176 177 private void loadDimens() { 178 mCollapsedHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_header_height); 179 mExpandedHeight = getResources().getDimensionPixelSize( 180 R.dimen.status_bar_header_height_expanded); 181 mKeyguardHeight = getResources().getDimensionPixelSize( 182 R.dimen.status_bar_header_height_keyguard); 183 mNormalWidth = getLayoutParams().width; 184 mPadding = getResources().getDimensionPixelSize(R.dimen.notification_side_padding); 185 mMultiUserExpandedMargin = 186 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_expanded_margin); 187 mMultiUserCollapsedMargin = 188 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_collapsed_margin); 189 mMultiUserKeyguardMargin = 190 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_keyguard_margin); 191 mSystemIconsSwitcherHiddenExpandedMargin = getResources().getDimensionPixelSize( 192 R.dimen.system_icons_switcher_hidden_expanded_margin); 193 mClockMarginBottomExpanded = 194 getResources().getDimensionPixelSize(R.dimen.clock_expanded_bottom_margin); 195 mClockMarginBottomCollapsed = 196 getResources().getDimensionPixelSize(R.dimen.clock_collapsed_bottom_margin); 197 mMultiUserSwitchWidthCollapsed = 198 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_collapsed); 199 mMultiUserSwitchWidthExpanded = 200 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_expanded); 201 mMultiUserSwitchWidthKeyguard = 202 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_keyguard); 203 mAvatarCollapsedScaleFactor = 204 getResources().getDimensionPixelSize(R.dimen.multi_user_avatar_collapsed_size) 205 / (float) mMultiUserAvatar.getLayoutParams().width; 206 mAvatarKeyguardScaleFactor = 207 getResources().getDimensionPixelSize(R.dimen.multi_user_avatar_keyguard_size) 208 / (float) mMultiUserAvatar.getLayoutParams().width; 209 mClockCollapsedScaleFactor = 210 (float) getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size) 211 / (float) getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size); 212 mBatteryPaddingEnd = 213 getResources().getDimensionPixelSize(R.dimen.battery_level_padding_end); 214 mBatteryMarginExpanded = 215 getResources().getDimensionPixelSize(R.dimen.header_battery_margin_expanded); 216 mBatteryMarginKeyguard = 217 getResources().getDimensionPixelSize(R.dimen.header_battery_margin_keyguard); 218 } 219 220 public void setActivityStarter(ActivityStarter activityStarter) { 221 mActivityStarter = activityStarter; 222 } 223 224 public void setBatteryController(BatteryController batteryController) { 225 mBatteryController = batteryController; 226 } 227 228 public void setNextAlarmController(NextAlarmController nextAlarmController) { 229 mNextAlarmController = nextAlarmController; 230 } 231 232 public int getCollapsedHeight() { 233 return mKeyguardShowing ? mKeyguardHeight : mCollapsedHeight; 234 } 235 236 public int getExpandedHeight() { 237 return mExpandedHeight; 238 } 239 240 public void setListening(boolean listening) { 241 if (listening == mListening) { 242 return; 243 } 244 mListening = listening; 245 updateListeners(); 246 } 247 248 public void setExpanded(boolean expanded, boolean overscrolled) { 249 boolean changed = expanded != mExpanded; 250 boolean overscrollChanged = overscrolled != mOverscrolled; 251 mExpanded = expanded; 252 mOverscrolled = overscrolled; 253 if (changed || overscrollChanged) { 254 updateHeights(); 255 updateVisibilities(); 256 updateSystemIconsLayoutParams(); 257 updateZTranslation(); 258 updateClickTargets(); 259 updateWidth(); 260 updatePadding(); 261 updateMultiUserSwitch(); 262 if (mQSPanel != null) { 263 mQSPanel.setExpanded(expanded && !overscrolled); 264 } 265 updateClockScale(); 266 updateAvatarScale(); 267 updateClockLp(); 268 updateBatteryLevelPaddingEnd(); 269 updateBatteryLevelLp(); 270 mStatusIconClipper.update(); 271 } 272 } 273 274 private void updateHeights() { 275 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 276 int height; 277 if (mExpanded) { 278 height = mExpandedHeight; 279 } else if (onKeyguardAndCollapsed) { 280 height = mKeyguardHeight; 281 } else { 282 height = mCollapsedHeight; 283 } 284 ViewGroup.LayoutParams lp = getLayoutParams(); 285 if (lp.height != height) { 286 lp.height = height; 287 setLayoutParams(lp); 288 } 289 int systemIconsContainerHeight = onKeyguardAndCollapsed ? mKeyguardHeight : mCollapsedHeight; 290 lp = mSystemIconsSuperContainer.getLayoutParams(); 291 if (lp.height != systemIconsContainerHeight) { 292 lp.height = systemIconsContainerHeight; 293 mSystemIconsSuperContainer.setLayoutParams(lp); 294 } 295 lp = mMultiUserSwitch.getLayoutParams(); 296 if (lp.height != systemIconsContainerHeight) { 297 lp.height = systemIconsContainerHeight; 298 mMultiUserSwitch.setLayoutParams(lp); 299 } 300 } 301 302 private void updateWidth() { 303 int width = (mKeyguardShowing && !mExpanded) ? mKeyguardWidth : mNormalWidth; 304 ViewGroup.LayoutParams lp = getLayoutParams(); 305 if (width != lp.width) { 306 lp.width = width; 307 setLayoutParams(lp); 308 } 309 } 310 311 private void updateVisibilities() { 312 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 313 if (onKeyguardAndCollapsed) { 314 setBackground(null); 315 } else { 316 setBackgroundResource(R.drawable.notification_header_bg); 317 } 318 mDateGroup.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); 319 mClock.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); 320 mKeyguardCarrierText.setVisibility(onKeyguardAndCollapsed ? View.VISIBLE : View.GONE); 321 mDateCollapsed.setVisibility(mExpanded && !mOverscrolled && mAlarmShowing 322 ? View.VISIBLE : View.GONE); 323 mDateExpanded.setVisibility(mExpanded && !mOverscrolled && mAlarmShowing 324 ? View.GONE : View.VISIBLE); 325 mAlarmStatus.setVisibility(mExpanded && !mOverscrolled && mAlarmShowing 326 ? View.VISIBLE : View.GONE); 327 mSettingsButton.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE); 328 mQsDetailHeader.setVisibility(mExpanded ? View.VISIBLE : View.GONE); 329 if (mStatusIcons != null) { 330 mStatusIcons.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 331 } 332 if (mSignalCluster != null) { 333 mSignalCluster.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 334 } 335 mEmergencyCallsOnly.setVisibility(mExpanded && !mOverscrolled && mShowEmergencyCallsOnly 336 ? VISIBLE : GONE); 337 mMultiUserSwitch.setVisibility(mExpanded || !mKeyguardUserSwitcherShowing 338 ? VISIBLE : GONE); 339 mBatteryLevel.setVisibility(mKeyguardShowing && mCharging || mExpanded && !mOverscrolled 340 ? View.VISIBLE : View.GONE); 341 if (mExpanded && !mOverscrolled && mKeyguardUserSwitcherShowing) { 342 mKeyguardUserSwitcher.hide(); 343 } 344 } 345 346 private void updateSystemIconsLayoutParams() { 347 RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsSuperContainer.getLayoutParams(); 348 lp.addRule(RelativeLayout.START_OF, mExpanded && !mOverscrolled 349 ? mSettingsButton.getId() 350 : mMultiUserSwitch.getId()); 351 lp.removeRule(ALIGN_PARENT_START); 352 if (mMultiUserSwitch.getVisibility() == GONE) { 353 lp.setMarginEnd(mSystemIconsSwitcherHiddenExpandedMargin); 354 } else { 355 lp.setMarginEnd(0); 356 } 357 mSystemIconsSuperContainer.setLayoutParams(lp); 358 } 359 360 private void updateListeners() { 361 if (mListening) { 362 mBatteryController.addStateChangedCallback(this); 363 mNextAlarmController.addStateChangedCallback(this); 364 } else { 365 mBatteryController.removeStateChangedCallback(this); 366 mNextAlarmController.removeStateChangedCallback(this); 367 } 368 } 369 370 private void updateAvatarScale() { 371 if (mExpanded && !mOverscrolled) { 372 mMultiUserSwitch.setScaleX(1f); 373 mMultiUserSwitch.setScaleY(1f); 374 } else if (mKeyguardShowing) { 375 mMultiUserSwitch.setScaleX(mAvatarKeyguardScaleFactor); 376 mMultiUserSwitch.setScaleY(mAvatarKeyguardScaleFactor); 377 } else { 378 mMultiUserSwitch.setScaleX(mAvatarCollapsedScaleFactor); 379 mMultiUserSwitch.setScaleY(mAvatarCollapsedScaleFactor); 380 } 381 } 382 383 private void updateClockScale() { 384 mAmPm.setScaleX(mClockCollapsedScaleFactor); 385 mAmPm.setScaleY(mClockCollapsedScaleFactor); 386 if (!mExpanded || mOverscrolled) { 387 mTime.setScaleX(mClockCollapsedScaleFactor); 388 mTime.setScaleY(mClockCollapsedScaleFactor); 389 } else { 390 mTime.setScaleX(1f); 391 mTime.setScaleY(1f); 392 } 393 updateAmPmTranslation(); 394 } 395 396 private void updateAmPmTranslation() { 397 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 398 mAmPm.setTranslationX((rtl ? 1 : -1) * mTime.getWidth() * (1 - mTime.getScaleX())); 399 } 400 401 private void updateBatteryLevelPaddingEnd() { 402 mBatteryLevel.setPaddingRelative(0, 0, 403 mKeyguardShowing && !mExpanded ? 0 : mBatteryPaddingEnd, 0); 404 } 405 406 @Override 407 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { 408 mBatteryLevel.setText(getResources().getString(R.string.battery_level_template, level)); 409 boolean changed = mCharging != charging; 410 mCharging = charging; 411 if (changed) { 412 updateVisibilities(); 413 } 414 } 415 416 @Override 417 public void onPowerSaveChanged() { 418 // could not care less 419 } 420 421 @Override 422 public void onNextAlarmChanged(AlarmClockInfo nextAlarm) { 423 mNextAlarm = nextAlarm; 424 if (nextAlarm != null) { 425 mAlarmStatus.setText(KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm)); 426 } 427 mAlarmShowing = nextAlarm != null; 428 updateVisibilities(); 429 } 430 431 432 private void updateClickTargets() { 433 setClickable(!mKeyguardShowing || mExpanded); 434 435 boolean keyguardSwitcherAvailable = 436 mKeyguardUserSwitcher != null && mKeyguardShowing && !mExpanded; 437 mMultiUserSwitch.setClickable(mExpanded || keyguardSwitcherAvailable); 438 mMultiUserSwitch.setKeyguardMode(keyguardSwitcherAvailable); 439 mSystemIconsSuperContainer.setClickable(mExpanded); 440 mAlarmStatus.setClickable(mNextAlarm != null && mNextAlarm.getShowIntent() != null); 441 } 442 443 private void updateZTranslation() { 444 445 // If we are on the Keyguard, we need to set our z position to zero, so we don't get 446 // shadows. 447 if (mKeyguardShowing && !mExpanded) { 448 setZ(0); 449 } else { 450 setTranslationZ(0); 451 } 452 } 453 454 private void updatePadding() { 455 boolean padded = !mKeyguardShowing || mExpanded; 456 int padding = padded ? mPadding : 0; 457 setPaddingRelative(padding, 0, padding, 0); 458 } 459 460 private void updateClockLp() { 461 int marginBottom = mExpanded && !mOverscrolled 462 ? mClockMarginBottomExpanded 463 : mClockMarginBottomCollapsed; 464 LayoutParams lp = (LayoutParams) mDateGroup.getLayoutParams(); 465 if (marginBottom != lp.bottomMargin) { 466 lp.bottomMargin = marginBottom; 467 mDateGroup.setLayoutParams(lp); 468 } 469 } 470 471 private void updateMultiUserSwitch() { 472 int marginEnd; 473 int width; 474 if (mExpanded && !mOverscrolled) { 475 marginEnd = mMultiUserExpandedMargin; 476 width = mMultiUserSwitchWidthExpanded; 477 } else if (mKeyguardShowing) { 478 marginEnd = mMultiUserKeyguardMargin; 479 width = mMultiUserSwitchWidthKeyguard; 480 } else { 481 marginEnd = mMultiUserCollapsedMargin; 482 width = mMultiUserSwitchWidthCollapsed; 483 } 484 MarginLayoutParams lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams(); 485 if (marginEnd != lp.getMarginEnd() || lp.width != width) { 486 lp.setMarginEnd(marginEnd); 487 lp.width = width; 488 mMultiUserSwitch.setLayoutParams(lp); 489 } 490 } 491 492 private void updateBatteryLevelLp() { 493 int marginStart = mExpanded && !mOverscrolled 494 ? mBatteryMarginExpanded 495 : mBatteryMarginKeyguard; 496 MarginLayoutParams lp = (MarginLayoutParams) mBatteryLevel.getLayoutParams(); 497 if (marginStart != lp.getMarginStart()) { 498 lp.setMarginStart(marginStart); 499 mBatteryLevel.setLayoutParams(lp); 500 } 501 } 502 503 public void setExpansion(float t) { 504 float height = mCollapsedHeight + t * (mExpandedHeight - mCollapsedHeight); 505 if (height < mCollapsedHeight) { 506 height = mCollapsedHeight; 507 } 508 if (height > mExpandedHeight) { 509 height = mExpandedHeight; 510 } 511 setClipping(height); 512 } 513 514 private void setClipping(float height) { 515 mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height); 516 setClipBounds(mClipBounds); 517 invalidateOutline(); 518 } 519 520 public void attachSystemIcons(LinearLayout systemIcons) { 521 mSystemIconsContainer.addView(systemIcons); 522 mStatusIcons = systemIcons.findViewById(R.id.statusIcons); 523 mSignalCluster = systemIcons.findViewById(R.id.signal_cluster); 524 mSignalCluster.addOnLayoutChangeListener(mStatusIconClipper); 525 } 526 527 public void onSystemIconsDetached() { 528 if (mStatusIcons != null) { 529 mStatusIcons.setVisibility(View.VISIBLE); 530 } 531 if (mSignalCluster != null) { 532 mSignalCluster.removeOnLayoutChangeListener(mStatusIconClipper); 533 mSignalCluster.setVisibility(View.VISIBLE); 534 } 535 mStatusIcons = null; 536 mSignalCluster = null; 537 } 538 539 public void setKeyguardShowing(boolean keyguardShowing) { 540 mKeyguardShowing = keyguardShowing; 541 updateHeights(); 542 updateWidth(); 543 updateVisibilities(); 544 updateZTranslation(); 545 updatePadding(); 546 updateMultiUserSwitch(); 547 updateClickTargets(); 548 updateBatteryLevelPaddingEnd(); 549 updateAvatarScale(); 550 mStatusIconClipper.update(); 551 } 552 553 public void setUserInfoController(UserInfoController userInfoController) { 554 userInfoController.addListener(new UserInfoController.OnUserInfoChangedListener() { 555 @Override 556 public void onUserInfoChanged(String name, Drawable picture) { 557 mMultiUserAvatar.setImageDrawable(picture); 558 } 559 }); 560 } 561 562 @Override 563 public void onClick(View v) { 564 if (v == mSettingsButton) { 565 startSettingsActivity(); 566 } else if (v == mSystemIconsSuperContainer) { 567 startBatteryActivity(); 568 } else if (v == mAlarmStatus && mNextAlarm != null) { 569 PendingIntent showIntent = mNextAlarm.getShowIntent(); 570 if (showIntent != null && showIntent.isActivity()) { 571 mActivityStarter.startActivity(showIntent.getIntent()); 572 } 573 } 574 } 575 576 private void startSettingsActivity() { 577 mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)); 578 } 579 580 private void startBatteryActivity() { 581 mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY)); 582 } 583 584 public void setQSPanel(QSPanel qsp) { 585 mQSPanel = qsp; 586 if (mQSPanel != null) { 587 mQSPanel.setCallback(mQsPanelCallback); 588 } 589 mMultiUserSwitch.setQsPanel(qsp); 590 } 591 592 public void setKeyguarUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) { 593 mKeyguardUserSwitcher = keyguardUserSwitcher; 594 mMultiUserSwitch.setKeyguardUserSwitcher(keyguardUserSwitcher); 595 } 596 597 @Override 598 public boolean shouldDelayChildPressedState() { 599 return true; 600 } 601 602 public void setShowEmergencyCallsOnly(boolean show) { 603 mShowEmergencyCallsOnly = show; 604 if (mExpanded) { 605 updateVisibilities(); 606 } 607 } 608 609 public void setKeyguardUserSwitcherShowing(boolean showing) { 610 mKeyguardUserSwitcherShowing = showing; 611 updateVisibilities(); 612 updateSystemIconsLayoutParams(); 613 } 614 615 @Override 616 public boolean hasOverlappingRendering() { 617 return !mKeyguardShowing || mExpanded; 618 } 619 620 @Override 621 protected void dispatchSetPressed(boolean pressed) { 622 // We don't want that everything lights up when we click on the header, so block the request 623 // here. 624 } 625 626 private final class StatusIconClipper implements OnLayoutChangeListener { 627 private final Rect mClipBounds = new Rect(); 628 629 @Override 630 public void onLayoutChange(View v, int left, int top, int right, 631 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 632 // Hide the statusIcons in the header by clipping them. Can't touch visibility since 633 // they are mirrored to the real status bar. 634 mClipBounds.set(left, 0, mSystemIconsContainer.getWidth(), 635 mSystemIconsContainer.getHeight()); 636 update(); 637 } 638 639 public void update() { 640 final boolean collapsedKeyguard = mKeyguardShowing && !mExpanded; 641 final boolean expanded = mExpanded && !mOverscrolled; 642 mSystemIconsContainer.setClipBounds(collapsedKeyguard || expanded ? null : mClipBounds); 643 } 644 } 645 646 private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() { 647 @Override 648 public void onToggleStateChanged(final boolean state) { 649 post(new Runnable() { 650 @Override 651 public void run() { 652 handleToggleStateChanged(state); 653 } 654 }); 655 } 656 657 @Override 658 public void onShowingDetail(final QSTile.DetailAdapter detail) { 659 post(new Runnable() { 660 @Override 661 public void run() { 662 handleShowingDetail(detail); 663 } 664 }); 665 } 666 667 @Override 668 public void onScanStateChanged(final boolean state) { 669 post(new Runnable() { 670 @Override 671 public void run() { 672 handleScanStateChanged(state); 673 } 674 }); 675 } 676 677 private void handleToggleStateChanged(boolean state) { 678 mQsDetailHeaderSwitch.setChecked(state); 679 } 680 681 private void handleScanStateChanged(boolean state) { 682 // TODO - waiting on framework asset 683 } 684 685 private void handleShowingDetail(final QSTile.DetailAdapter detail) { 686 final boolean showingDetail = detail != null; 687 transition(mClock, !showingDetail); 688 transition(mDateGroup, !showingDetail); 689 transition(mQsDetailHeader, showingDetail); 690 if (showingDetail) { 691 mQsDetailHeaderTitle.setText(detail.getTitle()); 692 final Boolean toggleState = detail.getToggleState(); 693 if (toggleState == null) { 694 mQsDetailHeaderSwitch.setVisibility(INVISIBLE); 695 mQsDetailHeader.setClickable(false); 696 } else { 697 mQsDetailHeaderSwitch.setVisibility(VISIBLE); 698 mQsDetailHeaderSwitch.setChecked(toggleState); 699 mQsDetailHeader.setClickable(true); 700 mQsDetailHeader.setOnClickListener(new OnClickListener() { 701 @Override 702 public void onClick(View v) { 703 detail.setToggleState(!mQsDetailHeaderSwitch.isChecked()); 704 } 705 }); 706 } 707 } else { 708 mQsDetailHeader.setClickable(false); 709 } 710 } 711 712 private void transition(final View v, final boolean in) { 713 if (in) { 714 v.bringToFront(); 715 } 716 v.animate().alpha(in ? 1 : 0).withLayer().start(); 717 } 718 }; 719} 720