PhoneStatusBarView.java revision ecbab3662d4474bbb45477939aaa167eb883212b
1/*
2 * Copyright (C) 2008 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.app.ActivityManager;
20import android.content.Context;
21import android.content.res.Resources;
22import android.content.res.Resources.NotFoundException;
23import android.util.AttributeSet;
24import android.util.EventLog;
25import android.util.Log;
26import android.view.MotionEvent;
27import android.view.View;
28import android.view.accessibility.AccessibilityEvent;
29
30import com.android.systemui.EventLogTags;
31import com.android.systemui.R;
32import com.android.systemui.statusbar.StatusBarState;
33
34public class PhoneStatusBarView extends PanelBar {
35    private static final String TAG = "PhoneStatusBarView";
36    private static final boolean DEBUG = PhoneStatusBar.DEBUG;
37    private static final boolean DEBUG_GESTURES = true;
38
39    PhoneStatusBar mBar;
40    int mScrimColor;
41    int mScrimColorKeyguard;
42
43    PanelView mFadingPanel = null;
44    PanelView mLastFullyOpenedPanel = null;
45    PanelView mNotificationPanel;
46    private boolean mShouldFade;
47    private final PhoneStatusBarTransitions mBarTransitions;
48
49    public PhoneStatusBarView(Context context, AttributeSet attrs) {
50        super(context, attrs);
51
52        Resources res = getContext().getResources();
53        mScrimColor = res.getColor(R.color.notification_panel_scrim_color);
54        mScrimColorKeyguard = res.getColor(R.color.notification_panel_scrim_color_keyguard);
55        mBarTransitions = new PhoneStatusBarTransitions(this);
56    }
57
58    public BarTransitions getBarTransitions() {
59        return mBarTransitions;
60    }
61
62    public void setBar(PhoneStatusBar bar) {
63        mBar = bar;
64    }
65
66    @Override
67    public void onAttachedToWindow() {
68        mBarTransitions.init();
69    }
70
71    @Override
72    public void addPanel(PanelView pv) {
73        super.addPanel(pv);
74        if (pv.getId() == R.id.notification_panel) {
75            mNotificationPanel = pv;
76        }
77    }
78
79    @Override
80    public boolean panelsEnabled() {
81        return mBar.panelsEnabled();
82    }
83
84    @Override
85    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
86        if (super.onRequestSendAccessibilityEvent(child, event)) {
87            // The status bar is very small so augment the view that the user is touching
88            // with the content of the status bar a whole. This way an accessibility service
89            // may announce the current item as well as the entire content if appropriate.
90            AccessibilityEvent record = AccessibilityEvent.obtain();
91            onInitializeAccessibilityEvent(record);
92            dispatchPopulateAccessibilityEvent(record);
93            event.appendRecord(record);
94            return true;
95        }
96        return false;
97    }
98
99    @Override
100    public PanelView selectPanelForTouch(MotionEvent touch) {
101        // No double swiping. If either panel is open, nothing else can be pulled down.
102        return mNotificationPanel.getExpandedHeight() > 0
103                ? null
104                : mNotificationPanel;
105    }
106
107    @Override
108    public void onPanelPeeked() {
109        super.onPanelPeeked();
110        mBar.makeExpandedVisible(false);
111    }
112
113    @Override
114    public void startOpeningPanel(PanelView panel) {
115        super.startOpeningPanel(panel);
116        // we only want to start fading if this is the "first" or "last" panel,
117        // which is kind of tricky to determine
118        mShouldFade = (mFadingPanel == null || mFadingPanel.isFullyExpanded());
119        if (DEBUG) {
120            Log.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade);
121        }
122        mFadingPanel = panel;
123    }
124
125    @Override
126    public void onAllPanelsCollapsed() {
127        super.onAllPanelsCollapsed();
128        // give animations time to settle
129        mBar.makeExpandedInvisibleSoon();
130        mFadingPanel = null;
131        mLastFullyOpenedPanel = null;
132        if (mScrimColor != 0 && ActivityManager.isHighEndGfx() && mBar.mStatusBarWindow != null) {
133            mBar.mStatusBarWindow.setBackgroundColor(0);
134        }
135    }
136
137    @Override
138    public void onPanelFullyOpened(PanelView openPanel) {
139        super.onPanelFullyOpened(openPanel);
140        if (openPanel != mLastFullyOpenedPanel) {
141            openPanel.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
142        }
143        mFadingPanel = openPanel;
144        mLastFullyOpenedPanel = openPanel;
145        mShouldFade = true; // now you own the fade, mister
146    }
147
148    @Override
149    public boolean onTouchEvent(MotionEvent event) {
150        boolean barConsumedEvent = mBar.interceptTouchEvent(event);
151
152        if (DEBUG_GESTURES) {
153            if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
154                EventLog.writeEvent(EventLogTags.SYSUI_PANELBAR_TOUCH,
155                        event.getActionMasked(), (int) event.getX(), (int) event.getY(),
156                        barConsumedEvent ? 1 : 0);
157            }
158        }
159
160        return barConsumedEvent || super.onTouchEvent(event);
161    }
162
163    @Override
164    public void onTrackingStarted(PanelView panel) {
165        super.onTrackingStarted(panel);
166        mBar.onTrackingStarted();
167    }
168
169    @Override
170    public void onTrackingStopped(PanelView panel) {
171        super.onTrackingStopped(panel);
172        mBar.onTrackingStopped();
173    }
174
175    @Override
176    public boolean onInterceptTouchEvent(MotionEvent event) {
177        return mBar.interceptTouchEvent(event) || super.onInterceptTouchEvent(event);
178    }
179
180    @Override
181    public void panelExpansionChanged(PanelView panel, float frac) {
182        super.panelExpansionChanged(panel, frac);
183
184        if (DEBUG) {
185            Log.v(TAG, "panelExpansionChanged: f=" + frac);
186        }
187
188        if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx()
189                && mBar.mStatusBarWindow != null) {
190            if (mShouldFade) {
191                int scrimColor = mBar.getBarState() == StatusBarState.KEYGUARD
192                        ? mScrimColorKeyguard
193                        : mScrimColor;
194                frac = mPanelExpandedFractionSum; // don't judge me
195                // let's start this 20% of the way down the screen
196                frac = frac * 1.2f - 0.2f;
197                if (frac <= 0) {
198                    mBar.mStatusBarWindow.setBackgroundColor(0);
199                } else {
200                    // woo, special effects
201                    final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
202                    // attenuate background color alpha by k
203                    final int color = (int) ((scrimColor >>> 24) * k) << 24 | (scrimColor & 0xFFFFFF);
204                    mBar.mStatusBarWindow.setBackgroundColor(color);
205                }
206            }
207        }
208
209        // fade out the panel as it gets buried into the status bar to avoid overdrawing the
210        // status bar on the last frame of a close animation
211        final int H = mBar.getStatusBarHeight();
212        final float ph = panel.getExpandedHeight() + panel.getPaddingBottom();
213        float alpha = 1f;
214        if (ph < 2*H) {
215            if (ph < H) alpha = 0f;
216            else alpha = (ph - H) / H;
217            alpha = alpha * alpha; // get there faster
218        }
219        if (panel.getAlpha() != alpha) {
220            panel.setAlpha(alpha);
221        }
222
223        mBar.animateHeadsUp(mNotificationPanel == panel, mPanelExpandedFractionSum);
224
225        mBar.updateCarrierLabelVisibility(false);
226        mBar.userActivity();
227    }
228}
229