NotificationPanelView.java revision 0d74eeb9ec7ffe30d5c825bf7a3af96a53e2683d
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/* 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * Copyright (C) 2012 The Android Open Source Project 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * Licensed under the Apache License, Version 2.0 (the "License"); 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner * you may not use this file except in compliance with the License. 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner * You may obtain a copy of the License at 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * http://www.apache.org/licenses/LICENSE-2.0 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * Unless required by applicable law or agreed to in writing, software 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * distributed under the License is distributed on an "AS IS" BASIS, 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * See the License for the specific language governing permissions and 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * limitations under the License. 15de7fb8413b13651fd85b7125d08b3c9ac2816d9dDaniel Dunbar */ 16c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar 17de7fb8413b13651fd85b7125d08b3c9ac2816d9dDaniel Dunbarpackage com.android.systemui.statusbar.phone; 18e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar 195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerimport android.animation.Animator; 204e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlssonimport android.animation.AnimatorListenerAdapter; 21d9e9ede6b1703849da739629904dad197306e527Devang Patelimport android.animation.ValueAnimator; 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerimport android.content.Context; 2345c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbarimport android.util.AttributeSet; 2445c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbarimport android.view.MotionEvent; 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerimport android.view.VelocityTracker; 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerimport android.view.View; 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerimport android.view.ViewGroup; 28057afddf0fab91d979d6a750667d56a345225c96Devang Patelimport android.view.accessibility.AccessibilityEvent; 2988a981b47c7face1b1fdaa9074256245107b9ca9Devang Patelimport android.view.animation.AnimationUtils; 30057afddf0fab91d979d6a750667d56a345225c96Devang Patelimport android.view.animation.Interpolator; 314c4635c6cd8114bfa3ee20628fa1f03e67ac1e55Devang Patelimport android.widget.LinearLayout; 32057afddf0fab91d979d6a750667d56a345225c96Devang Patel 33057afddf0fab91d979d6a750667d56a345225c96Devang Patelimport com.android.systemui.R; 34cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedmanimport com.android.systemui.statusbar.ExpandableView; 35cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedmanimport com.android.systemui.statusbar.GestureRecorder; 360bd41f2cea0639395e8ab7ef8fd6df2c1999b6aeDevang Patelimport com.android.systemui.statusbar.StatusBarState; 3786522b9e84d0c39f09b54e888538ad64e89788c4Devang Patelimport com.android.systemui.statusbar.stack.NotificationStackScrollLayout; 38057afddf0fab91d979d6a750667d56a345225c96Devang Patel 39057afddf0fab91d979d6a750667d56a345225c96Devang Patelpublic class NotificationPanelView extends PanelView implements 4088a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener, 4186522b9e84d0c39f09b54e888538ad64e89788c4Devang Patel View.OnClickListener { 4286522b9e84d0c39f09b54e888538ad64e89788c4Devang Patel public static final boolean DEBUG_GESTURES = true; 4386522b9e84d0c39f09b54e888538ad64e89788c4Devang Patel private static final int EXPANSION_ANIMATION_LENGTH = 375; 4486522b9e84d0c39f09b54e888538ad64e89788c4Devang Patel 45cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman PhoneStatusBar mStatusBar; 46057afddf0fab91d979d6a750667d56a345225c96Devang Patel private StatusBarHeaderView mHeader; 47057afddf0fab91d979d6a750667d56a345225c96Devang Patel private QuickSettingsContainerView mQsContainer; 48057afddf0fab91d979d6a750667d56a345225c96Devang Patel private View mKeyguardStatusView; 49057afddf0fab91d979d6a750667d56a345225c96Devang Patel private ObservableScrollView mScrollView; 50057afddf0fab91d979d6a750667d56a345225c96Devang Patel private View mStackScrollerContainer; 51057afddf0fab91d979d6a750667d56a345225c96Devang Patel 52057afddf0fab91d979d6a750667d56a345225c96Devang Patel private NotificationStackScrollLayout mNotificationStackScroller; 53eae1560d4fb99b9df814bc12c0419825996156cdDevang Patel private int mNotificationTopPadding; 545bfc1a7ecb853cf87d10e720a07b9fbcd2a223eeDevang Patel private boolean mAnimateNextTopPaddingChange; 555bfc1a7ecb853cf87d10e720a07b9fbcd2a223eeDevang Patel 565bfc1a7ecb853cf87d10e720a07b9fbcd2a223eeDevang Patel private Interpolator mExpansionInterpolator; 57057afddf0fab91d979d6a750667d56a345225c96Devang Patel 58f9fef925644a6c40b344a43ab9ebdb08a707de53Devang Patel private int mTrackingPointer; 59cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman private VelocityTracker mVelocityTracker; 60057afddf0fab91d979d6a750667d56a345225c96Devang Patel private boolean mTracking; 61eae1560d4fb99b9df814bc12c0419825996156cdDevang Patel private boolean mQsExpanded; 62057afddf0fab91d979d6a750667d56a345225c96Devang Patel private float mInitialHeightOnTouch; 63057afddf0fab91d979d6a750667d56a345225c96Devang Patel private float mInitialTouchX; 64057afddf0fab91d979d6a750667d56a345225c96Devang Patel private float mInitialTouchY; 657a4718e813e5e99d478567a482217c7eef8572c5Devang Patel private float mQsExpansionHeight; 667a4718e813e5e99d478567a482217c7eef8572c5Devang Patel private int mQsMinExpansionHeight; 676b1da0ea19c12346192f5ea4d70872c13bfcc82aDaniel Dunbar private int mQsMaxExpansionHeight; 686b1da0ea19c12346192f5ea4d70872c13bfcc82aDaniel Dunbar private int mMinStackHeight; 69d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner private float mNotificationTranslation; 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer private int mStackScrollerIntrinsicPadding; 71b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel private boolean mQsExpansionEnabled = true; 72efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar private ValueAnimator mQsExpansionAnimator; 7388a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel 74b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel public NotificationPanelView(Context context, AttributeSet attrs) { 75b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel super(context, attrs); 7688a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel } 77b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel 78b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel public void setStatusBar(PhoneStatusBar bar) { 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (mStatusBar != null) { 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer mStatusBar.setOnFlipRunnable(null); 81fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner } 82fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mStatusBar = bar; 83fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner if (bar != null) { 84fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mStatusBar.setOnFlipRunnable(new Runnable() { 85fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner @Override 86fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner public void run() { 87fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner requestPanelHeightUpdate(); 886aeae7fa9cfaacba3a4077d62c01c2531d88a63eDaniel Dunbar } 89fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner }); 90fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner } 91fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner } 92fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner 93fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner @Override 9457a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman protected void onFinishInflate() { 95fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner super.onFinishInflate(); 96fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mHeader = (StatusBarHeaderView) findViewById(R.id.header); 97fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mHeader.getBackgroundView().setOnClickListener(this); 98fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mKeyguardStatusView = findViewById(R.id.keyguard_status_view); 99fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mStackScrollerContainer = findViewById(R.id.notification_container_parent); 100fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mQsContainer = (QuickSettingsContainerView) findViewById(R.id.quick_settings_container); 101fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view); 10209dc6660487fc2f4a4bb2032e30123d3e0da7230Chris Lattner mScrollView.setListener(this); 1039619662a1d42e2008b865d3459c0677e149dad1bChris Lattner mNotificationStackScroller = (NotificationStackScrollLayout) 10430ec9972be5a5af1f7a2277360dfa3aa1540b4faDevang Patel findViewById(R.id.notification_stack_scroller); 1050ffe89ab1e4890899e0e11a6f68223567a69b38aDevang Patel mNotificationStackScroller.setOnHeightChangedListener(this); 1069619662a1d42e2008b865d3459c0677e149dad1bChris Lattner mNotificationTopPadding = getResources().getDimensionPixelSize( 1073c40085b373d8e6e4523812e06f73a0cb9d5142cDevang Patel R.dimen.notifications_top_padding); 108fae6e2994a51d8ec1e61b6eb68765247c83b1ccfChris Lattner mMinStackHeight = getResources().getDimensionPixelSize(R.dimen.collapsed_stack_height); 1094581fff8af09a156a9dcc4de62587385c5da9574Chris Lattner mExpansionInterpolator = AnimationUtils.loadInterpolator( 11047c87b4b160d45285b24b1b7f4e3cbaaed3dc464Devang Patel getContext(), android.R.interpolator.fast_out_slow_in); 11130ec9972be5a5af1f7a2277360dfa3aa1540b4faDevang Patel } 11230ec9972be5a5af1f7a2277360dfa3aa1540b4faDevang Patel 1139619662a1d42e2008b865d3459c0677e149dad1bChris Lattner @Override 1144581fff8af09a156a9dcc4de62587385c5da9574Chris Lattner protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 11530ec9972be5a5af1f7a2277360dfa3aa1540b4faDevang Patel super.onLayout(changed, left, top, right, bottom); 11630ec9972be5a5af1f7a2277360dfa3aa1540b4faDevang Patel int keyguardBottomMargin = 11730ec9972be5a5af1f7a2277360dfa3aa1540b4faDevang Patel ((MarginLayoutParams) mKeyguardStatusView.getLayoutParams()).bottomMargin; 11857a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman if (!mQsExpanded) { 11957a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman mStackScrollerIntrinsicPadding = mStatusBar.getBarState() == StatusBarState.KEYGUARD 12057a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman ? mKeyguardStatusView.getBottom() + keyguardBottomMargin 12157a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman : mHeader.getBottom() + mNotificationTopPadding; 12257a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman mNotificationStackScroller.setTopPadding(mStackScrollerIntrinsicPadding, 12357a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman mAnimateNextTopPaddingChange); 12457a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman mAnimateNextTopPaddingChange = false; 1254581fff8af09a156a9dcc4de62587385c5da9574Chris Lattner } 1264581fff8af09a156a9dcc4de62587385c5da9574Chris Lattner 1274581fff8af09a156a9dcc4de62587385c5da9574Chris Lattner // Calculate quick setting heights. 1284581fff8af09a156a9dcc4de62587385c5da9574Chris Lattner mQsMinExpansionHeight = mHeader.getCollapsedHeight(); 12919009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight(); 13019009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner if (mQsExpansionHeight == 0) { 13119009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner mQsExpansionHeight = mQsMinExpansionHeight; 13219009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner } 13319009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner } 13419009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner 13519009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner public void animateNextTopPaddingChange() { 13619009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner mAnimateNextTopPaddingChange = true; 13798be4943e8dc4f3905629a7102668960873cf863Chris Lattner requestLayout(); 13819009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner } 13919009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner 14019009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner /** 141b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman * @return Whether Quick Settings are currently expanded. 142b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman */ 143b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman public boolean isQsExpanded() { 144b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman return mQsExpanded; 145b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman } 146b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman 147b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman public void setQsExpansionEnabled(boolean qsExpansionEnabled) { 148b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman mQsExpansionEnabled = qsExpansionEnabled; 149b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman } 150b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman 151b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman public void closeQs() { 152b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman cancelAnimation(); 153b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman setQsExpansion(mQsMinExpansionHeight); 154b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman } 155b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman 156c5b8806cda286cf41866176ef98011fdaa68da01Chris Lattner public void openQs() { 157c5b8806cda286cf41866176ef98011fdaa68da01Chris Lattner cancelAnimation(); 158c5b8806cda286cf41866176ef98011fdaa68da01Chris Lattner if (mQsExpansionEnabled) { 159efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar setQsExpansion(mQsMaxExpansionHeight); 160efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar } 161efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar } 162efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar 1636ef58e36bbbfa232fe8b50309361e841985abfc6Chris Lattner @Override 1646ef58e36bbbfa232fe8b50309361e841985abfc6Chris Lattner public void fling(float vel, boolean always) { 1656ef58e36bbbfa232fe8b50309361e841985abfc6Chris Lattner GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder(); 166d86e6bc7ab4388a578daf46e7c76be9122a25072Chris Lattner if (gr != null) { 167d86e6bc7ab4388a578daf46e7c76be9122a25072Chris Lattner gr.tag( 1686ef58e36bbbfa232fe8b50309361e841985abfc6Chris Lattner "fling " + ((vel > 0) ? "open" : "closed"), 169d86e6bc7ab4388a578daf46e7c76be9122a25072Chris Lattner "notifications,v=" + vel); 170d86e6bc7ab4388a578daf46e7c76be9122a25072Chris Lattner } 171d86e6bc7ab4388a578daf46e7c76be9122a25072Chris Lattner super.fling(vel, always); 172d86e6bc7ab4388a578daf46e7c76be9122a25072Chris Lattner } 1738fb1dd005f4cb530bca11d622362d39727294420Chris Lattner 1748fb1dd005f4cb530bca11d622362d39727294420Chris Lattner @Override 175d86e6bc7ab4388a578daf46e7c76be9122a25072Chris Lattner public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 1768fb1dd005f4cb530bca11d622362d39727294420Chris Lattner if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { 1778fb1dd005f4cb530bca11d622362d39727294420Chris Lattner event.getText() 178b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman .add(getContext().getString(R.string.accessibility_desc_notification_shade)); 179b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman return true; 180b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman } 181b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman 182b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman return super.dispatchPopulateAccessibilityEvent(event); 183b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman } 184b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman 185b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman @Override 186b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman public boolean onInterceptTouchEvent(MotionEvent event) { 187b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman int pointerIndex = event.findPointerIndex(mTrackingPointer); 188b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman if (pointerIndex < 0) { 189b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman pointerIndex = 0; 190b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman mTrackingPointer = event.getPointerId(pointerIndex); 191b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman } 192b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman final float x = event.getX(pointerIndex); 193b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman final float y = event.getY(pointerIndex); 194b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman 195b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman switch (event.getActionMasked()) { 196b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman case MotionEvent.ACTION_DOWN: 197b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman mInitialTouchY = y; 198d86e6bc7ab4388a578daf46e7c76be9122a25072Chris Lattner mInitialTouchX = x; 199d86e6bc7ab4388a578daf46e7c76be9122a25072Chris Lattner initVelocityTracker(); 200b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner trackMovement(event); 201b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (shouldIntercept(mInitialTouchX, mInitialTouchY, 0)) { 202f6a943e047f541619a2202f9e43b20b3d7c0a96dEli Friedman getParent().requestDisallowInterceptTouchEvent(true); 203b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 204f6a943e047f541619a2202f9e43b20b3d7c0a96dEli Friedman break; 205b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner case MotionEvent.ACTION_POINTER_UP: 206f6a943e047f541619a2202f9e43b20b3d7c0a96dEli Friedman final int upPointer = event.getPointerId(event.getActionIndex()); 207b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (mTrackingPointer == upPointer) { 208f6a943e047f541619a2202f9e43b20b3d7c0a96dEli Friedman // gesture is ongoing, find a new pointer to track 209b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; 210f6a943e047f541619a2202f9e43b20b3d7c0a96dEli Friedman mTrackingPointer = event.getPointerId(newIndex); 211b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner mInitialTouchX = event.getX(newIndex); 212f6a943e047f541619a2202f9e43b20b3d7c0a96dEli Friedman mInitialTouchY = event.getY(newIndex); 213f6a943e047f541619a2202f9e43b20b3d7c0a96dEli Friedman } 214f6a943e047f541619a2202f9e43b20b3d7c0a96dEli Friedman break; 21530ec9972be5a5af1f7a2277360dfa3aa1540b4faDevang Patel 2169619662a1d42e2008b865d3459c0677e149dad1bChris Lattner case MotionEvent.ACTION_MOVE: 2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer final float h = y - mInitialTouchY; 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer trackMovement(event); 21972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor if (Math.abs(h) > mTouchSlop && Math.abs(h) > Math.abs(x - mInitialTouchX) 22072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor && shouldIntercept(mInitialTouchX, mInitialTouchY, h)) { 22172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor onQsExpansionStarted(); 22272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor mInitialHeightOnTouch = mQsExpansionHeight; 22372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor mInitialTouchY = y; 22472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor mInitialTouchX = x; 22572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor mTracking = true; 22672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return true; 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 229afef76e43a30380b3c612a674738f2f574c8f166Argyrios Kyrtzidis } 2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return !mQsExpanded && super.onInterceptTouchEvent(event); 2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 233d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner @Override 2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer public boolean onTouchEvent(MotionEvent event) { 2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // TODO: Handle doublefinger swipe to notifications again. Look at history for a reference 23619009e6fe7e0f51d2e49f4c94928a048c11c5281Chris Lattner // implementation. 2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (mTracking) { 2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer int pointerIndex = event.findPointerIndex(mTrackingPointer); 239d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner if (pointerIndex < 0) { 240d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner pointerIndex = 0; 241d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner mTrackingPointer = event.getPointerId(pointerIndex); 242d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner } 2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer final float y = event.getY(pointerIndex); 2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer final float x = event.getX(pointerIndex); 2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (event.getActionMasked()) { 2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case MotionEvent.ACTION_DOWN: 2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer mTracking = true; 2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer mInitialTouchY = y; 2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer mInitialTouchX = x; 251afef76e43a30380b3c612a674738f2f574c8f166Argyrios Kyrtzidis onQsExpansionStarted(); 25247f7dbf7c0b25505ad093a317983a9b39efe0610Chris Lattner mInitialHeightOnTouch = mQsExpansionHeight; 25398be4943e8dc4f3905629a7102668960873cf863Chris Lattner initVelocityTracker(); 2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer trackMovement(event); 255f6a943e047f541619a2202f9e43b20b3d7c0a96dEli Friedman break; 256c8b1227fa8c17d9881815e40c04e19334be536f8Nate Begeman 2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case MotionEvent.ACTION_POINTER_UP: 258b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner final int upPointer = event.getPointerId(event.getActionIndex()); 2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (mTrackingPointer == upPointer) { 2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // gesture is ongoing, find a new pointer to track 2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; 262f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman final float newY = event.getY(newIndex); 263f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman final float newX = event.getX(newIndex); 2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer mTrackingPointer = event.getPointerId(newIndex); 265572cf09ae8a78af1c56d40b016ec4cf1837163acChris Lattner mInitialHeightOnTouch = mQsExpansionHeight; 266fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mInitialTouchY = newY; 267572cf09ae8a78af1c56d40b016ec4cf1837163acChris Lattner mInitialTouchX = newX; 2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2697c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl break; 2707c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl 2716aeae7fa9cfaacba3a4077d62c01c2531d88a63eDaniel Dunbar case MotionEvent.ACTION_MOVE: 2726aeae7fa9cfaacba3a4077d62c01c2531d88a63eDaniel Dunbar final float h = y - mInitialTouchY; 2736aeae7fa9cfaacba3a4077d62c01c2531d88a63eDaniel Dunbar setQsExpansion(h + mInitialHeightOnTouch); 2746aeae7fa9cfaacba3a4077d62c01c2531d88a63eDaniel Dunbar trackMovement(event); 2756aeae7fa9cfaacba3a4077d62c01c2531d88a63eDaniel Dunbar break; 2766aeae7fa9cfaacba3a4077d62c01c2531d88a63eDaniel Dunbar 2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case MotionEvent.ACTION_UP: 2786aeae7fa9cfaacba3a4077d62c01c2531d88a63eDaniel Dunbar case MotionEvent.ACTION_CANCEL: 279fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mTracking = false; 280fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner mTrackingPointer = -1; 2816aeae7fa9cfaacba3a4077d62c01c2531d88a63eDaniel Dunbar trackMovement(event); 282fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner 2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer float vel = getCurrentVelocity(); 2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 285fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff // TODO: Better logic whether we should expand or not. 286fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff flingSettings(vel, vel > 0); 287c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman 2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (mVelocityTracker != null) { 289c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman mVelocityTracker.recycle(); 290c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman mVelocityTracker = null; 29157a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman } 292c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman break; 293c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman } 294c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman return true; 295c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman } 296c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman 297c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman // Consume touch events when QS are expanded. 29857a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman return mQsExpanded || super.onTouchEvent(event); 2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 300fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff 301fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff private void onQsExpansionStarted() { 30257a84fb51de4f3de50debcf12dd194af8c6aaa58Eli Friedman cancelAnimation(); 303fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff 304fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff // Reset scroll position and apply that position to the expanded height. 305213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman float height = mQsExpansionHeight - mScrollView.getScrollY(); 3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer mScrollView.scrollTo(0, 0); 3075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer setQsExpansion(height); 308fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner } 3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer private void expandQs() { 3115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer mHeader.setExpanded(true); 312bb36d331f439f49859efcfb4435c61762fbba6f9Daniel Dunbar mNotificationStackScroller.setEnabled(false); 313b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman mScrollView.setVisibility(View.VISIBLE); 314b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman mQsExpanded = true; 315b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman } 316b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman 317b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman private void collapseQs() { 318b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman mHeader.setExpanded(false); 319b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman mNotificationStackScroller.setEnabled(true); 320b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman mScrollView.setVisibility(View.INVISIBLE); 321b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman mQsExpanded = false; 322b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman } 323b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman 324b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman private void setQsExpansion(float height) { 3259a1a9c41cf7e2735f059bb0c1d85f3207f637b22Chris Lattner height = Math.min(Math.max(height, mQsMinExpansionHeight), mQsMaxExpansionHeight); 326b3b6b9b27ab8bdb2a435a5a92ce62e74e3399377Eli Friedman if (height > mQsMinExpansionHeight && !mQsExpanded) { 3279a1a9c41cf7e2735f059bb0c1d85f3207f637b22Chris Lattner expandQs(); 3289a1a9c41cf7e2735f059bb0c1d85f3207f637b22Chris Lattner } else if (height <= mQsMinExpansionHeight && mQsExpanded) { 3299a1a9c41cf7e2735f059bb0c1d85f3207f637b22Chris Lattner collapseQs(); 330bb36d331f439f49859efcfb4435c61762fbba6f9Daniel Dunbar } 331ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb mQsExpansionHeight = height; 332f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian mHeader.setExpansion(height); 333fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner setQsTranslation(height); 334f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian setQsStackScrollerPadding(height); 335b1776cb8d35dfa80bfd8606e58b8ade30dcd2438Chris Lattner } 336636efb6ee4382e6fc16724014e9cf70dbeb37c31Chris Lattner 337636efb6ee4382e6fc16724014e9cf70dbeb37c31Chris Lattner private void setQsTranslation(float height) { 338636efb6ee4382e6fc16724014e9cf70dbeb37c31Chris Lattner mQsContainer.setY(height - mQsContainer.getHeight()); 339636efb6ee4382e6fc16724014e9cf70dbeb37c31Chris Lattner } 340636efb6ee4382e6fc16724014e9cf70dbeb37c31Chris Lattner 341636efb6ee4382e6fc16724014e9cf70dbeb37c31Chris Lattner private void setQsStackScrollerPadding(float height) { 342391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner float start = height - mScrollView.getScrollY() + mNotificationTopPadding; 343412f59b23fc502b199b9ca96c72ef5d5ad21d62bDaniel Dunbar float stackHeight = mNotificationStackScroller.getHeight() - start; 344412f59b23fc502b199b9ca96c72ef5d5ad21d62bDaniel Dunbar if (stackHeight <= mMinStackHeight) { 345412f59b23fc502b199b9ca96c72ef5d5ad21d62bDaniel Dunbar float overflow = mMinStackHeight - stackHeight; 346412f59b23fc502b199b9ca96c72ef5d5ad21d62bDaniel Dunbar stackHeight = mMinStackHeight; 347412f59b23fc502b199b9ca96c72ef5d5ad21d62bDaniel Dunbar start = mNotificationStackScroller.getHeight() - stackHeight; 348412f59b23fc502b199b9ca96c72ef5d5ad21d62bDaniel Dunbar mNotificationStackScroller.setTranslationY(overflow); 349412f59b23fc502b199b9ca96c72ef5d5ad21d62bDaniel Dunbar mNotificationTranslation = overflow + mScrollView.getScrollY(); 350391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner } else { 351e37882ad335896dedf345102bb425383e6221c37Fariborz Jahanian mNotificationStackScroller.setTranslationY(0); 352a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek mNotificationTranslation = mScrollView.getScrollY(); 35398c5ead87d720d8b68b6f236c3c3579a388fc882Daniel Dunbar } 35498c5ead87d720d8b68b6f236c3c3579a388fc882Daniel Dunbar mNotificationStackScroller.setTopPadding(clampQsStackScrollerPadding((int) start), false); 355c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian } 35672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor 35772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor private int clampQsStackScrollerPadding(int desiredPadding) { 358de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner return Math.max(desiredPadding, mStackScrollerIntrinsicPadding); 3598fb1dd005f4cb530bca11d622362d39727294420Chris Lattner } 360de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner 361de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner private void trackMovement(MotionEvent event) { 362de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner if (mVelocityTracker != null) mVelocityTracker.addMovement(event); 363de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner } 364de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner 365de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner private void initVelocityTracker() { 366de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner if (mVelocityTracker != null) { 367d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner mVelocityTracker.recycle(); 368de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner } 369d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner mVelocityTracker = VelocityTracker.obtain(); 370de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner } 371de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner 372de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner private float getCurrentVelocity() { 373de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner if (mVelocityTracker == null) { 374de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner return 0; 375de0efb3b6eac36bdeae0e60f753a974cc4118a31Chris Lattner } 3769048891ff983d0681c116c6e8f1073aa31bdd6e8Daniel Dunbar mVelocityTracker.computeCurrentVelocity(1000); 3779048891ff983d0681c116c6e8f1073aa31bdd6e8Daniel Dunbar return mVelocityTracker.getYVelocity(); 3784e174f1b1e95faacc21da2eac70f7853807f3ea3Daniel Dunbar } 379209bb438042ef7652b2b046e43d4ffb5a00d9725Fariborz Jahanian 380209bb438042ef7652b2b046e43d4ffb5a00d9725Fariborz Jahanian private void cancelAnimation() { 381209bb438042ef7652b2b046e43d4ffb5a00d9725Fariborz Jahanian if (mQsExpansionAnimator != null) { 3829048891ff983d0681c116c6e8f1073aa31bdd6e8Daniel Dunbar mQsExpansionAnimator.cancel(); 383424c51d3d4bea87291919b75e73ca59386702ad5Sebastian Redl } 384424c51d3d4bea87291919b75e73ca59386702ad5Sebastian Redl } 385424c51d3d4bea87291919b75e73ca59386702ad5Sebastian Redl private void flingSettings(float vel, boolean expand) { 386424c51d3d4bea87291919b75e73ca59386702ad5Sebastian Redl 387424c51d3d4bea87291919b75e73ca59386702ad5Sebastian Redl // TODO: Actually use velocity. 388424c51d3d4bea87291919b75e73ca59386702ad5Sebastian Redl 389424c51d3d4bea87291919b75e73ca59386702ad5Sebastian Redl float target = expand ? mQsMaxExpansionHeight : mQsMinExpansionHeight; 3907532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target); 3917532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor animator.setDuration(EXPANSION_ANIMATION_LENGTH); 3927532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor animator.setInterpolator(mExpansionInterpolator); 3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer @Override 3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer public void onAnimationUpdate(ValueAnimator animation) { 3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer setQsExpansion((Float) animation.getAnimatedValue()); 3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer }); 399fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner animator.addListener(new AnimatorListenerAdapter() { 400fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner @Override 4018fb1dd005f4cb530bca11d622362d39727294420Chris Lattner public void onAnimationEnd(Animator animation) { 402efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar mQsExpansionAnimator = null; 403efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar } 404efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar }); 405efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar animator.start(); 406efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar mQsExpansionAnimator = animator; 407efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar } 408fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner 4095de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner /** 4105de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner * @return Whether we should intercept a gesture to open Quick Settings. 411fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner */ 412fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner private boolean shouldIntercept(float x, float y, float yDiff) { 4135de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner if (!mQsExpansionEnabled) { 4145de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner return false; 415fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner } 4165de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner View headerView = mStatusBar.getBarState() == StatusBarState.KEYGUARD && !mQsExpanded 417efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar ? mKeyguardStatusView 4185de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner : mHeader; 4195de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner boolean onHeader = x >= headerView.getLeft() && x <= headerView.getRight() 4205de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner && y >= headerView.getTop() && y <= headerView.getBottom(); 4215de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner if (mQsExpanded) { 4225de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner return onHeader || (mScrollView.isScrolledToBottom() && yDiff < 0); 42339ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis } else { 424fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner return onHeader; 425fce71b8ea53b6eb9c1630da24659289bc848f837Chris Lattner } 4265de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner } 4275de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner 4285de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner @Override 4295de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner public void setVisibility(int visibility) { 4305de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner int oldVisibility = getVisibility(); 4315de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner super.setVisibility(visibility); 4325de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner if (visibility != oldVisibility) { 4335de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner reparentStatusIcons(visibility == VISIBLE); 4345de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner } 435efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar } 4365de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner 4375de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner /** 4385de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner * When the notification panel gets expanded, we need to move the status icons in the header 439ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar * card. 440ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar */ 441ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar private void reparentStatusIcons(boolean toHeader) { 442ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar if (mStatusBar == null) { 443ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar return; 444fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner } 445cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman LinearLayout systemIcons = mStatusBar.getSystemIcons(); 446fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner if (systemIcons.getParent() != null) { 447ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar ((ViewGroup) systemIcons.getParent()).removeView(systemIcons); 448ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar } 449ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar if (toHeader) { 450ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar mHeader.attachSystemIcons(systemIcons); 451ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar } else { 452ae287239879386b9abf6da50a67bbb7fe81897f1Daniel Dunbar mStatusBar.reattachSystemIcons(); 453fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner } 4545de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner } 455efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar 456efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar @Override 457efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar protected boolean isScrolledToBottom() { 458efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar if (!isInSettings()) { 4595de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner return mNotificationStackScroller.isScrolledToBottom(); 460fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner } 461fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner return super.isScrolledToBottom(); 4625de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner } 4635de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner 4645de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner @Override 4655de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner protected int getMaxPanelHeight() { 4665de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner if (!isInSettings()) { 4675de00fcf7c923a14bb79bdbaabb2faeb5633d85aChris Lattner int maxPanelHeight = super.getMaxPanelHeight(); 468fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner int notificationMarginBottom = mStackScrollerContainer.getPaddingBottom(); 469fc3b8e9c1381d5e6ec361591d649c56a870ff971Chris Lattner int emptyBottomMargin = notificationMarginBottom 470b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel + mNotificationStackScroller.getEmptyBottomMargin(); 471b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel return maxPanelHeight - emptyBottomMargin; 472b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel } 473ce5605ecf76d8cde6372138f830bb144d174ced9Chris Lattner return super.getMaxPanelHeight(); 47421fdf416723e8c475812a0324a1f9fafc949c25fHartmut Kaiser } 475391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner 476391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner private boolean isInSettings() { 477391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner return mQsExpanded; 478c4c429a1a5947ba9be64d3070741d98362872265Devang Patel } 4792c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio 4802c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio @Override 4812c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio protected void onHeightUpdated(float expandedHeight) { 4822c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio mNotificationStackScroller.setStackHeight(expandedHeight); 4832c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio } 4842c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio 4852c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio @Override 4862c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio protected int getDesiredMeasureHeight() { 4872c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio return mMaxPanelHeight; 4882c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio } 4892c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio 4902c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio @Override 4912c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio protected void onExpandingStarted() { 4922c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio super.onExpandingStarted(); 4931abc7f654df795549d4f6f3a018ddb3a8fff013aNate Begeman mNotificationStackScroller.onExpansionStarted(); 4942c46ce8de96787aa8e040690a80896f1148c29b0Lauro Ramos Venancio } 495b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel 496b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel @Override 49788a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel protected void onExpandingFinished() { 49888a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel super.onExpandingFinished(); 499af31913e48c96fddb45a0fd33f25617546502cbbChris Lattner mNotificationStackScroller.onExpansionStopped(); 500efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar } 501efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar 502efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar @Override 503efb6d0dc3eafbcf4f8cd053138bd1abed1dda8d4Daniel Dunbar public void onHeightChanged(ExpandableView view) { 50488a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel requestPanelHeightUpdate(); 505b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel } 506b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel 507b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel @Override 508b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel public void onScrollChanged() { 50986522b9e84d0c39f09b54e888538ad64e89788c4Devang Patel if (mQsExpanded) { 510cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman mNotificationStackScroller.setTranslationY( 511cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman mNotificationTranslation - mScrollView.getScrollY()); 512cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman } 513cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman } 51488a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel 515e36a3c8b5c7db4916342e4381caa2fdc93eb5745Eli Friedman @Override 516e36a3c8b5c7db4916342e4381caa2fdc93eb5745Eli Friedman public void onClick(View v) { 517e36a3c8b5c7db4916342e4381caa2fdc93eb5745Eli Friedman if (v == mHeader.getBackgroundView()) { 518e36a3c8b5c7db4916342e4381caa2fdc93eb5745Eli Friedman onQsExpansionStarted(); 519cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman if (mQsExpanded) { 520e36a3c8b5c7db4916342e4381caa2fdc93eb5745Eli Friedman flingSettings(0 /* vel */, false /* expand */); 521cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman } else if (mQsExpansionEnabled) { 522cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman flingSettings(0 /* vel */, true /* expand */); 52344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor } 5246ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor } 5256ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor } 52644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor} 527cbadaf6ced6d664015ee409f62ab1bc20ae0bf73Eli Friedman