3939import android .graphics .PorterDuff ;
4040import android .graphics .Rect ;
4141import android .graphics .drawable .Drawable ;
42+ import android .graphics .drawable .NinePatchDrawable ;
4243import android .inputmethodservice .InputMethodService ;
4344import android .os .IBinder ;
4445import android .os .Message ;
@@ -161,6 +162,7 @@ public class PhoneStatusBar extends BaseStatusBar {
161162 View mExpandedContents ;
162163 int mNotificationPanelMarginBottomPx , mNotificationPanelMarginLeftPx ;
163164 int mNotificationPanelGravity ;
165+ int mNotificationPanelMinHeight ;
164166
165167 // top bar
166168 View mClearButton ;
@@ -208,6 +210,8 @@ public class PhoneStatusBar extends BaseStatusBar {
208210 long mAnimLastTimeNanos ;
209211 boolean mAnimatingReveal = false ;
210212 int mViewDelta ;
213+ float mFlingVelocity ;
214+ int mFlingY ;
211215 int [] mAbsPos = new int [2 ];
212216 Runnable mPostCollapseCleanup = null ;
213217
@@ -236,6 +240,33 @@ public void onAnimationEnd(Animator animation) {
236240 }
237241 };
238242
243+ private final Runnable mStartRevealAnimation = new Runnable () {
244+ @ Override
245+ public void run () {
246+ mAnimAccel = mExpandAccelPx ;
247+ mAnimVel = mFlingExpandMinVelocityPx ;
248+ mAnimY = getStatusBarHeight ();
249+ updateExpandedViewPos ((int )mAnimY );
250+
251+ mAnimating = true ;
252+ mAnimatingReveal = true ;
253+ resetLastAnimTime ();
254+ mChoreographer .removeCallbacks (Choreographer .CALLBACK_ANIMATION ,
255+ mAnimationCallback , null );
256+ mChoreographer .removeCallbacks (Choreographer .CALLBACK_ANIMATION ,
257+ mRevealAnimationCallback , null );
258+ mChoreographer .postCallback (Choreographer .CALLBACK_ANIMATION ,
259+ mRevealAnimationCallback , null );
260+ }
261+ };
262+
263+ private final Runnable mPerformFling = new Runnable () {
264+ @ Override
265+ public void run () {
266+ performFling (mFlingY + mViewDelta , mFlingVelocity , false );
267+ }
268+ };
269+
239270 private class ExpandedDialog extends Dialog {
240271 ExpandedDialog (Context context ) {
241272 super (context , com .android .internal .R .style .Theme_Translucent_NoTitleBar );
@@ -321,7 +352,6 @@ public boolean onTouch(View v, MotionEvent event) {
321352 mNotificationPanel .setBackground (new FastColorDrawable (context .getResources ().getColor (
322353 R .color .notification_panel_solid_background )));
323354 }
324-
325355 if (ENABLE_INTRUDERS ) {
326356 mIntruderAlertView = (IntruderAlertView ) View .inflate (context , R .layout .intruder_alert , null );
327357 mIntruderAlertView .setVisibility (View .GONE );
@@ -1042,14 +1072,13 @@ public void onFocusChange(View v, boolean hasFocus) {
10421072 }
10431073 };
10441074
1045- private void makeExpandedVisible () {
1075+ private void makeExpandedVisible (boolean revealAfterDraw ) {
10461076 if (SPEW ) Slog .d (TAG , "Make expanded visible: expanded visible=" + mExpandedVisible );
10471077 if (mExpandedVisible ) {
10481078 return ;
10491079 }
10501080
10511081 mExpandedVisible = true ;
1052- mNotificationPanel .setVisibility (View .VISIBLE );
10531082 makeSlippery (mNavigationBarView , true );
10541083
10551084 updateExpandedViewPos (EXPANDED_LEAVE_ALONE );
@@ -1063,6 +1092,12 @@ private void makeExpandedVisible() {
10631092 final WindowManager wm = WindowManagerImpl .getDefault ();
10641093 wm .updateViewLayout (mStatusBarWindow , lp );
10651094
1095+ // Updating the window layout will force an expensive traversal/redraw.
1096+ // Kick off the reveal animation after this is complete to avoid animation latency.
1097+ if (revealAfterDraw ) {
1098+ mHandler .post (mStartRevealAnimation );
1099+ }
1100+
10661101 visibilityChanged (true );
10671102 }
10681103
@@ -1148,7 +1183,7 @@ void performExpand() {
11481183 }
11491184
11501185 mExpanded = true ;
1151- makeExpandedVisible ();
1186+ makeExpandedVisible (false );
11521187 updateExpandedViewPos (EXPANDED_FULL_OPEN );
11531188
11541189 if (false ) postStartTracing ();
@@ -1163,7 +1198,6 @@ void performCollapse() {
11631198 }
11641199 mExpandedVisible = false ;
11651200 visibilityChanged (false );
1166- mNotificationPanel .setVisibility (View .INVISIBLE );
11671201 makeSlippery (mNavigationBarView , false );
11681202
11691203 // Shrink the window to the size of the status bar only
@@ -1244,6 +1278,8 @@ void doAnimation(long frameTimeNanos) {
12441278 }
12451279
12461280 void stopTracking () {
1281+ if (!mTracking )
1282+ return ;
12471283 mTracking = false ;
12481284 mPile .setLayerType (View .LAYER_TYPE_NONE , null );
12491285 mVelocityTracker .recycle ();
@@ -1268,7 +1304,7 @@ void doRevealAnimation(long frameTimeNanos) {
12681304 if (SPEW ) {
12691305 Slog .d (TAG , "doRevealAnimation: dt=" + (frameTimeNanos - mAnimLastTimeNanos ));
12701306 }
1271- final int h = getCloseViewHeight () + getStatusBarHeight () ;
1307+ final int h = mNotificationPanelMinHeight ;
12721308 if (mAnimatingReveal && mAnimating && mAnimY < h ) {
12731309 incrementAnim (frameTimeNanos );
12741310 if (mAnimY >= h ) {
@@ -1293,20 +1329,7 @@ void prepareTracking(int y, boolean opening) {
12931329 mPile .setLayerType (View .LAYER_TYPE_HARDWARE , null );
12941330 mVelocityTracker = VelocityTracker .obtain ();
12951331 if (opening ) {
1296- mAnimAccel = mExpandAccelPx ;
1297- mAnimVel = mFlingExpandMinVelocityPx ;
1298- mAnimY = getStatusBarHeight ();
1299- updateExpandedViewPos ((int )mAnimY );
1300- mAnimating = true ;
1301- mAnimatingReveal = true ;
1302- resetLastAnimTime ();
1303- mChoreographer .removeCallbacks (Choreographer .CALLBACK_ANIMATION ,
1304- mAnimationCallback , null );
1305- mChoreographer .removeCallbacks (Choreographer .CALLBACK_ANIMATION ,
1306- mRevealAnimationCallback , null );
1307- mChoreographer .postCallback (Choreographer .CALLBACK_ANIMATION ,
1308- mRevealAnimationCallback , null );
1309- makeExpandedVisible ();
1332+ makeExpandedVisible (true );
13101333 } else {
13111334 // it's open, close it?
13121335 if (mAnimating ) {
@@ -1320,7 +1343,7 @@ void prepareTracking(int y, boolean opening) {
13201343
13211344 void performFling (int y , float vel , boolean always ) {
13221345 if (CHATTY ) {
1323- Slog .d (TAG , "panel: will fling, y=" + y + " vel=" + vel );
1346+ Slog .d (TAG , "panel: will fling, y=" + y + " vel=" + vel + " mExpanded=" + mExpanded );
13241347 }
13251348
13261349 mAnimatingReveal = false ;
@@ -1389,7 +1412,7 @@ void performFling(int y, float vel, boolean always) {
13891412 boolean interceptTouchEvent (MotionEvent event ) {
13901413 if (SPEW ) {
13911414 Slog .d (TAG , "Touch: rawY=" + event .getRawY () + " event=" + event + " mDisabled="
1392- + mDisabled );
1415+ + mDisabled + " mTracking=" + mTracking );
13931416 } else if (CHATTY ) {
13941417 if (event .getAction () != MotionEvent .ACTION_MOVE ) {
13951418 Slog .d (TAG , String .format (
@@ -1434,9 +1457,8 @@ boolean interceptTouchEvent(MotionEvent event) {
14341457 }
14351458 } else if (mTracking ) {
14361459 trackMovement (event );
1437- final int minY = statusBarSize + getCloseViewHeight ();
14381460 if (action == MotionEvent .ACTION_MOVE ) {
1439- if (mAnimatingReveal && (y + mViewDelta ) < minY ) {
1461+ if (mAnimatingReveal && (y + mViewDelta ) < mNotificationPanelMinHeight ) {
14401462 // nothing
14411463 } else {
14421464 mAnimatingReveal = false ;
@@ -1470,7 +1492,15 @@ boolean interceptTouchEvent(MotionEvent event) {
14701492 vel ));
14711493 }
14721494
1473- performFling (y + mViewDelta , vel , false );
1495+ if (mTrackingPosition == mNotificationPanelMinHeight ) {
1496+ // start the fling from the tracking position, ignore y and view delta
1497+ mFlingY = mTrackingPosition ;
1498+ mViewDelta = 0 ;
1499+ } else {
1500+ mFlingY = y ;
1501+ }
1502+ mFlingVelocity = vel ;
1503+ mHandler .post (mPerformFling );
14741504 }
14751505
14761506 }
@@ -1873,7 +1903,6 @@ protected void updateExpandedViewPos(int expandedPosition) {
18731903 + " mTrackingPosition=" + mTrackingPosition
18741904 + " gravity=" + mNotificationPanelGravity );
18751905 }
1876-
18771906 int panelh = 0 ;
18781907 final int disph = getExpandedViewMaxHeight ();
18791908
@@ -2159,10 +2188,24 @@ protected void loadDimens() {
21592188 if (mNotificationPanelGravity <= 0 ) {
21602189 mNotificationPanelGravity = Gravity .CENTER_VERTICAL | Gravity .TOP ;
21612190 }
2191+ mNotificationPanelMinHeight =
2192+ res .getDimensionPixelSize (R .dimen .notification_panel_padding_top )
2193+ + res .getDimensionPixelSize (R .dimen .notification_panel_header_height )
2194+ + res .getDimensionPixelSize (R .dimen .close_handle_underlap )
2195+ + getNinePatchPadding (res .getDrawable (R .drawable .notification_panel_bg )).bottom ;
21622196
21632197 if (false ) Slog .v (TAG , "updateResources" );
21642198 }
21652199
2200+ private static Rect getNinePatchPadding (Drawable d ) {
2201+ Rect padding = new Rect ();
2202+ if (d instanceof NinePatchDrawable ) {
2203+ NinePatchDrawable ninePatch = (NinePatchDrawable ) d ;
2204+ ninePatch .getPadding (padding );
2205+ }
2206+ return padding ;
2207+ }
2208+
21662209 //
21672210 // tracing
21682211 //
0 commit comments