StatusBarHeaderView.java revision 1ab15ca80bb70d4ffc48bce0bc36c3a1d58090d1
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
67    private int mCollapsedHeight;
68    private int mExpandedHeight;
69    private int mKeyguardHeight;
70
71    private int mKeyguardWidth = ViewGroup.LayoutParams.MATCH_PARENT;
72    private int mNormalWidth;
73
74    private ActivityStarter mActivityStarter;
75    private BrightnessController mBrightnessController;
76    private QSPanel mQSPanel;
77
78    private final Rect mClipBounds = new Rect();
79    private final Outline mOutline = new Outline();
80
81    public StatusBarHeaderView(Context context, AttributeSet attrs) {
82        super(context, attrs);
83    }
84
85    @Override
86    protected void onFinishInflate() {
87        super.onFinishInflate();
88        mBackground = findViewById(R.id.background);
89        mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container);
90        mDateTime = findViewById(R.id.datetime);
91        mKeyguardCarrierText = findViewById(R.id.keyguard_carrier_text);
92        mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
93        mDate = findViewById(R.id.date);
94        mSettingsButton = findViewById(R.id.settings_button);
95        mSettingsButton.setOnClickListener(this);
96        mBrightnessContainer = findViewById(R.id.brightness_container);
97        mBrightnessController = new BrightnessController(getContext(),
98                (ImageView) findViewById(R.id.brightness_icon),
99                (ToggleSlider) findViewById(R.id.brightness_slider));
100        mEmergencyCallsOnly = findViewById(R.id.header_emergency_calls_only);
101        mChargingInfo = (TextView) findViewById(R.id.header_charging_info);
102        loadDimens();
103        updateVisibilities();
104        addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
105            @Override
106            public void onLayoutChange(View v, int left, int top, int right,
107                    int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
108                if ((right - left) != (oldRight - oldLeft)) {
109                    // width changed, update clipping
110                    setClipping(getHeight());
111                }
112            }
113        });
114    }
115
116    private void loadDimens() {
117        mCollapsedHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_header_height);
118        mExpandedHeight = getResources().getDimensionPixelSize(
119                R.dimen.status_bar_header_height_expanded);
120        mKeyguardHeight = getResources().getDimensionPixelSize(
121                R.dimen.status_bar_header_height_keyguard);
122        mNormalWidth = getLayoutParams().width;
123    }
124
125    public void setActivityStarter(ActivityStarter activityStarter) {
126        mActivityStarter = activityStarter;
127    }
128
129    public int getCollapsedHeight() {
130        return mKeyguardShowing ? mKeyguardHeight : mCollapsedHeight;
131    }
132
133    public int getExpandedHeight() {
134        return mExpandedHeight;
135    }
136
137    public void setExpanded(boolean expanded, boolean overscrolled) {
138        boolean changed = expanded != mExpanded;
139        boolean overscrollChanged = overscrolled != mOverscrolled;
140        mExpanded = expanded;
141        mOverscrolled = overscrolled;
142        if (changed || overscrollChanged) {
143            updateHeights();
144            updateVisibilities();
145            updateSystemIconsLayoutParams();
146            updateBrightnessControllerState();
147            updateZTranslation();
148            updateClickTargets();
149            updateWidth();
150            if (mQSPanel != null) {
151                mQSPanel.setExpanded(expanded && !overscrolled);
152            }
153        }
154    }
155
156    private void updateHeights() {
157        boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded;
158        int height;
159        if (mExpanded) {
160            height = mExpandedHeight;
161        } else if (onKeyguardAndCollapsed) {
162            height = mKeyguardHeight;
163        } else {
164            height = mCollapsedHeight;
165        }
166        ViewGroup.LayoutParams lp = getLayoutParams();
167        if (lp.height != height) {
168            lp.height = height;
169            setLayoutParams(lp);
170        }
171        int systemIconsContainerHeight = onKeyguardAndCollapsed ? mKeyguardHeight : mCollapsedHeight;
172        lp = mSystemIconsContainer.getLayoutParams();
173        if (lp.height != systemIconsContainerHeight) {
174            lp.height = systemIconsContainerHeight;
175            mSystemIconsContainer.setLayoutParams(lp);
176        }
177        lp = mMultiUserSwitch.getLayoutParams();
178        if (lp.height != systemIconsContainerHeight) {
179            lp.height = systemIconsContainerHeight;
180            mMultiUserSwitch.setLayoutParams(lp);
181        }
182    }
183
184    private void updateWidth() {
185        int width = (mKeyguardShowing && !mExpanded) ? mKeyguardWidth : mNormalWidth;
186        ViewGroup.LayoutParams lp = getLayoutParams();
187        if (width != lp.width) {
188            lp.width = width;
189            setLayoutParams(lp);
190        }
191    }
192
193    private void updateVisibilities() {
194        boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded;
195        mBackground.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE);
196        mDateTime.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE);
197        mKeyguardCarrierText.setVisibility(onKeyguardAndCollapsed ? View.VISIBLE : View.GONE);
198        mDate.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
199        mSettingsButton.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE);
200        mBrightnessContainer.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
201        if (mStatusIcons != null) {
202            mStatusIcons.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE);
203        }
204        if (mSignalCluster != null) {
205            mSignalCluster.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE);
206        }
207        mEmergencyCallsOnly.setVisibility(mExpanded && !mOverscrolled && mShowEmergencyCallsOnly
208                ? VISIBLE : GONE);
209        mChargingInfo.setVisibility(mExpanded && !mOverscrolled && mShowChargingInfo
210                && !mShowEmergencyCallsOnly ? VISIBLE : GONE);
211    }
212
213    private void updateSystemIconsLayoutParams() {
214        RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsContainer.getLayoutParams();
215        boolean systemIconsAboveClock = mExpanded && !mOverscrolled
216                && mShowChargingInfo && !mShowEmergencyCallsOnly;
217        if (systemIconsAboveClock) {
218            lp.addRule(ALIGN_PARENT_START);
219            lp.removeRule(START_OF);
220        } else {
221            lp.addRule(RelativeLayout.START_OF, mExpanded
222                    ? mSettingsButton.getId()
223                    : mMultiUserSwitch.getId());
224            lp.removeRule(ALIGN_PARENT_START);
225        }
226
227        RelativeLayout.LayoutParams clockLp = (LayoutParams) mDateTime.getLayoutParams();
228        if (systemIconsAboveClock) {
229            clockLp.addRule(BELOW, mChargingInfo.getId());
230        } else {
231            clockLp.addRule(BELOW, mEmergencyCallsOnly.getId());
232        }
233    }
234
235    private void updateBrightnessControllerState() {
236        if (mExpanded) {
237            mBrightnessController.registerCallbacks();
238        } else {
239            mBrightnessController.unregisterCallbacks();
240        }
241    }
242
243    private void updateClickTargets() {
244        mDateTime.setClickable(mExpanded);
245        mMultiUserSwitch.setClickable(mExpanded);
246    }
247
248    private void updateZTranslation() {
249
250        // If we are on the Keyguard, we need to set our z position to zero, so we don't get
251        // shadows.
252        if (mKeyguardShowing && !mExpanded) {
253            setZ(0);
254        } else {
255            setTranslationZ(0);
256        }
257    }
258
259    public void setExpansion(float height) {
260        height = (height - mCollapsedHeight) * EXPANSION_RUBBERBAND_FACTOR + mCollapsedHeight;
261        if (height < mCollapsedHeight) {
262            height = mCollapsedHeight;
263        }
264        if (height > mExpandedHeight) {
265            height = mExpandedHeight;
266        }
267        setClipping(height);
268    }
269
270    private void setClipping(float height) {
271        mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height);
272        setClipBounds(mClipBounds);
273        mOutline.setRect(mClipBounds);
274        setOutline(mOutline);
275    }
276
277    public View getBackgroundView() {
278        return mBackground;
279    }
280
281    public void attachSystemIcons(LinearLayout systemIcons) {
282        mSystemIconsContainer.addView(systemIcons);
283        mStatusIcons = systemIcons.findViewById(R.id.statusIcons);
284        mSignalCluster = systemIcons.findViewById(R.id.signal_cluster);
285    }
286
287    public void onSystemIconsDetached() {
288        if (mStatusIcons != null) {
289            mStatusIcons.setVisibility(View.VISIBLE);
290        }
291        if (mSignalCluster != null) {
292            mSignalCluster.setVisibility(View.VISIBLE);
293        }
294        mStatusIcons = null;
295        mSignalCluster = null;
296    }
297
298    public void setKeyguardShowing(boolean keyguardShowing) {
299        mKeyguardShowing = keyguardShowing;
300        updateHeights();
301        updateWidth();
302        updateVisibilities();
303        updateZTranslation();
304    }
305
306    public void setUserInfoController(UserInfoController userInfoController) {
307        mMultiUserSwitch.setUserInfoController(userInfoController);
308    }
309
310    public void setOverlayParent(ViewGroup parent) {
311        mMultiUserSwitch.setOverlayParent(parent);
312    }
313
314    @Override
315    public void onClick(View v) {
316        if (v == mSettingsButton) {
317            startSettingsActivity();
318        }
319    }
320
321    private void startSettingsActivity() {
322        mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
323    }
324
325    public void setQSPanel(QSPanel qsp) {
326        mQSPanel = qsp;
327        if (mQSPanel != null) {
328            mQSPanel.setCallback(mQsPanelCallback);
329        }
330    }
331
332    private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
333        @Override
334        public void onShowingDetail(boolean showingDetail) {
335            mBrightnessContainer.animate().alpha(showingDetail ? 0 : 1).withLayer().start();
336        }
337    };
338
339    @Override
340    public boolean shouldDelayChildPressedState() {
341        return true;
342    }
343
344    public void setShowEmergencyCallsOnly(boolean show) {
345        mShowEmergencyCallsOnly = show;
346        if (mExpanded) {
347            updateVisibilities();
348            updateSystemIconsLayoutParams();
349        }
350    }
351
352    public void setShowChargingInfo(boolean showChargingInfo) {
353        mShowChargingInfo = showChargingInfo;
354        if (mExpanded) {
355            updateVisibilities();
356            updateSystemIconsLayoutParams();
357        }
358    }
359
360    public void setChargingInfo(CharSequence chargingInfo) {
361        mChargingInfo.setText(chargingInfo);
362    }
363}
364