186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato/*
286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * Copyright (C) 2008 The Android Open Source Project
386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato *
486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * you may not use this file except in compliance with the License.
686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * You may obtain a copy of the License at
786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato *
886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato *
1086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * Unless required by applicable law or agreed to in writing, software
1186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
1286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * See the License for the specific language governing permissions and
1486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * limitations under the License.
1586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato */
1686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
17fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopackage com.android.systemui.statusbar.policy;
1886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
1989835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlockimport android.animation.Animator;
20a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.animation.AnimatorSet;
21a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.animation.ObjectAnimator;
2286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.Context;
2386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.res.TypedArray;
24a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.graphics.Canvas;
25a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.graphics.RectF;
26de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.graphics.drawable.Drawable;
27ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.hardware.input.InputManager;
2886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.SystemClock;
2986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.util.AttributeSet;
3089835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlockimport android.util.Log;
31804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.HapticFeedbackConstants;
32bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brownimport android.view.InputDevice;
336b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.view.KeyCharacterMap;
3486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.KeyEvent;
3586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.MotionEvent;
36aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandlerimport android.view.SoundEffectConstants;
37a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.view.View;
38804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.ViewConfiguration;
3956d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlockimport android.view.ViewDebug;
40de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.view.accessibility.AccessibilityEvent;
4186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.widget.ImageView;
4286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
4386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport com.android.systemui.R;
4486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
4586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratopublic class KeyButtonView extends ImageView {
46fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    private static final String TAG = "StatusBar.KeyButtonView";
4789835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock    private static final boolean DEBUG = false;
48fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
4996f4818ef41141649337d4dee09f837594e93d09Daniel Sandler    final float GLOW_MAX_SCALE_FACTOR = 1.8f;
5089835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock    public static final float DEFAULT_QUIESCENT_ALPHA = 0.70f;
5196f4818ef41141649337d4dee09f837594e93d09Daniel Sandler
5286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    long mDownTime;
5386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    int mCode;
54aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler    int mTouchSlop;
55a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    Drawable mGlowBG;
563fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler    int mGlowWidth, mGlowHeight;
5756d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock    float mGlowAlpha = 0f, mGlowScale = 1f;
5856d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock    @ViewDebug.ExportedProperty(category = "drawing")
5956d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock    float mDrawingAlpha = 1f;
6056d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock    @ViewDebug.ExportedProperty(category = "drawing")
6189835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock    float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA;
6244a4616bf780f131f8d78b46a075844800088860Daniel Sandler    boolean mSupportsLongpress = true;
6356d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock    RectF mRect = new RectF();
6460bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka    AnimatorSet mPressedAnim;
657edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    Animator mAnimateToQuiescent = new ObjectAnimator();
66aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler
67804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler    Runnable mCheckLongPress = new Runnable() {
68804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler        public void run() {
69804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler            if (isPressed()) {
70cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock                // Log.d("KeyButtonView", "longpressed: " + this);
71a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                if (mCode != 0) {
7298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
73a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
74a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                } else {
75a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    // Just an old-fashioned ImageView
76a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    performLongClick();
77a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                }
78804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler            }
79804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler        }
80804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler    };
8186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public KeyButtonView(Context context, AttributeSet attrs) {
8386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        this(context, attrs, 0);
8486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
8586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public KeyButtonView(Context context, AttributeSet attrs, int defStyle) {
8786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        super(context, attrs);
8886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
9086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                defStyle, 0);
9186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
9286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
93209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock
9444a4616bf780f131f8d78b46a075844800088860Daniel Sandler        mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
95a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
96a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground);
9756d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock        setDrawingAlpha(mQuiescentAlpha);
98a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG != null) {
993fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler            mGlowWidth = mGlowBG.getIntrinsicWidth();
1003fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler            mGlowHeight = mGlowBG.getIntrinsicHeight();
10186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        }
102209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock
10386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        a.recycle();
10486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
105641bad449ba3b971500843c6bf7bf6f08363d09eJoe Onorato        setClickable(true);
106aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
10786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
10886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
109a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    @Override
110a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    protected void onDraw(Canvas canvas) {
111a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG != null) {
112a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            canvas.save();
113a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            final int w = getWidth();
114a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            final int h = getHeight();
1153fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler            final float aspect = (float)mGlowWidth / mGlowHeight;
1163fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler            final int drawW = (int)(h*aspect);
1173fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler            final int drawH = h;
1183fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler            final int margin = (drawW-w)/2;
119a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            canvas.scale(mGlowScale, mGlowScale, w*0.5f, h*0.5f);
1203fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler            mGlowBG.setBounds(-margin, 0, drawW-margin, drawH);
1210b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka            mGlowBG.setAlpha((int)(mDrawingAlpha * mGlowAlpha * 255));
122a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            mGlowBG.draw(canvas);
123a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            canvas.restore();
124c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler            mRect.right = w;
125c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler            mRect.bottom = h;
126a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        }
127a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        super.onDraw(canvas);
128a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
129a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
1307edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    public void setQuiescentAlpha(float alpha, boolean animate) {
1317edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        mAnimateToQuiescent.cancel();
13289835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock        alpha = Math.min(Math.max(alpha, 0), 1);
13356d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock        if (alpha == mQuiescentAlpha && alpha == mDrawingAlpha) return;
13489835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock        mQuiescentAlpha = alpha;
13589835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock        if (DEBUG) Log.d(TAG, "New quiescent alpha = " + mQuiescentAlpha);
13656d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock        if (mGlowBG != null && animate) {
13756d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock            mAnimateToQuiescent = animateToQuiescent();
13856d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock            mAnimateToQuiescent.start();
13956d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock        } else {
14056d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock            setDrawingAlpha(mQuiescentAlpha);
14189835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock        }
14289835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock    }
14389835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock
1447edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    private ObjectAnimator animateToQuiescent() {
1457edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        return ObjectAnimator.ofFloat(this, "drawingAlpha", mQuiescentAlpha);
1467edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    }
1477edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
14856d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock    public float getQuiescentAlpha() {
14956d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock        return mQuiescentAlpha;
15056d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock    }
15156d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock
152a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public float getDrawingAlpha() {
153a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        return mDrawingAlpha;
154a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
155a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
156a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public void setDrawingAlpha(float x) {
1570b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka        // Calling setAlpha(int), which is an ImageView-specific
1580b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka        // method that's different from setAlpha(float). This sets
1590b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka        // the alpha on this ImageView's drawable directly
1600b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka        setAlpha((int) (x * 255));
161a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        mDrawingAlpha = x;
162a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
163a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
164a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public float getGlowAlpha() {
165a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return 0;
166a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        return mGlowAlpha;
167a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
168a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
169a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public void setGlowAlpha(float x) {
170a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return;
171a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        mGlowAlpha = x;
172a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        invalidate();
173a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
174a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
175a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public float getGlowScale() {
176a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return 0;
177a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        return mGlowScale;
178a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
179a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
180a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public void setGlowScale(float x) {
181a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return;
182a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        mGlowScale = x;
183a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        final float w = getWidth();
184a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        final float h = getHeight();
18596f4818ef41141649337d4dee09f837594e93d09Daniel Sandler        if (GLOW_MAX_SCALE_FACTOR <= 1.0f) {
18696f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            // this only works if we know the glow will never leave our bounds
187a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            invalidate();
188a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        } else {
18996f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
19096f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
191a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            com.android.systemui.SwipeHelper.invalidateGlobalRegion(
192a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    this,
1935298582717494098fcdf115d832c8e871340d0b5Daniel Sandler                    new RectF(getLeft() - rx,
1945298582717494098fcdf115d832c8e871340d0b5Daniel Sandler                              getTop() - ry,
1955298582717494098fcdf115d832c8e871340d0b5Daniel Sandler                              getRight() + rx,
1965298582717494098fcdf115d832c8e871340d0b5Daniel Sandler                              getBottom() + ry));
19796f4818ef41141649337d4dee09f837594e93d09Daniel Sandler
19896f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            // also invalidate our immediate parent to help avoid situations where nearby glows
19996f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            // interfere
20096f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            ((View)getParent()).invalidate();
201a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        }
202a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
203a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
204a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public void setPressed(boolean pressed) {
205a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG != null) {
206a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            if (pressed != isPressed()) {
20760bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka                if (mPressedAnim != null && mPressedAnim.isRunning()) {
20860bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka                    mPressedAnim.cancel();
20960bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka                }
21060bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka                final AnimatorSet as = mPressedAnim = new AnimatorSet();
211a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                if (pressed) {
212209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock                    if (mGlowScale < GLOW_MAX_SCALE_FACTOR)
213bceff71b9231643090d0dad6e3f1e1aac6fda1a2Justin Ho                        mGlowScale = GLOW_MAX_SCALE_FACTOR;
21489835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock                    if (mGlowAlpha < mQuiescentAlpha)
21589835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock                        mGlowAlpha = mQuiescentAlpha;
216a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    setDrawingAlpha(1f);
217a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    as.playTogether(
218a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
21996f4818ef41141649337d4dee09f837594e93d09Daniel Sandler                        ObjectAnimator.ofFloat(this, "glowScale", GLOW_MAX_SCALE_FACTOR)
220a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    );
221a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    as.setDuration(50);
222a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                } else {
2237edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                    mAnimateToQuiescent.cancel();
2247edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                    mAnimateToQuiescent = animateToQuiescent();
225a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    as.playTogether(
226a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        ObjectAnimator.ofFloat(this, "glowAlpha", 0f),
227a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        ObjectAnimator.ofFloat(this, "glowScale", 1f),
2287edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                        mAnimateToQuiescent
229a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    );
230a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    as.setDuration(500);
231a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                }
232a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                as.start();
233a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            }
234a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        }
235a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        super.setPressed(pressed);
236a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
237a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
23886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public boolean onTouchEvent(MotionEvent ev) {
23986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        final int action = ev.getAction();
24086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        int x, y;
24186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
24286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        switch (action) {
24386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_DOWN:
244cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock                //Log.d("KeyButtonView", "press");
24586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                mDownTime = SystemClock.uptimeMillis();
24644a4616bf780f131f8d78b46a075844800088860Daniel Sandler                setPressed(true);
24798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                if (mCode != 0) {
24898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
24998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                } else {
25098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    // Provide the same haptic feedback that the system offers for virtual keys.
25198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
25298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                }
25344a4616bf780f131f8d78b46a075844800088860Daniel Sandler                if (mSupportsLongpress) {
25444a4616bf780f131f8d78b46a075844800088860Daniel Sandler                    removeCallbacks(mCheckLongPress);
25544a4616bf780f131f8d78b46a075844800088860Daniel Sandler                    postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
25644a4616bf780f131f8d78b46a075844800088860Daniel Sandler                }
25786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
25886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_MOVE:
25998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                x = (int)ev.getX();
26098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                y = (int)ev.getY();
26198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                setPressed(x >= -mTouchSlop
26298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        && x < getWidth() + mTouchSlop
26398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        && y >= -mTouchSlop
26498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        && y < getHeight() + mTouchSlop);
26586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
26686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_CANCEL:
267804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                setPressed(false);
26898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                if (mCode != 0) {
26998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
27098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                }
27198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                if (mSupportsLongpress) {
27298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    removeCallbacks(mCheckLongPress);
273abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                }
274abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                break;
275abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato            case MotionEvent.ACTION_UP:
276aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler                final boolean doIt = isPressed();
277abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                setPressed(false);
27898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                if (mCode != 0) {
27998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    if (doIt) {
28098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        sendEvent(KeyEvent.ACTION_UP, 0);
28198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
28298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        playSoundEffect(SoundEffectConstants.CLICK);
2835ee1a3daf0fb274b2a5fdea797748b569495a621Patrick Dubroy                    } else {
28498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
285aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler                    }
28698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                } else {
28798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    // no key code, just a regular ImageView
28898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    if (doIt) {
28998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        performClick();
29098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    }
29198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                }
29298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                if (mSupportsLongpress) {
29398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    removeCallbacks(mCheckLongPress);
29486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                }
29586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
29686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        }
29786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
29886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        return true;
29986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
30086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
301bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown    void sendEvent(int action, int flags) {
302bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown        sendEvent(action, flags, SystemClock.uptimeMillis());
30386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
30486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
305bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown    void sendEvent(int action, int flags, long when) {
30698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown        final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
30798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown        final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
30898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
30998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
31098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                InputDevice.SOURCE_KEYBOARD);
3119f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown        InputManager.getInstance().injectInputEvent(ev,
3129f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
31386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
31486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato}
31586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
31686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
317