StatusBarHeaderView.java revision 59a6127551650e7307fd6e6e1b72c1c2377fac80
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            if (mQSPanel != null) {
150                mQSPanel.setExpanded(expanded && !overscrolled);
151            }
152        }
153    }
154
155    private void updateHeights() {
156        boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded;
157        int height;
158        if (mExpanded) {
159            height = mExpandedHeight;
160        } else if (onKeyguardAndCollapsed) {
161            height = mKeyguardHeight;
162        } else {
163            height = mCollapsedHeight;
164        }
165        ViewGroup.LayoutParams lp = getLayoutParams();
166        if (lp.height != height) {
167            lp.height = height;
168            setLayoutParams(lp);
169        }
170        int systemIconsContainerHeight = onKeyguardAndCollapsed ? mKeyguardHeight : mCollapsedHeight;
171        lp = mSystemIconsContainer.getLayoutParams();
172        if (lp.height != systemIconsContainerHeight) {
173            lp.height = systemIconsContainerHeight;
174            mSystemIconsContainer.setLayoutParams(lp);
175        }
176        lp = mMultiUserSwitch.getLayoutParams();
177        if (lp.height != systemIconsContainerHeight) {
178            lp.height = systemIconsContainerHeight;
179            mMultiUserSwitch.setLayoutParams(lp);
180        }
181    }
182
183    private void updateWidth() {
184        int width = mKeyguardShowing ? mKeyguardWidth : mNormalWidth;
185        ViewGroup.LayoutParams lp = getLayoutParams();
186        if (width != lp.width) {
187            lp.width = width;
188            setLayoutParams(lp);
189        }
190    }
191
192    private void updateVisibilities() {
193        boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded;
194        mBackground.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE);
195        mDateTime.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE);
196        mKeyguardCarrierText.setVisibility(onKeyguardAndCollapsed ? View.VISIBLE : View.GONE);
197        mDate.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
198        mSettingsButton.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE);
199        mBrightnessContainer.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
200        if (mStatusIcons != null) {
201            mStatusIcons.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE);
202        }
203        if (mSignalCluster != null) {
204            mSignalCluster.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE);
205        }
206        mEmergencyCallsOnly.setVisibility(mExpanded && !mOverscrolled && mShowEmergencyCallsOnly
207                ? VISIBLE : GONE);
208        mChargingInfo.setVisibility(mExpanded && !mOverscrolled && mShowChargingInfo
209                && !mShowEmergencyCallsOnly ? VISIBLE : GONE);
210    }
211
212    private void updateSystemIconsLayoutParams() {
213        RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsContainer.getLayoutParams();
214        boolean systemIconsAboveClock = mExpanded && !mOverscrolled
215                && mShowChargingInfo && !mShowEmergencyCallsOnly;
216        if (systemIconsAboveClock) {
217            lp.addRule(ALIGN_PARENT_START);
218            lp.removeRule(START_OF);
219        } else {
220            lp.addRule(RelativeLayout.START_OF, mExpanded
221                    ? mSettingsButton.getId()
222                    : mMultiUserSwitch.getId());
223            lp.removeRule(ALIGN_PARENT_START);
224        }
225
226        RelativeLayout.LayoutParams clockLp = (LayoutParams) mDateTime.getLayoutParams();
227        if (systemIconsAboveClock) {
228            clockLp.addRule(BELOW, mChargingInfo.getId());
229        } else {
230            clockLp.addRule(BELOW, mEmergencyCallsOnly.getId());
231        }
232    }
233
234    private void updateBrightnessControllerState() {
235        if (mExpanded) {
236            mBrightnessController.registerCallbacks();
237        } else {
238            mBrightnessController.unregisterCallbacks();
239        }
240    }
241
242    private void updateClickTargets() {
243        mDateTime.setClickable(mExpanded);
244        mMultiUserSwitch.setClickable(mExpanded);
245    }
246
247    private void updateZTranslation() {
248
249        // If we are on the Keyguard, we need to set our z position to zero, so we don't get
250        // shadows.
251        if (mKeyguardShowing && !mExpanded) {
252            setZ(0);
253        } else {
254            setTranslationZ(0);
255        }
256    }
257
258    public void setExpansion(float height) {
259        height = (height - mCollapsedHeight) * EXPANSION_RUBBERBAND_FACTOR + mCollapsedHeight;
260        if (height < mCollapsedHeight) {
261            height = mCollapsedHeight;
262        }
263        if (height > mExpandedHeight) {
264            height = mExpandedHeight;
265        }
266        setClipping(height);
267    }
268
269    private void setClipping(float height) {
270        mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height);
271        setClipBounds(mClipBounds);
272        mOutline.setRect(mClipBounds);
273        setOutline(mOutline);
274    }
275
276    public View getBackgroundView() {
277        return mBackground;
278    }
279
280    public void attachSystemIcons(LinearLayout systemIcons) {
281        mSystemIconsContainer.addView(systemIcons);
282        mStatusIcons = systemIcons.findViewById(R.id.statusIcons);
283        mSignalCluster = systemIcons.findViewById(R.id.signal_cluster);
284    }
285
286    public void onSystemIconsDetached() {
287        if (mStatusIcons != null) {
288            mStatusIcons.setVisibility(View.VISIBLE);
289        }
290        if (mSignalCluster != null) {
291            mSignalCluster.setVisibility(View.VISIBLE);
292        }
293        mStatusIcons = null;
294        mSignalCluster = null;
295    }
296
297    public void setKeyguardShowing(boolean keyguardShowing) {
298        mKeyguardShowing = keyguardShowing;
299        updateHeights();
300        updateWidth();
301        updateVisibilities();
302        updateZTranslation();
303    }
304
305    public void setUserInfoController(UserInfoController userInfoController) {
306        mMultiUserSwitch.setUserInfoController(userInfoController);
307    }
308
309    public void setOverlayParent(ViewGroup parent) {
310        mMultiUserSwitch.setOverlayParent(parent);
311    }
312
313    @Override
314    public void onClick(View v) {
315        if (v == mSettingsButton) {
316            startSettingsActivity();
317        }
318    }
319
320    private void startSettingsActivity() {
321        mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
322    }
323
324    public void setQSPanel(QSPanel qsp) {
325        mQSPanel = qsp;
326        if (mQSPanel != null) {
327            mQSPanel.setCallback(mQsPanelCallback);
328        }
329    }
330
331    private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
332        @Override
333        public void onShowingDetail(boolean showingDetail) {
334            mBrightnessContainer.animate().alpha(showingDetail ? 0 : 1).withLayer().start();
335        }
336    };
337
338    public void setShowEmergencyCallsOnly(boolean show) {
339        mShowEmergencyCallsOnly = show;
340        if (mExpanded) {
341            updateVisibilities();
342            updateSystemIconsLayoutParams();
343        }
344    }
345
346    public void setShowChargingInfo(boolean showChargingInfo) {
347        mShowChargingInfo = showChargingInfo;
348        if (mExpanded) {
349            updateVisibilities();
350            updateSystemIconsLayoutParams();
351        }
352    }
353
354    public void setChargingInfo(CharSequence chargingInfo) {
355        mChargingInfo.setText(chargingInfo);
356    }
357}
358