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 17 package com.android.systemui.statusbar.phone; 18 19 import android.content.Context; 20 import android.content.res.Configuration; 21 import android.content.res.Resources; 22 import android.graphics.drawable.Drawable; 23 import android.util.AttributeSet; 24 import android.util.TypedValue; 25 import android.view.View; 26 import android.view.ViewTreeObserver; 27 import android.widget.ImageView; 28 import android.widget.RelativeLayout; 29 import android.widget.TextView; 30 31 import com.android.systemui.BatteryMeterView; 32 import com.android.systemui.Interpolators; 33 import com.android.systemui.R; 34 import com.android.systemui.qs.QSPanel; 35 import com.android.systemui.statusbar.policy.BatteryController; 36 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; 37 import com.android.systemui.statusbar.policy.UserInfoController; 38 import com.android.systemui.statusbar.policy.UserSwitcherController; 39 40 import java.text.NumberFormat; 41 42 /** 43 * The header group on Keyguard. 44 */ 45 public class KeyguardStatusBarView extends RelativeLayout 46 implements BatteryController.BatteryStateChangeCallback { 47 48 private boolean mBatteryCharging; 49 private boolean mKeyguardUserSwitcherShowing; 50 private boolean mBatteryListening; 51 52 private TextView mCarrierLabel; 53 private View mSystemIconsSuperContainer; 54 private MultiUserSwitch mMultiUserSwitch; 55 private ImageView mMultiUserAvatar; 56 private TextView mBatteryLevel; 57 58 private BatteryController mBatteryController; 59 private KeyguardUserSwitcher mKeyguardUserSwitcher; 60 private UserSwitcherController mUserSwitcherController; 61 62 private int mSystemIconsSwitcherHiddenExpandedMargin; 63 private int mSystemIconsBaseMargin; 64 private View mSystemIconsContainer; 65 66 public KeyguardStatusBarView(Context context, AttributeSet attrs) { 67 super(context, attrs); 68 } 69 70 @Override 71 protected void onFinishInflate() { 72 super.onFinishInflate(); 73 mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container); 74 mSystemIconsContainer = findViewById(R.id.system_icons_container); 75 mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch); 76 mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar); 77 mBatteryLevel = (TextView) findViewById(R.id.battery_level); 78 mCarrierLabel = (TextView) findViewById(R.id.keyguard_carrier_text); 79 loadDimens(); 80 updateUserSwitcher(); 81 } 82 83 @Override 84 protected void onConfigurationChanged(Configuration newConfig) { 85 super.onConfigurationChanged(newConfig); 86 87 MarginLayoutParams lp = (MarginLayoutParams) mMultiUserAvatar.getLayoutParams(); 88 lp.width = lp.height = getResources().getDimensionPixelSize( 89 R.dimen.multi_user_avatar_keyguard_size); 90 mMultiUserAvatar.setLayoutParams(lp); 91 92 lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams(); 93 lp.width = getResources().getDimensionPixelSize( 94 R.dimen.multi_user_switch_width_keyguard); 95 lp.setMarginEnd(getResources().getDimensionPixelSize( 96 R.dimen.multi_user_switch_keyguard_margin)); 97 mMultiUserSwitch.setLayoutParams(lp); 98 99 lp = (MarginLayoutParams) mSystemIconsSuperContainer.getLayoutParams(); 100 lp.height = getResources().getDimensionPixelSize( 101 R.dimen.status_bar_header_height); 102 lp.setMarginStart(getResources().getDimensionPixelSize( 103 R.dimen.system_icons_super_container_margin_start)); 104 mSystemIconsSuperContainer.setLayoutParams(lp); 105 mSystemIconsSuperContainer.setPaddingRelative(mSystemIconsSuperContainer.getPaddingStart(), 106 mSystemIconsSuperContainer.getPaddingTop(), 107 getResources().getDimensionPixelSize(R.dimen.system_icons_keyguard_padding_end), 108 mSystemIconsSuperContainer.getPaddingBottom()); 109 110 lp = (MarginLayoutParams) mSystemIconsContainer.getLayoutParams(); 111 lp.height = getResources().getDimensionPixelSize( 112 R.dimen.status_bar_height); 113 mSystemIconsContainer.setLayoutParams(lp); 114 115 lp = (MarginLayoutParams) mBatteryLevel.getLayoutParams(); 116 lp.setMarginStart( 117 getResources().getDimensionPixelSize(R.dimen.header_battery_margin_keyguard)); 118 mBatteryLevel.setLayoutParams(lp); 119 mBatteryLevel.setPaddingRelative(mBatteryLevel.getPaddingStart(), 120 mBatteryLevel.getPaddingTop(), 121 getResources().getDimensionPixelSize(R.dimen.battery_level_padding_end), 122 mBatteryLevel.getPaddingBottom()); 123 mBatteryLevel.setTextSize(TypedValue.COMPLEX_UNIT_PX, 124 getResources().getDimensionPixelSize(R.dimen.battery_level_text_size)); 125 126 // Respect font size setting. 127 mCarrierLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX, 128 getResources().getDimensionPixelSize( 129 com.android.internal.R.dimen.text_size_small_material)); 130 lp = (MarginLayoutParams) mCarrierLabel.getLayoutParams(); 131 lp.setMarginStart( 132 getResources().getDimensionPixelSize(R.dimen.keyguard_carrier_text_margin)); 133 mCarrierLabel.setLayoutParams(lp); 134 135 lp = (MarginLayoutParams) getLayoutParams(); 136 lp.height = getResources().getDimensionPixelSize( 137 R.dimen.status_bar_header_height_keyguard); 138 setLayoutParams(lp); 139 } 140 141 private void loadDimens() { 142 Resources res = getResources(); 143 mSystemIconsSwitcherHiddenExpandedMargin = res.getDimensionPixelSize( 144 R.dimen.system_icons_switcher_hidden_expanded_margin); 145 mSystemIconsBaseMargin = res.getDimensionPixelSize( 146 R.dimen.system_icons_super_container_avatarless_margin_end); 147 } 148 149 private void updateVisibilities() { 150 if (mMultiUserSwitch.getParent() != this && !mKeyguardUserSwitcherShowing) { 151 if (mMultiUserSwitch.getParent() != null) { 152 getOverlay().remove(mMultiUserSwitch); 153 } 154 addView(mMultiUserSwitch, 0); 155 } else if (mMultiUserSwitch.getParent() == this && mKeyguardUserSwitcherShowing) { 156 removeView(mMultiUserSwitch); 157 } 158 if (mKeyguardUserSwitcher == null) { 159 // If we have no keyguard switcher, the screen width is under 600dp. In this case, 160 // we don't show the multi-user avatar unless there is more than 1 user on the device. 161 if (mUserSwitcherController != null 162 && mUserSwitcherController.getSwitchableUserCount() > 1) { 163 mMultiUserSwitch.setVisibility(View.VISIBLE); 164 } else { 165 mMultiUserSwitch.setVisibility(View.GONE); 166 } 167 } 168 mBatteryLevel.setVisibility(mBatteryCharging ? View.VISIBLE : View.GONE); 169 } 170 171 private void updateSystemIconsLayoutParams() { 172 RelativeLayout.LayoutParams lp = 173 (LayoutParams) mSystemIconsSuperContainer.getLayoutParams(); 174 // If the avatar icon is gone, we need to have some end margin to display the system icons 175 // correctly. 176 int baseMarginEnd = mMultiUserSwitch.getVisibility() == View.GONE 177 ? mSystemIconsBaseMargin 178 : 0; 179 int marginEnd = mKeyguardUserSwitcherShowing ? mSystemIconsSwitcherHiddenExpandedMargin : 180 baseMarginEnd; 181 if (marginEnd != lp.getMarginEnd()) { 182 lp.setMarginEnd(marginEnd); 183 mSystemIconsSuperContainer.setLayoutParams(lp); 184 } 185 } 186 187 public void setListening(boolean listening) { 188 if (listening == mBatteryListening) { 189 return; 190 } 191 mBatteryListening = listening; 192 if (mBatteryListening) { 193 mBatteryController.addStateChangedCallback(this); 194 } else { 195 mBatteryController.removeStateChangedCallback(this); 196 } 197 } 198 199 private void updateUserSwitcher() { 200 boolean keyguardSwitcherAvailable = mKeyguardUserSwitcher != null; 201 mMultiUserSwitch.setClickable(keyguardSwitcherAvailable); 202 mMultiUserSwitch.setFocusable(keyguardSwitcherAvailable); 203 mMultiUserSwitch.setKeyguardMode(keyguardSwitcherAvailable); 204 } 205 206 public void setBatteryController(BatteryController batteryController) { 207 mBatteryController = batteryController; 208 ((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController); 209 } 210 211 public void setUserSwitcherController(UserSwitcherController controller) { 212 mUserSwitcherController = controller; 213 mMultiUserSwitch.setUserSwitcherController(controller); 214 } 215 216 public void setUserInfoController(UserInfoController userInfoController) { 217 userInfoController.addListener(new UserInfoController.OnUserInfoChangedListener() { 218 @Override 219 public void onUserInfoChanged(String name, Drawable picture) { 220 mMultiUserAvatar.setImageDrawable(picture); 221 } 222 }); 223 } 224 225 public void setQSPanel(QSPanel qsp) { 226 mMultiUserSwitch.setQsPanel(qsp); 227 } 228 229 @Override 230 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { 231 String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0); 232 mBatteryLevel.setText(percentage); 233 boolean changed = mBatteryCharging != charging; 234 mBatteryCharging = charging; 235 if (changed) { 236 updateVisibilities(); 237 } 238 } 239 240 @Override 241 public void onPowerSaveChanged(boolean isPowerSave) { 242 // could not care less 243 } 244 245 public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) { 246 mKeyguardUserSwitcher = keyguardUserSwitcher; 247 mMultiUserSwitch.setKeyguardUserSwitcher(keyguardUserSwitcher); 248 updateUserSwitcher(); 249 } 250 251 public void setKeyguardUserSwitcherShowing(boolean showing, boolean animate) { 252 mKeyguardUserSwitcherShowing = showing; 253 if (animate) { 254 animateNextLayoutChange(); 255 } 256 updateVisibilities(); 257 updateSystemIconsLayoutParams(); 258 } 259 260 private void animateNextLayoutChange() { 261 final int systemIconsCurrentX = mSystemIconsSuperContainer.getLeft(); 262 final boolean userSwitcherVisible = mMultiUserSwitch.getParent() == this; 263 getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 264 @Override 265 public boolean onPreDraw() { 266 getViewTreeObserver().removeOnPreDrawListener(this); 267 boolean userSwitcherHiding = userSwitcherVisible 268 && mMultiUserSwitch.getParent() != KeyguardStatusBarView.this; 269 mSystemIconsSuperContainer.setX(systemIconsCurrentX); 270 mSystemIconsSuperContainer.animate() 271 .translationX(0) 272 .setDuration(400) 273 .setStartDelay(userSwitcherHiding ? 300 : 0) 274 .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) 275 .start(); 276 if (userSwitcherHiding) { 277 getOverlay().add(mMultiUserSwitch); 278 mMultiUserSwitch.animate() 279 .alpha(0f) 280 .setDuration(300) 281 .setStartDelay(0) 282 .setInterpolator(Interpolators.ALPHA_OUT) 283 .withEndAction(new Runnable() { 284 @Override 285 public void run() { 286 mMultiUserSwitch.setAlpha(1f); 287 getOverlay().remove(mMultiUserSwitch); 288 } 289 }) 290 .start(); 291 292 } else { 293 mMultiUserSwitch.setAlpha(0f); 294 mMultiUserSwitch.animate() 295 .alpha(1f) 296 .setDuration(300) 297 .setStartDelay(200) 298 .setInterpolator(Interpolators.ALPHA_IN); 299 } 300 return true; 301 } 302 }); 303 304 } 305 306 @Override 307 public void setVisibility(int visibility) { 308 super.setVisibility(visibility); 309 if (visibility != View.VISIBLE) { 310 mSystemIconsSuperContainer.animate().cancel(); 311 mSystemIconsSuperContainer.setTranslationX(0); 312 mMultiUserSwitch.animate().cancel(); 313 mMultiUserSwitch.setAlpha(1f); 314 } else { 315 updateVisibilities(); 316 updateSystemIconsLayoutParams(); 317 } 318 } 319 320 @Override 321 public boolean hasOverlappingRendering() { 322 return false; 323 } 324 } 325