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 );
@@ -1039,14 +1069,13 @@ public void onFocusChange(View v, boolean hasFocus) {
10391069 }
10401070 };
10411071
1042- private void makeExpandedVisible () {
1072+ private void makeExpandedVisible (boolean revealAfterDraw ) {
10431073 if (SPEW ) Slog .d (TAG , "Make expanded visible: expanded visible=" + mExpandedVisible );
10441074 if (mExpandedVisible ) {
10451075 return ;
10461076 }
10471077
10481078 mExpandedVisible = true ;
1049- mNotificationPanel .setVisibility (View .VISIBLE );
10501079 makeSlippery (mNavigationBarView , true );
10511080
10521081 updateExpandedViewPos (EXPANDED_LEAVE_ALONE );
@@ -1060,6 +1089,12 @@ private void makeExpandedVisible() {
10601089 final WindowManager wm = WindowManagerImpl .getDefault ();
10611090 wm .updateViewLayout (mStatusBarWindow , lp );
10621091
1092+ // Updating the window layout will force an expensive traversal/redraw.
1093+ // Kick off the reveal animation after this is complete to avoid animation latency.
1094+ if (revealAfterDraw ) {
1095+ mHandler .post (mStartRevealAnimation );
1096+ }
1097+
10631098 visibilityChanged (true );
10641099 }
10651100
@@ -1145,7 +1180,7 @@ void performExpand() {
11451180 }
11461181
11471182 mExpanded = true ;
1148- makeExpandedVisible ();
1183+ makeExpandedVisible (false );
11491184 updateExpandedViewPos (EXPANDED_FULL_OPEN );
11501185
11511186 if (false ) postStartTracing ();
@@ -1160,7 +1195,6 @@ void performCollapse() {
11601195 }
11611196 mExpandedVisible = false ;
11621197 visibilityChanged (false );
1163- mNotificationPanel .setVisibility (View .INVISIBLE );
11641198 makeSlippery (mNavigationBarView , false );
11651199
11661200 // Shrink the window to the size of the status bar only
@@ -1241,6 +1275,8 @@ void doAnimation(long frameTimeNanos) {
12411275 }
12421276
12431277 void stopTracking () {
1278+ if (!mTracking )
1279+ return ;
12441280 mTracking = false ;
12451281 mPile .setLayerType (View .LAYER_TYPE_NONE , null );
12461282 mVelocityTracker .recycle ();
@@ -1265,7 +1301,7 @@ void doRevealAnimation(long frameTimeNanos) {
12651301 if (SPEW ) {
12661302 Slog .d (TAG , "doRevealAnimation: dt=" + (frameTimeNanos - mAnimLastTimeNanos ));
12671303 }
1268- final int h = getCloseViewHeight () + getStatusBarHeight () ;
1304+ final int h = mNotificationPanelMinHeight ;
12691305 if (mAnimatingReveal && mAnimating && mAnimY < h ) {
12701306 incrementAnim (frameTimeNanos );
12711307 if (mAnimY >= h ) {
@@ -1290,20 +1326,7 @@ void prepareTracking(int y, boolean opening) {
12901326 mPile .setLayerType (View .LAYER_TYPE_HARDWARE , null );
12911327 mVelocityTracker = VelocityTracker .obtain ();
12921328 if (opening ) {
1293- mAnimAccel = mExpandAccelPx ;
1294- mAnimVel = mFlingExpandMinVelocityPx ;
1295- mAnimY = getStatusBarHeight ();
1296- updateExpandedViewPos ((int )mAnimY );
1297- mAnimating = true ;
1298- mAnimatingReveal = true ;
1299- resetLastAnimTime ();
1300- mChoreographer .removeCallbacks (Choreographer .CALLBACK_ANIMATION ,
1301- mAnimationCallback , null );
1302- mChoreographer .removeCallbacks (Choreographer .CALLBACK_ANIMATION ,
1303- mRevealAnimationCallback , null );
1304- mChoreographer .postCallback (Choreographer .CALLBACK_ANIMATION ,
1305- mRevealAnimationCallback , null );
1306- makeExpandedVisible ();
1329+ makeExpandedVisible (true );
13071330 } else {
13081331 // it's open, close it?
13091332 if (mAnimating ) {
@@ -1317,7 +1340,7 @@ void prepareTracking(int y, boolean opening) {
13171340
13181341 void performFling (int y , float vel , boolean always ) {
13191342 if (CHATTY ) {
1320- Slog .d (TAG , "panel: will fling, y=" + y + " vel=" + vel );
1343+ Slog .d (TAG , "panel: will fling, y=" + y + " vel=" + vel + " mExpanded=" + mExpanded );
13211344 }
13221345
13231346 mAnimatingReveal = false ;
@@ -1386,7 +1409,7 @@ void performFling(int y, float vel, boolean always) {
13861409 boolean interceptTouchEvent (MotionEvent event ) {
13871410 if (SPEW ) {
13881411 Slog .d (TAG , "Touch: rawY=" + event .getRawY () + " event=" + event + " mDisabled="
1389- + mDisabled );
1412+ + mDisabled + " mTracking=" + mTracking );
13901413 } else if (CHATTY ) {
13911414 if (event .getAction () != MotionEvent .ACTION_MOVE ) {
13921415 Slog .d (TAG , String .format (
@@ -1431,9 +1454,8 @@ boolean interceptTouchEvent(MotionEvent event) {
14311454 }
14321455 } else if (mTracking ) {
14331456 trackMovement (event );
1434- final int minY = statusBarSize + getCloseViewHeight ();
14351457 if (action == MotionEvent .ACTION_MOVE ) {
1436- if (mAnimatingReveal && (y + mViewDelta ) < minY ) {
1458+ if (mAnimatingReveal && (y + mViewDelta ) < mNotificationPanelMinHeight ) {
14371459 // nothing
14381460 } else {
14391461 mAnimatingReveal = false ;
@@ -1467,7 +1489,15 @@ boolean interceptTouchEvent(MotionEvent event) {
14671489 vel ));
14681490 }
14691491
1470- performFling (y + mViewDelta , vel , false );
1492+ if (mTrackingPosition == mNotificationPanelMinHeight ) {
1493+ // start the fling from the tracking position, ignore y and view delta
1494+ mFlingY = mTrackingPosition ;
1495+ mViewDelta = 0 ;
1496+ } else {
1497+ mFlingY = y ;
1498+ }
1499+ mFlingVelocity = vel ;
1500+ mHandler .post (mPerformFling );
14711501 }
14721502
14731503 }
@@ -1870,7 +1900,6 @@ protected void updateExpandedViewPos(int expandedPosition) {
18701900 + " mTrackingPosition=" + mTrackingPosition
18711901 + " gravity=" + mNotificationPanelGravity );
18721902 }
1873-
18741903 int panelh = 0 ;
18751904 final int disph = getExpandedViewMaxHeight ();
18761905
@@ -2156,10 +2185,24 @@ protected void loadDimens() {
21562185 if (mNotificationPanelGravity <= 0 ) {
21572186 mNotificationPanelGravity = Gravity .CENTER_VERTICAL | Gravity .TOP ;
21582187 }
2188+ mNotificationPanelMinHeight =
2189+ res .getDimensionPixelSize (R .dimen .notification_panel_padding_top )
2190+ + res .getDimensionPixelSize (R .dimen .notification_panel_header_height )
2191+ + res .getDimensionPixelSize (R .dimen .close_handle_underlap )
2192+ + getNinePatchPadding (res .getDrawable (R .drawable .notification_panel_bg )).bottom ;
21592193
21602194 if (false ) Slog .v (TAG , "updateResources" );
21612195 }
21622196
2197+ private static Rect getNinePatchPadding (Drawable d ) {
2198+ Rect padding = new Rect ();
2199+ if (d instanceof NinePatchDrawable ) {
2200+ NinePatchDrawable ninePatch = (NinePatchDrawable ) d ;
2201+ ninePatch .getPadding (padding );
2202+ }
2203+ return padding ;
2204+ }
2205+
21632206 //
21642207 // tracing
21652208 //
0 commit comments