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