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.animation.LayoutTransition; 20 import android.content.Context; 21 import android.content.res.Configuration; 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.view.animation.AnimationUtils; 28 import android.view.animation.Interpolator; 29 import android.widget.ImageView; 30 import android.widget.RelativeLayout; 31 import android.widget.TextView; 32 33 import com.android.systemui.BatteryMeterView; 34 import com.android.systemui.R; 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 39 /** 40 * The header group on Keyguard. 41 */ 42 public class KeyguardStatusBarView extends RelativeLayout 43 implements BatteryController.BatteryStateChangeCallback { 44 45 private boolean mBatteryCharging; 46 private boolean mKeyguardUserSwitcherShowing; 47 private boolean mBatteryListening; 48 49 private TextView mCarrierLabel; 50 private View mSystemIconsSuperContainer; 51 private MultiUserSwitch mMultiUserSwitch; 52 private ImageView mMultiUserAvatar; 53 private TextView mBatteryLevel; 54 55 private BatteryController mBatteryController; 56 private KeyguardUserSwitcher mKeyguardUserSwitcher; 57 58 private int mSystemIconsSwitcherHiddenExpandedMargin; 59 private Interpolator mFastOutSlowInInterpolator; 60 61 public KeyguardStatusBarView(Context context, AttributeSet attrs) { 62 super(context, attrs); 63 } 64 65 @Override 66 protected void onFinishInflate() { 67 super.onFinishInflate(); 68 mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container); 69 mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch); 70 mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar); 71 mBatteryLevel = (TextView) findViewById(R.id.battery_level); 72 mCarrierLabel = (TextView) findViewById(R.id.keyguard_carrier_text); 73 loadDimens(); 74 mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(), 75 android.R.interpolator.fast_out_slow_in); 76 updateUserSwitcher(); 77 } 78 79 @Override 80 protected void onConfigurationChanged(Configuration newConfig) { 81 super.onConfigurationChanged(newConfig); 82 83 // Respect font size setting. 84 mCarrierLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX, 85 getResources().getDimensionPixelSize( 86 com.android.internal.R.dimen.text_size_small_material)); 87 mBatteryLevel.setTextSize(TypedValue.COMPLEX_UNIT_PX, 88 getResources().getDimensionPixelSize(R.dimen.battery_level_text_size)); 89 } 90 91 private void loadDimens() { 92 mSystemIconsSwitcherHiddenExpandedMargin = getResources().getDimensionPixelSize( 93 R.dimen.system_icons_switcher_hidden_expanded_margin); 94 } 95 96 private void updateVisibilities() { 97 if (mMultiUserSwitch.getParent() != this && !mKeyguardUserSwitcherShowing) { 98 if (mMultiUserSwitch.getParent() != null) { 99 getOverlay().remove(mMultiUserSwitch); 100 } 101 addView(mMultiUserSwitch, 0); 102 } else if (mMultiUserSwitch.getParent() == this && mKeyguardUserSwitcherShowing) { 103 removeView(mMultiUserSwitch); 104 } 105 mBatteryLevel.setVisibility(mBatteryCharging ? View.VISIBLE : View.GONE); 106 } 107 108 private void updateSystemIconsLayoutParams() { 109 RelativeLayout.LayoutParams lp = 110 (LayoutParams) mSystemIconsSuperContainer.getLayoutParams(); 111 int marginEnd = mKeyguardUserSwitcherShowing ? mSystemIconsSwitcherHiddenExpandedMargin : 0; 112 if (marginEnd != lp.getMarginEnd()) { 113 lp.setMarginEnd(marginEnd); 114 mSystemIconsSuperContainer.setLayoutParams(lp); 115 } 116 } 117 118 public void setListening(boolean listening) { 119 if (listening == mBatteryListening) { 120 return; 121 } 122 mBatteryListening = listening; 123 if (mBatteryListening) { 124 mBatteryController.addStateChangedCallback(this); 125 } else { 126 mBatteryController.removeStateChangedCallback(this); 127 } 128 } 129 130 private void updateUserSwitcher() { 131 boolean keyguardSwitcherAvailable = mKeyguardUserSwitcher != null; 132 mMultiUserSwitch.setClickable(keyguardSwitcherAvailable); 133 mMultiUserSwitch.setFocusable(keyguardSwitcherAvailable); 134 mMultiUserSwitch.setKeyguardMode(keyguardSwitcherAvailable); 135 } 136 137 public void setBatteryController(BatteryController batteryController) { 138 mBatteryController = batteryController; 139 ((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController); 140 } 141 142 public void setUserInfoController(UserInfoController userInfoController) { 143 userInfoController.addListener(new UserInfoController.OnUserInfoChangedListener() { 144 @Override 145 public void onUserInfoChanged(String name, Drawable picture) { 146 mMultiUserAvatar.setImageDrawable(picture); 147 } 148 }); 149 } 150 151 @Override 152 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { 153 mBatteryLevel.setText(getResources().getString(R.string.battery_level_template, level)); 154 boolean changed = mBatteryCharging != charging; 155 mBatteryCharging = charging; 156 if (changed) { 157 updateVisibilities(); 158 } 159 } 160 161 @Override 162 public void onPowerSaveChanged() { 163 // could not care less 164 } 165 166 public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) { 167 mKeyguardUserSwitcher = keyguardUserSwitcher; 168 mMultiUserSwitch.setKeyguardUserSwitcher(keyguardUserSwitcher); 169 updateUserSwitcher(); 170 } 171 172 public void setKeyguardUserSwitcherShowing(boolean showing, boolean animate) { 173 mKeyguardUserSwitcherShowing = showing; 174 if (animate) { 175 animateNextLayoutChange(); 176 } 177 updateVisibilities(); 178 updateSystemIconsLayoutParams(); 179 } 180 181 private void animateNextLayoutChange() { 182 final int systemIconsCurrentX = mSystemIconsSuperContainer.getLeft(); 183 final boolean userSwitcherVisible = mMultiUserSwitch.getParent() == this; 184 getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 185 @Override 186 public boolean onPreDraw() { 187 getViewTreeObserver().removeOnPreDrawListener(this); 188 boolean userSwitcherHiding = userSwitcherVisible 189 && mMultiUserSwitch.getParent() != KeyguardStatusBarView.this; 190 mSystemIconsSuperContainer.setX(systemIconsCurrentX); 191 mSystemIconsSuperContainer.animate() 192 .translationX(0) 193 .setDuration(400) 194 .setStartDelay(userSwitcherHiding ? 300 : 0) 195 .setInterpolator(mFastOutSlowInInterpolator) 196 .start(); 197 if (userSwitcherHiding) { 198 getOverlay().add(mMultiUserSwitch); 199 mMultiUserSwitch.animate() 200 .alpha(0f) 201 .setDuration(300) 202 .setStartDelay(0) 203 .setInterpolator(PhoneStatusBar.ALPHA_OUT) 204 .withEndAction(new Runnable() { 205 @Override 206 public void run() { 207 mMultiUserSwitch.setAlpha(1f); 208 getOverlay().remove(mMultiUserSwitch); 209 } 210 }) 211 .start(); 212 213 } else { 214 mMultiUserSwitch.setAlpha(0f); 215 mMultiUserSwitch.animate() 216 .alpha(1f) 217 .setDuration(300) 218 .setStartDelay(200) 219 .setInterpolator(PhoneStatusBar.ALPHA_IN); 220 } 221 return true; 222 } 223 }); 224 225 } 226 227 @Override 228 public void setVisibility(int visibility) { 229 super.setVisibility(visibility); 230 if (visibility != View.VISIBLE) { 231 mSystemIconsSuperContainer.animate().cancel(); 232 mMultiUserSwitch.animate().cancel(); 233 mMultiUserSwitch.setAlpha(1f); 234 } 235 } 236 237 @Override 238 public boolean hasOverlappingRendering() { 239 return false; 240 } 241 } 242