StatusBarHeaderView.java revision 8ddb2da8759c29b3968b4d6bb9488f59a19f0ff2
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.content.Context; 20import android.content.Intent; 21import android.graphics.Outline; 22import android.graphics.Rect; 23import android.util.AttributeSet; 24import android.view.View; 25import android.view.ViewGroup; 26import android.widget.ImageView; 27import android.widget.LinearLayout; 28import android.widget.RelativeLayout; 29import android.widget.TextView; 30 31import com.android.systemui.R; 32import com.android.systemui.qs.QSPanel; 33import com.android.systemui.settings.BrightnessController; 34import com.android.systemui.settings.ToggleSlider; 35import com.android.systemui.statusbar.policy.UserInfoController; 36 37/** 38 * The view to manage the header area in the expanded status bar. 39 */ 40public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener { 41 42 /** 43 * How much the header expansion gets rubberbanded while expanding the panel. 44 */ 45 private static final float EXPANSION_RUBBERBAND_FACTOR = 0.35f; 46 47 private boolean mExpanded; 48 private boolean mOverscrolled; 49 private boolean mKeyguardShowing; 50 51 private View mBackground; 52 private ViewGroup mSystemIconsContainer; 53 private View mDateTime; 54 private View mKeyguardCarrierText; 55 private MultiUserSwitch mMultiUserSwitch; 56 private View mDate; 57 private View mStatusIcons; 58 private View mSignalCluster; 59 private View mSettingsButton; 60 private View mBrightnessContainer; 61 private View mEmergencyCallsOnly; 62 private TextView mChargingInfo; 63 64 private boolean mShowEmergencyCallsOnly; 65 private boolean mShowChargingInfo; 66 private boolean mKeyguardUserSwitcherShowing; 67 68 private int mCollapsedHeight; 69 private int mExpandedHeight; 70 private int mKeyguardHeight; 71 72 private int mKeyguardWidth = ViewGroup.LayoutParams.MATCH_PARENT; 73 private int mNormalWidth; 74 private int mPadding; 75 private int mMultiUserExpandedMargin; 76 private int mSystemIconsSwitcherHiddenExpandedMargin; 77 78 private ActivityStarter mActivityStarter; 79 private BrightnessController mBrightnessController; 80 private QSPanel mQSPanel; 81 82 private final Rect mClipBounds = new Rect(); 83 private final Outline mOutline = new Outline(); 84 85 public StatusBarHeaderView(Context context, AttributeSet attrs) { 86 super(context, attrs); 87 } 88 89 @Override 90 protected void onFinishInflate() { 91 super.onFinishInflate(); 92 mBackground = findViewById(R.id.background); 93 mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container); 94 mDateTime = findViewById(R.id.datetime); 95 mKeyguardCarrierText = findViewById(R.id.keyguard_carrier_text); 96 mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch); 97 mDate = findViewById(R.id.date); 98 mSettingsButton = findViewById(R.id.settings_button); 99 mSettingsButton.setOnClickListener(this); 100 mBrightnessContainer = findViewById(R.id.brightness_container); 101 mBrightnessController = new BrightnessController(getContext(), 102 (ImageView) findViewById(R.id.brightness_icon), 103 (ToggleSlider) findViewById(R.id.brightness_slider)); 104 mEmergencyCallsOnly = findViewById(R.id.header_emergency_calls_only); 105 mChargingInfo = (TextView) findViewById(R.id.header_charging_info); 106 loadDimens(); 107 updateVisibilities(); 108 addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 109 @Override 110 public void onLayoutChange(View v, int left, int top, int right, 111 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 112 if ((right - left) != (oldRight - oldLeft)) { 113 // width changed, update clipping 114 setClipping(getHeight()); 115 } 116 } 117 }); 118 } 119 120 private void loadDimens() { 121 mCollapsedHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_header_height); 122 mExpandedHeight = getResources().getDimensionPixelSize( 123 R.dimen.status_bar_header_height_expanded); 124 mKeyguardHeight = getResources().getDimensionPixelSize( 125 R.dimen.status_bar_header_height_keyguard); 126 mNormalWidth = getLayoutParams().width; 127 mPadding = getResources().getDimensionPixelSize(R.dimen.notification_side_padding); 128 mMultiUserExpandedMargin = 129 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_expanded_margin); 130 mSystemIconsSwitcherHiddenExpandedMargin = getResources().getDimensionPixelSize( 131 R.dimen.system_icons_switcher_hidden_expanded_margin); 132 } 133 134 public void setActivityStarter(ActivityStarter activityStarter) { 135 mActivityStarter = activityStarter; 136 } 137 138 public int getCollapsedHeight() { 139 return mKeyguardShowing ? mKeyguardHeight : mCollapsedHeight; 140 } 141 142 public int getExpandedHeight() { 143 return mExpandedHeight; 144 } 145 146 public void setExpanded(boolean expanded, boolean overscrolled) { 147 boolean changed = expanded != mExpanded; 148 boolean overscrollChanged = overscrolled != mOverscrolled; 149 mExpanded = expanded; 150 mOverscrolled = overscrolled; 151 if (changed || overscrollChanged) { 152 updateHeights(); 153 updateVisibilities(); 154 updateSystemIconsLayoutParams(); 155 updateBrightnessControllerState(); 156 updateZTranslation(); 157 updateClickTargets(); 158 updateWidth(); 159 updatePadding(); 160 updateMultiUserSwitch(); 161 if (mQSPanel != null) { 162 mQSPanel.setExpanded(expanded && !overscrolled); 163 } 164 } 165 } 166 167 private void updateHeights() { 168 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 169 int height; 170 if (mExpanded) { 171 height = mExpandedHeight; 172 } else if (onKeyguardAndCollapsed) { 173 height = mKeyguardHeight; 174 } else { 175 height = mCollapsedHeight; 176 } 177 ViewGroup.LayoutParams lp = getLayoutParams(); 178 if (lp.height != height) { 179 lp.height = height; 180 setLayoutParams(lp); 181 } 182 int systemIconsContainerHeight = onKeyguardAndCollapsed ? mKeyguardHeight : mCollapsedHeight; 183 lp = mSystemIconsContainer.getLayoutParams(); 184 if (lp.height != systemIconsContainerHeight) { 185 lp.height = systemIconsContainerHeight; 186 mSystemIconsContainer.setLayoutParams(lp); 187 } 188 lp = mMultiUserSwitch.getLayoutParams(); 189 if (lp.height != systemIconsContainerHeight) { 190 lp.height = systemIconsContainerHeight; 191 mMultiUserSwitch.setLayoutParams(lp); 192 } 193 } 194 195 private void updateWidth() { 196 int width = (mKeyguardShowing && !mExpanded) ? mKeyguardWidth : mNormalWidth; 197 ViewGroup.LayoutParams lp = getLayoutParams(); 198 if (width != lp.width) { 199 lp.width = width; 200 setLayoutParams(lp); 201 } 202 } 203 204 private void updateVisibilities() { 205 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 206 mBackground.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); 207 mDateTime.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); 208 mKeyguardCarrierText.setVisibility(onKeyguardAndCollapsed ? View.VISIBLE : View.GONE); 209 mDate.setVisibility(mExpanded ? View.VISIBLE : View.GONE); 210 mSettingsButton.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE); 211 mBrightnessContainer.setVisibility(mExpanded ? View.VISIBLE : View.GONE); 212 if (mStatusIcons != null) { 213 mStatusIcons.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 214 } 215 if (mSignalCluster != null) { 216 mSignalCluster.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 217 } 218 mEmergencyCallsOnly.setVisibility(mExpanded && !mOverscrolled && mShowEmergencyCallsOnly 219 ? VISIBLE : GONE); 220 mChargingInfo.setVisibility(mExpanded && !mOverscrolled && mShowChargingInfo 221 && !mShowEmergencyCallsOnly ? VISIBLE : GONE); 222 mMultiUserSwitch.setVisibility(mExpanded || !mKeyguardUserSwitcherShowing 223 ? VISIBLE : GONE); 224 } 225 226 private void updateSystemIconsLayoutParams() { 227 RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsContainer.getLayoutParams(); 228 boolean systemIconsAboveClock = mExpanded && !mOverscrolled 229 && mShowChargingInfo && !mShowEmergencyCallsOnly; 230 lp.setMarginEnd(0); 231 if (systemIconsAboveClock) { 232 lp.addRule(ALIGN_PARENT_START); 233 lp.removeRule(START_OF); 234 } else { 235 lp.addRule(RelativeLayout.START_OF, mExpanded 236 ? mSettingsButton.getId() 237 : mMultiUserSwitch.getId()); 238 lp.removeRule(ALIGN_PARENT_START); 239 if (mMultiUserSwitch.getVisibility() == GONE) { 240 lp.setMarginEnd(mSystemIconsSwitcherHiddenExpandedMargin); 241 } 242 } 243 mSystemIconsContainer.setLayoutParams(lp); 244 245 RelativeLayout.LayoutParams clockLp = (LayoutParams) mDateTime.getLayoutParams(); 246 if (systemIconsAboveClock) { 247 clockLp.addRule(BELOW, mChargingInfo.getId()); 248 } else { 249 clockLp.addRule(BELOW, mEmergencyCallsOnly.getId()); 250 } 251 mDateTime.setLayoutParams(clockLp); 252 } 253 254 private void updateBrightnessControllerState() { 255 if (mExpanded) { 256 mBrightnessController.registerCallbacks(); 257 } else { 258 mBrightnessController.unregisterCallbacks(); 259 } 260 } 261 262 private void updateClickTargets() { 263 mDateTime.setClickable(mExpanded); 264 mMultiUserSwitch.setClickable(mExpanded); 265 } 266 267 private void updateZTranslation() { 268 269 // If we are on the Keyguard, we need to set our z position to zero, so we don't get 270 // shadows. 271 if (mKeyguardShowing && !mExpanded) { 272 setZ(0); 273 } else { 274 setTranslationZ(0); 275 } 276 } 277 278 private void updatePadding() { 279 boolean padded = !mKeyguardShowing || mExpanded; 280 int padding = padded ? mPadding : 0; 281 setPaddingRelative(padding, 0, padding, 0); 282 } 283 284 private void updateMultiUserSwitch() { 285 int marginEnd = !mKeyguardShowing || mExpanded ? mMultiUserExpandedMargin : 0; 286 MarginLayoutParams lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams(); 287 if (marginEnd != lp.getMarginEnd()) { 288 lp.setMarginEnd(marginEnd); 289 mMultiUserSwitch.setLayoutParams(lp); 290 } 291 } 292 293 public void setExpansion(float height) { 294 height = (height - mCollapsedHeight) * EXPANSION_RUBBERBAND_FACTOR + mCollapsedHeight; 295 if (height < mCollapsedHeight) { 296 height = mCollapsedHeight; 297 } 298 if (height > mExpandedHeight) { 299 height = mExpandedHeight; 300 } 301 setClipping(height); 302 } 303 304 private void setClipping(float height) { 305 mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height); 306 setClipBounds(mClipBounds); 307 mOutline.setRect(mClipBounds); 308 setOutline(mOutline); 309 } 310 311 public View getBackgroundView() { 312 return mBackground; 313 } 314 315 public void attachSystemIcons(LinearLayout systemIcons) { 316 mSystemIconsContainer.addView(systemIcons); 317 mStatusIcons = systemIcons.findViewById(R.id.statusIcons); 318 mSignalCluster = systemIcons.findViewById(R.id.signal_cluster); 319 } 320 321 public void onSystemIconsDetached() { 322 if (mStatusIcons != null) { 323 mStatusIcons.setVisibility(View.VISIBLE); 324 } 325 if (mSignalCluster != null) { 326 mSignalCluster.setVisibility(View.VISIBLE); 327 } 328 mStatusIcons = null; 329 mSignalCluster = null; 330 } 331 332 public void setKeyguardShowing(boolean keyguardShowing) { 333 mKeyguardShowing = keyguardShowing; 334 updateHeights(); 335 updateWidth(); 336 updateVisibilities(); 337 updateZTranslation(); 338 updatePadding(); 339 updateMultiUserSwitch(); 340 } 341 342 public void setUserInfoController(UserInfoController userInfoController) { 343 mMultiUserSwitch.setUserInfoController(userInfoController); 344 } 345 346 public void setOverlayParent(ViewGroup parent) { 347 mMultiUserSwitch.setOverlayParent(parent); 348 } 349 350 @Override 351 public void onClick(View v) { 352 if (v == mSettingsButton) { 353 startSettingsActivity(); 354 } 355 } 356 357 private void startSettingsActivity() { 358 mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)); 359 } 360 361 public void setQSPanel(QSPanel qsp) { 362 mQSPanel = qsp; 363 if (mQSPanel != null) { 364 mQSPanel.setCallback(mQsPanelCallback); 365 } 366 } 367 368 private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() { 369 @Override 370 public void onShowingDetail(boolean showingDetail) { 371 mBrightnessContainer.animate().alpha(showingDetail ? 0 : 1).withLayer().start(); 372 } 373 }; 374 375 @Override 376 public boolean shouldDelayChildPressedState() { 377 return true; 378 } 379 380 public void setShowEmergencyCallsOnly(boolean show) { 381 mShowEmergencyCallsOnly = show; 382 if (mExpanded) { 383 updateVisibilities(); 384 updateSystemIconsLayoutParams(); 385 } 386 } 387 388 public void setShowChargingInfo(boolean showChargingInfo) { 389 mShowChargingInfo = showChargingInfo; 390 if (mExpanded) { 391 updateVisibilities(); 392 updateSystemIconsLayoutParams(); 393 } 394 } 395 396 public void setChargingInfo(CharSequence chargingInfo) { 397 mChargingInfo.setText(chargingInfo); 398 } 399 400 public void setKeyguardUserSwitcherShowing(boolean showing) { 401 // STOPSHIP: NOT CALLED PROPERLY WHEN GOING TO FULL SHADE AND RETURNING!?! 402 mKeyguardUserSwitcherShowing = showing; 403 updateVisibilities(); 404 updateSystemIconsLayoutParams(); 405 } 406} 407