StatusBarHeaderView.java revision 13dee43e6f793a5e2a71f82c2c48586e5bb09afa
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;
29
30import com.android.systemui.R;
31import com.android.systemui.qs.QSPanel;
32import com.android.systemui.settings.BrightnessController;
33import com.android.systemui.settings.ToggleSlider;
34import com.android.systemui.statusbar.policy.UserInfoController;
35
36/**
37 * The view to manage the header area in the expanded status bar.
38 */
39public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener {
40
41    /**
42     * How much the header expansion gets rubberbanded while expanding the panel.
43     */
44    private static final float EXPANSION_RUBBERBAND_FACTOR = 0.35f;
45
46    private boolean mExpanded;
47    private boolean mOverscrolled;
48    private boolean mKeyguardShowing;
49
50    private View mBackground;
51    private ViewGroup mSystemIconsContainer;
52    private View mDateTime;
53    private View mKeyguardCarrierText;
54    private MultiUserSwitch mMultiUserSwitch;
55    private View mDate;
56    private View mStatusIcons;
57    private View mSignalCluster;
58    private View mSettingsButton;
59    private View mBrightnessContainer;
60
61    private int mCollapsedHeight;
62    private int mExpandedHeight;
63    private int mKeyguardHeight;
64
65    private int mKeyguardWidth = ViewGroup.LayoutParams.MATCH_PARENT;
66    private int mNormalWidth;
67
68    private ActivityStarter mActivityStarter;
69    private BrightnessController mBrightnessController;
70    private QSPanel mQSPanel;
71
72    private final Rect mClipBounds = new Rect();
73    private final Outline mOutline = new Outline();
74
75    public StatusBarHeaderView(Context context, AttributeSet attrs) {
76        super(context, attrs);
77    }
78
79    @Override
80    protected void onFinishInflate() {
81        super.onFinishInflate();
82        mBackground = findViewById(R.id.background);
83        mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container);
84        mDateTime = findViewById(R.id.datetime);
85        mKeyguardCarrierText = findViewById(R.id.keyguard_carrier_text);
86        mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
87        mDate = findViewById(R.id.date);
88        mSettingsButton = findViewById(R.id.settings_button);
89        mSettingsButton.setOnClickListener(this);
90        mBrightnessContainer = findViewById(R.id.brightness_container);
91        mBrightnessController = new BrightnessController(getContext(),
92                (ImageView) findViewById(R.id.brightness_icon),
93                (ToggleSlider) findViewById(R.id.brightness_slider));
94        loadDimens();
95        updateVisibilities();
96        addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
97            @Override
98            public void onLayoutChange(View v, int left, int top, int right,
99                    int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
100                if ((right - left) != (oldRight - oldLeft)) {
101                    // width changed, update clipping
102                    setClipping(getHeight());
103                }
104            }
105        });
106    }
107
108    private void loadDimens() {
109        mCollapsedHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_header_height);
110        mExpandedHeight = getResources().getDimensionPixelSize(
111                R.dimen.status_bar_header_height_expanded);
112        mKeyguardHeight = getResources().getDimensionPixelSize(
113                R.dimen.status_bar_header_height_keyguard);
114        mNormalWidth = getLayoutParams().width;
115    }
116
117    public void setActivityStarter(ActivityStarter activityStarter) {
118        mActivityStarter = activityStarter;
119    }
120
121    public int getCollapsedHeight() {
122        return mKeyguardShowing ? mKeyguardHeight : mCollapsedHeight;
123    }
124
125    public int getExpandedHeight() {
126        return mExpandedHeight;
127    }
128
129    public void setExpanded(boolean expanded, boolean overscrolled) {
130        boolean changed = expanded != mExpanded;
131        boolean overscrollChanged = overscrolled != mOverscrolled;
132        mExpanded = expanded;
133        mOverscrolled = overscrolled;
134        if (changed || overscrollChanged) {
135            updateHeights();
136            updateVisibilities();
137            updateSystemIconsLayoutParams();
138            updateBrightnessControllerState();
139            updateZTranslation();
140            updateClickTargets();
141            updateWidth();
142            if (mQSPanel != null) {
143                mQSPanel.setExpanded(expanded && !overscrolled);
144            }
145        }
146    }
147
148    private void updateHeights() {
149        boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded;
150        int height;
151        if (mExpanded) {
152            height = mExpandedHeight;
153        } else if (onKeyguardAndCollapsed) {
154            height = mKeyguardHeight;
155        } else {
156            height = mCollapsedHeight;
157        }
158        ViewGroup.LayoutParams lp = getLayoutParams();
159        if (lp.height != height) {
160            lp.height = height;
161            setLayoutParams(lp);
162        }
163        int systemIconsContainerHeight = onKeyguardAndCollapsed ? mKeyguardHeight : mCollapsedHeight;
164        lp = mSystemIconsContainer.getLayoutParams();
165        if (lp.height != systemIconsContainerHeight) {
166            lp.height = systemIconsContainerHeight;
167            mSystemIconsContainer.setLayoutParams(lp);
168        }
169        lp = mMultiUserSwitch.getLayoutParams();
170        if (lp.height != systemIconsContainerHeight) {
171            lp.height = systemIconsContainerHeight;
172            mMultiUserSwitch.setLayoutParams(lp);
173        }
174    }
175
176    private void updateWidth() {
177        int width = (mKeyguardShowing && !mExpanded) ? mKeyguardWidth : mNormalWidth;
178        ViewGroup.LayoutParams lp = getLayoutParams();
179        if (width != lp.width) {
180            lp.width = width;
181            setLayoutParams(lp);
182        }
183    }
184
185    private void updateVisibilities() {
186        boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded;
187        mBackground.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE);
188        mDateTime.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE);
189        mKeyguardCarrierText.setVisibility(onKeyguardAndCollapsed ? View.VISIBLE : View.GONE);
190        mDate.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
191        mSettingsButton.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE);
192        mBrightnessContainer.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
193        if (mStatusIcons != null) {
194            mStatusIcons.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE);
195        }
196        if (mSignalCluster != null) {
197            mSignalCluster.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE);
198        }
199    }
200
201    private void updateSystemIconsLayoutParams() {
202        RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsContainer.getLayoutParams();
203        lp.addRule(RelativeLayout.START_OF, mExpanded
204                ? mSettingsButton.getId()
205                : mMultiUserSwitch.getId());
206    }
207
208    private void updateBrightnessControllerState() {
209        if (mExpanded) {
210            mBrightnessController.registerCallbacks();
211        } else {
212            mBrightnessController.unregisterCallbacks();
213        }
214    }
215
216    private void updateClickTargets() {
217        mDateTime.setClickable(mExpanded);
218        mMultiUserSwitch.setClickable(mExpanded);
219    }
220
221    private void updateZTranslation() {
222
223        // If we are on the Keyguard, we need to set our z position to zero, so we don't get
224        // shadows.
225        if (mKeyguardShowing && !mExpanded) {
226            setZ(0);
227        } else {
228            setTranslationZ(0);
229        }
230    }
231
232    public void setExpansion(float height) {
233        height = (height - mCollapsedHeight) * EXPANSION_RUBBERBAND_FACTOR + mCollapsedHeight;
234        if (height < mCollapsedHeight) {
235            height = mCollapsedHeight;
236        }
237        if (height > mExpandedHeight) {
238            height = mExpandedHeight;
239        }
240        setClipping(height);
241    }
242
243    private void setClipping(float height) {
244        mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height);
245        setClipBounds(mClipBounds);
246        mOutline.setRect(mClipBounds);
247        setOutline(mOutline);
248    }
249
250    public View getBackgroundView() {
251        return mBackground;
252    }
253
254    public void attachSystemIcons(LinearLayout systemIcons) {
255        mSystemIconsContainer.addView(systemIcons);
256        mStatusIcons = systemIcons.findViewById(R.id.statusIcons);
257        mSignalCluster = systemIcons.findViewById(R.id.signal_cluster);
258    }
259
260    public void onSystemIconsDetached() {
261        if (mStatusIcons != null) {
262            mStatusIcons.setVisibility(View.VISIBLE);
263        }
264        if (mSignalCluster != null) {
265            mSignalCluster.setVisibility(View.VISIBLE);
266        }
267        mStatusIcons = null;
268        mSignalCluster = null;
269    }
270
271    public void setKeyguardShowing(boolean keyguardShowing) {
272        mKeyguardShowing = keyguardShowing;
273        updateHeights();
274        updateWidth();
275        updateVisibilities();
276        updateZTranslation();
277    }
278
279    public void setUserInfoController(UserInfoController userInfoController) {
280        mMultiUserSwitch.setUserInfoController(userInfoController);
281    }
282
283    public void setOverlayParent(ViewGroup parent) {
284        mMultiUserSwitch.setOverlayParent(parent);
285    }
286
287    @Override
288    public void onClick(View v) {
289        if (v == mSettingsButton) {
290            startSettingsActivity();
291        }
292    }
293
294    private void startSettingsActivity() {
295        mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
296    }
297
298    public void setQSPanel(QSPanel qsp) {
299        mQSPanel = qsp;
300        if (mQSPanel != null) {
301            mQSPanel.setCallback(mQsPanelCallback);
302        }
303    }
304
305    private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
306        @Override
307        public void onShowingDetail(boolean showingDetail) {
308            mBrightnessContainer.animate().alpha(showingDetail ? 0 : 1).withLayer().start();
309        }
310    };
311}
312