1a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn/* 2a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * Copyright (C) 2012 The Android Open Source Project 3a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * 4a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * you may not use this file except in compliance with the License. 6a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * You may obtain a copy of the License at 7a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * 8a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * 10a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * Unless required by applicable law or agreed to in writing, software 11a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * See the License for the specific language governing permissions and 14a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn * limitations under the License. 15a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn */ 16a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 17a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornpackage com.android.systemui; 18a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 19a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.app.ActivityManager; 20a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.content.Context; 21a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.content.res.Configuration; 22a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.content.res.Resources; 23a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.graphics.Matrix; 24a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.graphics.PixelFormat; 25a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.os.RemoteException; 26a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.util.Log; 27a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.util.Slog; 28a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.view.Choreographer; 29a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.view.Display; 30a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.view.IWindowSession; 31a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.view.MotionEvent; 32a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.view.VelocityTracker; 33a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.view.View; 34a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.view.ViewRootImpl; 35a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.view.WindowManager; 3698365d7663cbd82979a5700faf0050220b01084dJeff Brownimport android.view.WindowManagerGlobal; 37a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.view.animation.Transformation; 38a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornimport android.widget.FrameLayout; 39a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 40a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackbornpublic class UniverseBackground extends FrameLayout { 41a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn static final String TAG = "UniverseBackground"; 42a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn static final boolean SPEW = false; 43a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn static final boolean CHATTY = false; 44a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 45a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final IWindowSession mSession; 46a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final View mContent; 47a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final View mBottomAnchor; 48a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 49a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final Runnable mAnimationCallback = new Runnable() { 50a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn @Override 51a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn public void run() { 52a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn doAnimation(mChoreographer.getFrameTimeNanos()); 53a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 54a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn }; 55a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 56a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // fling gesture tuning parameters, scaled to display density 57a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mSelfExpandVelocityPx; // classic value: 2000px/s 58a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up") 59a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mFlingExpandMinVelocityPx; // classic value: 200px/s 60a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mFlingCollapseMinVelocityPx; // classic value: 200px/s 61a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1) 62a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand) 63a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s 64a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 65a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mExpandAccelPx; // classic value: 2000px/s/s 66a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up") 67a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 68a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn static final int STATE_CLOSED = 0; 69a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn static final int STATE_OPENING = 1; 70a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn static final int STATE_OPEN = 2; 71a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private int mState = STATE_CLOSED; 72a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 73a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mDragStartX, mDragStartY; 74a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mAverageX, mAverageY; 75a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 76a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // position 77a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private int[] mPositionTmp = new int[2]; 78a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private boolean mExpanded; 79a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private boolean mExpandedVisible; 80a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 81a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private boolean mTracking; 82a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private VelocityTracker mVelocityTracker; 83a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 84a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private Choreographer mChoreographer; 85a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private boolean mAnimating; 86a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private boolean mClosing; // only valid when mAnimating; indicates the initial acceleration 87a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mAnimY; 88a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mAnimVel; 89a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private float mAnimAccel; 90a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private long mAnimLastTimeNanos; 91a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private boolean mAnimatingReveal = false; 92a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 93a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private int mYDelta = 0; 94a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private Transformation mUniverseTransform = new Transformation(); 95a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private final float[] mTmpFloats = new float[9]; 96a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 97a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn public UniverseBackground(Context context) { 98a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn super(context); 99a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn setBackgroundColor(0xff000000); 100f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mSession = WindowManagerGlobal.getWindowSession(); 101a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mContent = View.inflate(context, R.layout.universe, null); 102a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn addView(mContent); 103a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mContent.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() { 104a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn @Override public void onClick(View v) { 105a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn animateCollapse(); 106a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 107a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn }); 108a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mBottomAnchor = mContent.findViewById(R.id.bottom); 109a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mChoreographer = Choreographer.getInstance(); 110a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn loadDimens(); 111a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 112a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 113a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn @Override 114a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn protected void onConfigurationChanged(Configuration newConfig) { 115a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn super.onConfigurationChanged(newConfig); 116a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn loadDimens(); 117a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 118a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 119a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private void loadDimens() { 120a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final Resources res = getContext().getResources(); 121a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity); 122a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity); 123a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity); 124a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity); 125a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 126a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1); 127a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1); 128a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 129a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mExpandAccelPx = res.getDimension(R.dimen.expand_accel); 130a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel); 131a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 132a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity); 133a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 134a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 135a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private void computeAveragePos(MotionEvent event) { 136a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final int num = event.getPointerCount(); 137a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn float x = 0, y = 0; 138a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn for (int i=0; i<num; i++) { 139a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn x += event.getX(i); 140a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn y += event.getY(i); 141a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 142a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAverageX = x / num; 143a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAverageY = y / num; 144a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 145a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 146a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private void sendUniverseTransform() { 147a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (getWindowToken() != null) { 148a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mUniverseTransform.getMatrix().getValues(mTmpFloats); 149a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn try { 150a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mSession.setUniverseTransform(getWindowToken(), mUniverseTransform.getAlpha(), 151a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y], 152a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], 153a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); 154a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } catch (RemoteException e) { 155a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 156a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 157a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 158a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 15998365d7663cbd82979a5700faf0050220b01084dJeff Brown public WindowManager.LayoutParams getLayoutParams() { 160a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 161a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 162a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND, 163a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 0 164a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 165a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 166a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 167a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn PixelFormat.OPAQUE); 168a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // this will allow the window to run in an overlay on devices that support this 16998365d7663cbd82979a5700faf0050220b01084dJeff Brown if (ActivityManager.isHighEndGfx()) { 170a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 171a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 172a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn lp.setTitle("UniverseBackground"); 173a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn lp.windowAnimations = 0; 174a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return lp; 175a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 176a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 177a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private int getExpandedViewMaxHeight() { 178a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return mBottomAnchor.getTop(); 179a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 180a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 181a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn public void animateCollapse() { 182a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn animateCollapse(1.0f); 183a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 184a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 185a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn public void animateCollapse(float velocityMultiplier) { 186a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (SPEW) { 187a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded 188a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn + " mExpandedVisible=" + mExpandedVisible 189a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn + " mExpanded=" + mExpanded 190a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn + " mAnimating=" + mAnimating 191a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn + " mAnimY=" + mAnimY 192a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn + " mAnimVel=" + mAnimVel); 193a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 194a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 195a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mState = STATE_CLOSED; 196a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (!mExpandedVisible) { 197a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return; 198a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 199a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 200a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn int y; 201a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mAnimating) { 202a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn y = (int)mAnimY; 203a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } else { 204a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn y = getExpandedViewMaxHeight()-1; 205a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 206a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // Let the fling think that we're open so it goes in the right direction 207a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // and doesn't try to re-open the windowshade. 208a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mExpanded = true; 209a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn prepareTracking(y, false); 210a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn performFling(y, -mSelfCollapseVelocityPx*velocityMultiplier, true); 211a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 212a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 213a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private void updateUniverseScale() { 214a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mYDelta > 0) { 215a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn int w = getWidth(); 216a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn int h = getHeight(); 217a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn float scale = (h-mYDelta+.5f) / (float)h; 218a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mUniverseTransform.getMatrix().setScale(scale, scale, w/2, h); 219a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (CHATTY) Log.i(TAG, "w=" + w + " h=" + h + " scale=" + scale 220a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn + ": " + mUniverseTransform); 221a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn sendUniverseTransform(); 222a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (getVisibility() != VISIBLE) { 223a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn setVisibility(VISIBLE); 224a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 225a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } else { 226a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (CHATTY) Log.i(TAG, "mYDelta=" + mYDelta); 227a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mUniverseTransform.clear(); 228a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn sendUniverseTransform(); 229a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (getVisibility() == VISIBLE) { 230a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn setVisibility(GONE); 231a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 232a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 233a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 234a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 235a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn void resetLastAnimTime() { 236a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimLastTimeNanos = System.nanoTime(); 237a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (SPEW) { 238a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn Throwable t = new Throwable(); 239a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn t.fillInStackTrace(); 240a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn Slog.d(TAG, "resetting last anim time=" + mAnimLastTimeNanos, t); 241a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 242a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 243a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 244a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn void doAnimation(long frameTimeNanos) { 245a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mAnimating) { 246a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (SPEW) Slog.d(TAG, "doAnimation dt=" + (frameTimeNanos - mAnimLastTimeNanos)); 247a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY); 248a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn incrementAnim(frameTimeNanos); 249a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (SPEW) { 250a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn Slog.d(TAG, "doAnimation after mAnimY=" + mAnimY); 251a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 252a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 253a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mAnimY >= getExpandedViewMaxHeight()-1 && !mClosing) { 254a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (SPEW) Slog.d(TAG, "Animation completed to expanded state."); 255a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimating = false; 256a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mYDelta = getExpandedViewMaxHeight(); 257a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn updateUniverseScale(); 258a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mExpanded = true; 259a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mState = STATE_OPEN; 260a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return; 261a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 262a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 263a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mAnimY <= 0 && mClosing) { 264a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (SPEW) Slog.d(TAG, "Animation completed to collapsed state."); 265a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimating = false; 266a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mYDelta = 0; 267a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn updateUniverseScale(); 268a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mExpanded = false; 269a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mState = STATE_CLOSED; 270a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return; 271a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 272a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 273a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mYDelta = (int)mAnimY; 274a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn updateUniverseScale(); 275a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, 276a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimationCallback, null); 277a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 278a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 279a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 280a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn void stopTracking() { 281a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mTracking = false; 282a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mVelocityTracker.recycle(); 283a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mVelocityTracker = null; 284a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 285a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 286a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn void incrementAnim(long frameTimeNanos) { 287a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final long deltaNanos = Math.max(frameTimeNanos - mAnimLastTimeNanos, 0); 288a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final float t = deltaNanos * 0.000000001f; // ns -> s 289a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final float y = mAnimY; 290a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final float v = mAnimVel; // px/s 291a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn final float a = mAnimAccel; // px/s/s 292a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimY = y + (v*t) + (0.5f*a*t*t); // px 293a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimVel = v + (a*t); // px/s 294a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimLastTimeNanos = frameTimeNanos; // ns 295a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY 296a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // + " mAnimAccel=" + mAnimAccel); 297a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 298a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 299a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn void prepareTracking(int y, boolean opening) { 300a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (CHATTY) { 301a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn Slog.d(TAG, "panel: beginning to track the user's touch, y=" + y + " opening=" + opening); 302a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 303a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 304a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mTracking = true; 305a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mVelocityTracker = VelocityTracker.obtain(); 306a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (opening) { 307a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimAccel = mExpandAccelPx; 308a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimVel = mFlingExpandMinVelocityPx; 309a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimY = y; 310a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimating = true; 311a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimatingReveal = true; 312a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn resetLastAnimTime(); 313a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mExpandedVisible = true; 314a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 315a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mAnimating) { 316a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimating = false; 317a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, 318a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimationCallback, null); 319a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 320a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 321a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 322a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn void performFling(int y, float vel, boolean always) { 323a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (CHATTY) { 324a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn Slog.d(TAG, "panel: will fling, y=" + y + " vel=" + vel); 325a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 326a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 327a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimatingReveal = false; 328a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 329a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimY = y; 330a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimVel = vel; 331a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 332a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel); 333a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 334a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mExpanded) { 335a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (!always && ( 336a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn vel > mFlingCollapseMinVelocityPx 337a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn || (y > (getExpandedViewMaxHeight()*(1f-mCollapseMinDisplayFraction)) && 338a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn vel > -mFlingExpandMinVelocityPx))) { 339a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // We are expanded, but they didn't move sufficiently to cause 340a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // us to retract. Animate back to the expanded position. 341a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimAccel = mExpandAccelPx; 342a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (vel < 0) { 343a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimVel = 0; 344a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 345a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 346a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn else { 347a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // We are expanded and are now going to animate away. 348a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimAccel = -mCollapseAccelPx; 349a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (vel > 0) { 350a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimVel = 0; 351a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 352a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 353a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } else { 354a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (always || ( 355a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn vel > mFlingExpandMinVelocityPx 356a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn || (y > (getExpandedViewMaxHeight()*(1f-mExpandMinDisplayFraction)) && 357a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn vel > -mFlingCollapseMinVelocityPx))) { 358a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // We are collapsed, and they moved enough to allow us to 359a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // expand. Animate in the notifications. 360a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimAccel = mExpandAccelPx; 361a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (vel < 0) { 362a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimVel = 0; 363a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 364a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 365a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn else { 366a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // We are collapsed, but they didn't move sufficiently to cause 367a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // us to retract. Animate back to the collapsed position. 368a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimAccel = -mCollapseAccelPx; 369a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (vel > 0) { 370a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimVel = 0; 371a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 372a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 373a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 374a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel 375a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // + " mAnimAccel=" + mAnimAccel); 376a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 377a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn resetLastAnimTime(); 378a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimating = true; 379a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mClosing = mAnimAccel < 0; 380a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, 381a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimationCallback, null); 382a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, 383a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mAnimationCallback, null); 384a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 385a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn stopTracking(); 386a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 387a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 388a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn private void trackMovement(MotionEvent event) { 389a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mVelocityTracker.addMovement(event); 390a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 391a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 392a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn public boolean consumeEvent(MotionEvent event) { 393a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mState == STATE_CLOSED) { 394a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { 395a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn // Second finger down, time to start opening! 396a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn computeAveragePos(event); 397a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mDragStartX = mAverageX; 398a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mDragStartY = mAverageY; 399a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mYDelta = 0; 400a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mUniverseTransform.clear(); 401a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn sendUniverseTransform(); 402a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn setVisibility(VISIBLE); 403a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mState = STATE_OPENING; 404a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn prepareTracking((int)mDragStartY, true); 405a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mVelocityTracker.clear(); 406a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn trackMovement(event); 407a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return true; 408a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 409a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return false; 410a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 411a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 412a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mState == STATE_OPENING) { 413a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (event.getActionMasked() == MotionEvent.ACTION_UP 414a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn || event.getActionMasked() == MotionEvent.ACTION_CANCEL) { 415a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mVelocityTracker.computeCurrentVelocity(1000); 416a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn computeAveragePos(event); 417a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 418a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn float yVel = mVelocityTracker.getYVelocity(); 419a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn boolean negative = yVel < 0; 420a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 421a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn float xVel = mVelocityTracker.getXVelocity(); 422a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (xVel < 0) { 423a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn xVel = -xVel; 424a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 425a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (xVel > mFlingGestureMaxXVelocityPx) { 426a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn xVel = mFlingGestureMaxXVelocityPx; // limit how much we care about the x axis 427a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 428a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 429a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn float vel = (float)Math.hypot(yVel, xVel); 430a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (negative) { 431a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn vel = -vel; 432a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 433a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 434a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (CHATTY) { 435a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn Slog.d(TAG, String.format("gesture: vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f", 436a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mVelocityTracker.getXVelocity(), 437a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mVelocityTracker.getYVelocity(), 438a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn xVel, yVel, 439a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn vel)); 440a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 441a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 442a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn performFling((int)mAverageY, vel, false); 443a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mState = STATE_OPEN; 444a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return true; 445a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 446a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 447a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn computeAveragePos(event); 448a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mYDelta = (int)(mAverageY - mDragStartY); 449a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn if (mYDelta > getExpandedViewMaxHeight()) { 450a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn mYDelta = getExpandedViewMaxHeight(); 451a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 452a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn updateUniverseScale(); 453a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return true; 454a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 455a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn 456a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn return false; 457a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn } 458a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn} 459