PhoneStatusBarView.java revision 80c2abe5bb896bd31509b201428208dd4fce8c76
115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root/*
215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Copyright (C) 2008 The Android Open Source Project
315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * you may not use this file except in compliance with the License.
615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * You may obtain a copy of the License at
715a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
815a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
915a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
1015a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Unless required by applicable law or agreed to in writing, software
1115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
1215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * See the License for the specific language governing permissions and
1415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * limitations under the License.
1515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root */
1615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root
17fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopackage com.android.systemui.statusbar.phone;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
201c1edaa5f127d814058271ee4827fc0fe4a8de44Daniel Sandlerimport android.content.res.Resources;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
2264161ccb2f3341ebe1675e38a999250c7967d0adChris Wrenimport android.util.EventLog;
236a1bd2b3dbc993e63632f12819d77ae5fa872a06Selim Cinekimport android.util.Log;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MotionEvent;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
266179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
2764161ccb2f3341ebe1675e38a999250c7967d0adChris Wren
2864161ccb2f3341ebe1675e38a999250c7967d0adChris Wrenimport com.android.systemui.EventLogTags;
2979de0c550037a5328bbc7f4fddaf02f192a5c283Joe Onoratoimport com.android.systemui.R;
306a1bd2b3dbc993e63632f12819d77ae5fa872a06Selim Cinekimport com.android.systemui.statusbar.StatusBarState;
3179de0c550037a5328bbc7f4fddaf02f192a5c283Joe Onorato
3208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerpublic class PhoneStatusBarView extends PanelBar {
33fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    private static final String TAG = "PhoneStatusBarView";
34198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    private static final boolean DEBUG = PhoneStatusBar.DEBUG;
35934025e8d79975444d8b93cf6a18c7d98760b3adChristoph Studer    private static final boolean DEBUG_GESTURES = false;
36198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler
3708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    PhoneStatusBar mBar;
385a8aefa6c8ab2f129bc6477a49cd0876ec5d72faDaniel Sandler
39bac221ff0b9e1406f95f23c9a5c3b580ece10eabCasey Burkhardt    PanelView mLastFullyOpenedPanel = null;
40507288322b11ae27ab8f47438d3ef4203dad0192John Spurlock    PanelView mNotificationPanel;
417edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    private final PhoneStatusBarTransitions mBarTransitions;
42ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private ScrimController mScrimController;
433d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    private float mMinFraction;
443d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    private float mPanelFraction;
4580c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek    private Runnable mHideExpandedRunnable = new Runnable() {
4680c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek        @Override
4780c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek        public void run() {
4880c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek            mBar.makeExpandedInvisible();
4980c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek        }
5080c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek    };
51119a4015f0f7ac1f63d596da158768f880f9fe9bJoe Onorato
52fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    public PhoneStatusBarView(Context context, AttributeSet attrs) {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs);
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
551c1edaa5f127d814058271ee4827fc0fe4a8de44Daniel Sandler        Resources res = getContext().getResources();
567edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        mBarTransitions = new PhoneStatusBarTransitions(this);
57e932e30eadb5978591316ffe3d21d60604c0cd91John Spurlock    }
58e932e30eadb5978591316ffe3d21d60604c0cd91John Spurlock
59e932e30eadb5978591316ffe3d21d60604c0cd91John Spurlock    public BarTransitions getBarTransitions() {
60e932e30eadb5978591316ffe3d21d60604c0cd91John Spurlock        return mBarTransitions;
611c1edaa5f127d814058271ee4827fc0fe4a8de44Daniel Sandler    }
621c1edaa5f127d814058271ee4827fc0fe4a8de44Daniel Sandler
63efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler    public void setBar(PhoneStatusBar bar) {
64efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler        mBar = bar;
65efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler    }
66efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler
67ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public void setScrimController(ScrimController scrimController) {
68ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mScrimController = scrimController;
69ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
70ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
71efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler    @Override
72acea100015dffbb77d137b0681d6c34992e72ae9Jorim Jaggi    public void onFinishInflate() {
73e6f0a716501e57616c8e1d809c0f60b08d21eb0aJohn Spurlock        mBarTransitions.init();
74efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler    }
75efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler
761c1edaa5f127d814058271ee4827fc0fe4a8de44Daniel Sandler    @Override
77cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler    public void addPanel(PanelView pv) {
78cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler        super.addPanel(pv);
79cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler        if (pv.getId() == R.id.notification_panel) {
80cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler            mNotificationPanel = pv;
81cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler        }
82cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler    }
83cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler
84cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler    @Override
855050813f15a1d39d49cb8eca5a3aa6df43c4d450Daniel Sandler    public boolean panelsEnabled() {
869764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock        return mBar.panelsEnabled();
871e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler    }
881e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler
891e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler    @Override
90a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
915b0467522c8fd2e17d688e04ec592bdba9f2f012Alan Viverette        if (super.onRequestSendAccessibilityEventInternal(child, event)) {
9208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            // The status bar is very small so augment the view that the user is touching
9308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            // with the content of the status bar a whole. This way an accessibility service
9408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            // may announce the current item as well as the entire content if appropriate.
9508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            AccessibilityEvent record = AccessibilityEvent.obtain();
9608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            onInitializeAccessibilityEvent(record);
9708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            dispatchPopulateAccessibilityEvent(record);
9808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            event.appendRecord(record);
9908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            return true;
100d49258fed489bcd72a2b2a6ce3a3c38d4b2531e6Dianne Hackborn        }
10108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        return false;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
105efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler    public PanelView selectPanelForTouch(MotionEvent touch) {
106507288322b11ae27ab8f47438d3ef4203dad0192John Spurlock        // No double swiping. If either panel is open, nothing else can be pulled down.
107507288322b11ae27ab8f47438d3ef4203dad0192John Spurlock        return mNotificationPanel.getExpandedHeight() > 0
108507288322b11ae27ab8f47438d3ef4203dad0192John Spurlock                ? null
109507288322b11ae27ab8f47438d3ef4203dad0192John Spurlock                : mNotificationPanel;
110cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler    }
111cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler
112cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler    @Override
11308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public void onPanelPeeked() {
11408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        super.onPanelPeeked();
115fa505a7f26bdf685c701e92b481602eb59d7ff56Jorim Jaggi        mBar.makeExpandedVisible(false);
11667eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler    }
11767eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler
11867eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler    @Override
11908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public void onAllPanelsCollapsed() {
12008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        super.onAllPanelsCollapsed();
1216a1bd2b3dbc993e63632f12819d77ae5fa872a06Selim Cinek        if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD
1226a1bd2b3dbc993e63632f12819d77ae5fa872a06Selim Cinek                && mBar.getBarState() == StatusBarState.KEYGUARD) {
1236a1bd2b3dbc993e63632f12819d77ae5fa872a06Selim Cinek            Log.i(PhoneStatusBar.TAG, "Panel collapsed! Stacktrace: "
1246a1bd2b3dbc993e63632f12819d77ae5fa872a06Selim Cinek                    + Log.getStackTraceString(new Throwable()));
1256a1bd2b3dbc993e63632f12819d77ae5fa872a06Selim Cinek        }
1262580a976ec93a01ed00fae51364ad872bc591d95Jorim Jaggi        // Close the status bar in the next frame so we can show the end of the animation.
12780c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek        postOnAnimation(mHideExpandedRunnable);
128bac221ff0b9e1406f95f23c9a5c3b580ece10eabCasey Burkhardt        mLastFullyOpenedPanel = null;
1298e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler    }
1308e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler
13180c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek    public void removePendingHideExpandedRunnables() {
13280c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek        removeCallbacks(mHideExpandedRunnable);
13380c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek    }
13480c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek
1358e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler    @Override
1368e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler    public void onPanelFullyOpened(PanelView openPanel) {
137750bb9bff9fccf94f4bbf5945e10ce3f76534e7fDaniel Sandler        super.onPanelFullyOpened(openPanel);
138bac221ff0b9e1406f95f23c9a5c3b580ece10eabCasey Burkhardt        if (openPanel != mLastFullyOpenedPanel) {
139bac221ff0b9e1406f95f23c9a5c3b580ece10eabCasey Burkhardt            openPanel.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
140bac221ff0b9e1406f95f23c9a5c3b580ece10eabCasey Burkhardt        }
141bac221ff0b9e1406f95f23c9a5c3b580ece10eabCasey Burkhardt        mLastFullyOpenedPanel = openPanel;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onTouchEvent(MotionEvent event) {
14664161ccb2f3341ebe1675e38a999250c7967d0adChris Wren        boolean barConsumedEvent = mBar.interceptTouchEvent(event);
14764161ccb2f3341ebe1675e38a999250c7967d0adChris Wren
14864161ccb2f3341ebe1675e38a999250c7967d0adChris Wren        if (DEBUG_GESTURES) {
14964161ccb2f3341ebe1675e38a999250c7967d0adChris Wren            if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
15064161ccb2f3341ebe1675e38a999250c7967d0adChris Wren                EventLog.writeEvent(EventLogTags.SYSUI_PANELBAR_TOUCH,
15164161ccb2f3341ebe1675e38a999250c7967d0adChris Wren                        event.getActionMasked(), (int) event.getX(), (int) event.getY(),
15264161ccb2f3341ebe1675e38a999250c7967d0adChris Wren                        barConsumedEvent ? 1 : 0);
15364161ccb2f3341ebe1675e38a999250c7967d0adChris Wren            }
15464161ccb2f3341ebe1675e38a999250c7967d0adChris Wren        }
15564161ccb2f3341ebe1675e38a999250c7967d0adChris Wren
15664161ccb2f3341ebe1675e38a999250c7967d0adChris Wren        return barConsumedEvent || super.onTouchEvent(event);
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
160e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi    public void onTrackingStarted(PanelView panel) {
161e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi        super.onTrackingStarted(panel);
162e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi        mBar.onTrackingStarted();
163ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mScrimController.onTrackingStarted();
164e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi    }
165e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi
166e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi    @Override
167dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek    public void onClosingFinished() {
168dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek        super.onClosingFinished();
169dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek        mBar.onClosingFinished();
170dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek    }
171dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek
172dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek    @Override
1732fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi    public void onTrackingStopped(PanelView panel, boolean expand) {
1742fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi        super.onTrackingStopped(panel, expand);
1752fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi        mBar.onTrackingStopped(expand);
1762fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi    }
1772fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi
1782fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi    @Override
1792fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi    public void onExpandingFinished() {
1802fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi        super.onExpandingFinished();
1812fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi        mScrimController.onExpandingFinished();
182e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi    }
183e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi
184e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi    @Override
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onInterceptTouchEvent(MotionEvent event) {
18608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        return mBar.interceptTouchEvent(event) || super.onInterceptTouchEvent(event);
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1896179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov    @Override
1903d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    public void panelScrimMinFractionChanged(float minFraction) {
1913d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        if (mMinFraction != minFraction) {
1923d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek            mMinFraction = minFraction;
1933d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek            updateScrimFraction();
1943d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        }
1953d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    }
1963d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek
1973d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    @Override
198b472b347b51f84489217bb5d9c3beeeda1e4e626Jorim Jaggi    public void panelExpansionChanged(PanelView panel, float frac, boolean expanded) {
199b472b347b51f84489217bb5d9c3beeeda1e4e626Jorim Jaggi        super.panelExpansionChanged(panel, frac, expanded);
2003d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        mPanelFraction = frac;
2013d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        updateScrimFraction();
2023d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    }
2033d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek
2043d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    private void updateScrimFraction() {
2053d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        float scrimFraction = Math.max(mPanelFraction - mMinFraction / (1.0f - mMinFraction), 0);
2063d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        mScrimController.setPanelExpansion(scrimFraction);
2076179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov    }
2086179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov}
209