KeyButtonView.java revision 96f4818ef41141649337d4dee09f837594e93d09
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
19a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.animation.Animator;
20a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.animation.AnimatorSet;
21a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.animation.ObjectAnimator;
2286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.Context;
2386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.res.TypedArray;
2486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.graphics.drawable.AnimationDrawable;
2586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.graphics.drawable.Drawable;
26a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.graphics.Canvas;
27a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.graphics.RectF;
2886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.RemoteException;
2986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.SystemClock;
3086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.ServiceManager;
3186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.util.AttributeSet;
3286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.util.Slog;
33aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandlerimport android.view.accessibility.AccessibilityEvent;
34804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.HapticFeedbackConstants;
3586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.IWindowManager;
36bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brownimport android.view.InputDevice;
376b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.view.KeyCharacterMap;
3886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.KeyEvent;
3986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.MotionEvent;
40aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandlerimport android.view.SoundEffectConstants;
41a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.view.View;
42804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.ViewConfiguration;
43a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.view.ViewGroup;
4486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.widget.ImageView;
4586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.widget.RemoteViews.RemoteView;
4686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
4786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport com.android.systemui.R;
4886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
4986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratopublic class KeyButtonView extends ImageView {
50fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    private static final String TAG = "StatusBar.KeyButtonView";
51fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
5296f4818ef41141649337d4dee09f837594e93d09Daniel Sandler    final float GLOW_MAX_SCALE_FACTOR = 1.8f;
5396f4818ef41141649337d4dee09f837594e93d09Daniel Sandler
5486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    IWindowManager mWindowManager;
5586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    long mDownTime;
56ece945291e04ea8493895349ed95a2ab46b51c93Patrick Dubroy    boolean mSending;
5786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    int mCode;
5886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    int mRepeat;
59aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler    int mTouchSlop;
60a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    Drawable mGlowBG;
61a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    float mGlowAlpha = 0f, mGlowScale = 1f, mDrawingAlpha = 1f;
62aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler
63804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler    Runnable mCheckLongPress = new Runnable() {
64804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler        public void run() {
65804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler            if (isPressed()) {
66aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler
67a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                if (mCode != 0) {
68a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    mRepeat++;
69a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    sendEvent(KeyEvent.ACTION_DOWN,
70a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                            KeyEvent.FLAG_FROM_SYSTEM
71a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                            | KeyEvent.FLAG_VIRTUAL_HARD_KEY
72a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                            | KeyEvent.FLAG_LONG_PRESS);
73a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
74a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
75a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                } else {
76a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    // Just an old-fashioned ImageView
77a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    performLongClick();
78a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                }
79804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler            }
80804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler        }
81804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler    };
8286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public KeyButtonView(Context context, AttributeSet attrs) {
8486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        this(context, attrs, 0);
8586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
8686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public KeyButtonView(Context context, AttributeSet attrs, int defStyle) {
8886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        super(context, attrs);
8986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
9086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
9186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                defStyle, 0);
9286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
9386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
94a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
95a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground);
96a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG != null) {
97a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            mDrawingAlpha = 0.5f;
9886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        }
9986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
10086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        a.recycle();
10186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
10286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        mWindowManager = IWindowManager.Stub.asInterface(
10386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                ServiceManager.getService(Context.WINDOW_SERVICE));
104641bad449ba3b971500843c6bf7bf6f08363d09eJoe 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();
115a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            canvas.scale(mGlowScale, mGlowScale, w*0.5f, h*0.5f);
116a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            mGlowBG.setBounds(0, 0, w, h);
117a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            mGlowBG.setAlpha((int)(mGlowAlpha * 255));
118a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            mGlowBG.draw(canvas);
119a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            canvas.restore();
120a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
121a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            canvas.saveLayerAlpha(null, (int)(mDrawingAlpha * 255), Canvas.ALL_SAVE_FLAG);
122a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        }
123a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        super.onDraw(canvas);
124a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG != null) {
125a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            canvas.restore();
126a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        }
127a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
128a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
129a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public float getDrawingAlpha() {
130a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return 0;
131a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        return mDrawingAlpha;
132a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
133a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
134a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public void setDrawingAlpha(float x) {
135a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return;
136a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        mDrawingAlpha = x;
137a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        invalidate();
138a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
139a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
140a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public float getGlowAlpha() {
141a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return 0;
142a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        return mGlowAlpha;
143a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
144a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
145a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public void setGlowAlpha(float x) {
146a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return;
147a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        mGlowAlpha = x;
148a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        invalidate();
149a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
150a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
151a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public float getGlowScale() {
152a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return 0;
153a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        return mGlowScale;
154a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
155a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
156a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public void setGlowScale(float x) {
157a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG == null) return;
158a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        mGlowScale = x;
159a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        final float w = getWidth();
160a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        final float h = getHeight();
16196f4818ef41141649337d4dee09f837594e93d09Daniel Sandler        if (GLOW_MAX_SCALE_FACTOR <= 1.0f) {
16296f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            // this only works if we know the glow will never leave our bounds
163a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            invalidate();
164a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        } else {
16596f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
16696f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
167a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            com.android.systemui.SwipeHelper.invalidateGlobalRegion(
168a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    this,
1695298582717494098fcdf115d832c8e871340d0b5Daniel Sandler                    new RectF(getLeft() - rx,
1705298582717494098fcdf115d832c8e871340d0b5Daniel Sandler                              getTop() - ry,
1715298582717494098fcdf115d832c8e871340d0b5Daniel Sandler                              getRight() + rx,
1725298582717494098fcdf115d832c8e871340d0b5Daniel Sandler                              getBottom() + ry));
17396f4818ef41141649337d4dee09f837594e93d09Daniel Sandler
17496f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            // also invalidate our immediate parent to help avoid situations where nearby glows
17596f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            // interfere
17696f4818ef41141649337d4dee09f837594e93d09Daniel Sandler            ((View)getParent()).invalidate();
177a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        }
178a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
179a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
180a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    public void setPressed(boolean pressed) {
181a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        if (mGlowBG != null) {
182a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            if (pressed != isPressed()) {
183a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                AnimatorSet as = new AnimatorSet();
184a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                if (pressed) {
185a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    if (mGlowScale < 1.7f) mGlowScale = 1.7f;
186a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    if (mGlowAlpha < 0.5f) mGlowAlpha = 0.5f;
187a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    setDrawingAlpha(1f);
188a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    as.playTogether(
189a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
19096f4818ef41141649337d4dee09f837594e93d09Daniel Sandler                        ObjectAnimator.ofFloat(this, "glowScale", GLOW_MAX_SCALE_FACTOR)
191a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    );
192a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    as.setDuration(50);
193a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                } else {
194a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    as.playTogether(
195a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        ObjectAnimator.ofFloat(this, "glowAlpha", 0f),
196a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        ObjectAnimator.ofFloat(this, "glowScale", 1f),
197a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        ObjectAnimator.ofFloat(this, "drawingAlpha", 0.5f)
198a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    );
199a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    as.setDuration(500);
200a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                }
201a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                as.start();
202a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler            }
203a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        }
204a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler        super.setPressed(pressed);
205a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler    }
206a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
20786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public boolean onTouchEvent(MotionEvent ev) {
20886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        final int action = ev.getAction();
20986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        int x, y;
21086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
21186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        switch (action) {
21286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_DOWN:
2137a1a2f0e9273afbde398d9804cfaa245f6adbf5dChristopher Tate                //Slog.d("KeyButtonView", "press");
21486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                mDownTime = SystemClock.uptimeMillis();
21586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                mRepeat = 0;
21686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                mSending = true;
217bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown                sendEvent(KeyEvent.ACTION_DOWN,
218804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                        KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime);
219a101f8f6ef1c730f3f008256734cde54417e22ccDaniel Sandler                setPressed(true);
220804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                removeCallbacks(mCheckLongPress);
221804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
22286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
22386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_MOVE:
22486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                if (mSending) {
22586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                    x = (int)ev.getX();
22686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                    y = (int)ev.getY();
227aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler                    setPressed(x >= -mTouchSlop
228aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler                            && x < getWidth() + mTouchSlop
229aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler                            && y >= -mTouchSlop
230aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler                            && y < getHeight() + mTouchSlop);
23186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                }
23286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
23386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_CANCEL:
234804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                setPressed(false);
235ece945291e04ea8493895349ed95a2ab46b51c93Patrick Dubroy                if (mSending) {
23686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                    mSending = false;
237bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown                    sendEvent(KeyEvent.ACTION_UP,
238abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                            KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
239abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                                | KeyEvent.FLAG_CANCELED);
240abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                    removeCallbacks(mCheckLongPress);
241abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                }
242abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                break;
243abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato            case MotionEvent.ACTION_UP:
244aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler                final boolean doIt = isPressed();
245abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                setPressed(false);
246ece945291e04ea8493895349ed95a2ab46b51c93Patrick Dubroy                if (mSending) {
247abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                    mSending = false;
2485ee1a3daf0fb274b2a5fdea797748b569495a621Patrick Dubroy                    final int flags = KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY;
249804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                    removeCallbacks(mCheckLongPress);
250a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
251a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    if (mCode != 0) {
252a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        if (doIt) {
253a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                            sendEvent(KeyEvent.ACTION_UP, flags);
254a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
255a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                            playSoundEffect(SoundEffectConstants.CLICK);
256a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        } else {
257a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                            sendEvent(KeyEvent.ACTION_UP, flags | KeyEvent.FLAG_CANCELED);
258a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        }
2595ee1a3daf0fb274b2a5fdea797748b569495a621Patrick Dubroy                    } else {
260a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        // no key code, just a regular ImageView
261a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                        if (doIt) performClick();
262aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler                    }
26386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                }
26486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
26586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        }
26686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
26786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        return true;
26886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
26986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
270bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown    void sendEvent(int action, int flags) {
271bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown        sendEvent(action, flags, SystemClock.uptimeMillis());
27286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
27386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
274bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown    void sendEvent(int action, int flags, long when) {
275bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown        final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, mRepeat,
2766b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags, InputDevice.SOURCE_KEYBOARD);
27786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        try {
278fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            //Slog.d(TAG, "injecting event " + ev);
279bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown            mWindowManager.injectInputEventNoWait(ev);
28086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        } catch (RemoteException ex) {
28186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            // System process is dead
28286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        }
28386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
28486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato}
28586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
28686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
287