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
191ea49352cb01ffaac889c52de04571390d32fc31Annie Chinimport android.annotation.DrawableRes;
201ea49352cb01ffaac889c52de04571390d32fc31Annie Chinimport android.annotation.Nullable;
210c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monkimport android.app.ActivityManager;
2286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.Context;
233bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roosimport android.content.res.Configuration;
2486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.res.TypedArray;
258457ad89a851323288561d85ac86c6c26666c904Jason Monkimport android.graphics.drawable.Drawable;
268457ad89a851323288561d85ac86c6c26666c904Jason Monkimport android.graphics.drawable.Icon;
27ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.hardware.input.InputManager;
280c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monkimport android.media.AudioManager;
298457ad89a851323288561d85ac86c6c26666c904Jason Monkimport android.os.AsyncTask;
307beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggiimport android.os.Bundle;
3186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.SystemClock;
3286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.util.AttributeSet;
333bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roosimport android.util.TypedValue;
34804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.HapticFeedbackConstants;
35bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brownimport android.view.InputDevice;
366b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.view.KeyCharacterMap;
3786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.KeyEvent;
3886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.MotionEvent;
39aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandlerimport android.view.SoundEffectConstants;
4042310965fa2c0d2c91bea0a76730a21f6dd308a2Christian Robertsonimport android.view.View;
41804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.ViewConfiguration;
42de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.view.accessibility.AccessibilityEvent;
437beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggiimport android.view.accessibility.AccessibilityNodeInfo;
4486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.widget.ImageView;
4586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
4686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport com.android.systemui.R;
471ea49352cb01ffaac889c52de04571390d32fc31Annie Chinimport com.android.systemui.statusbar.phone.ButtonDispatcher;
4886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
497beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggiimport static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
507beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggiimport static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
517beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi
521ea49352cb01ffaac889c52de04571390d32fc31Annie Chinpublic class KeyButtonView extends ImageView implements ButtonDispatcher.ButtonInterface {
5396f4818ef41141649337d4dee09f837594e93d09Daniel Sandler
543bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos    private int mContentDescriptionRes;
55cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos    private long mDownTime;
56cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos    private int mCode;
57cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos    private int mTouchSlop;
58cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos    private boolean mSupportsLongpress = true;
590c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk    private AudioManager mAudioManager;
602fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi    private boolean mGestureAborted;
61053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi    private boolean mLongClicked;
6205bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi    private OnClickListener mOnClickListener;
63aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler
64cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos    private final Runnable mCheckLongPress = new Runnable() {
65804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler        public void run() {
66804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler            if (isPressed()) {
67cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock                // Log.d("KeyButtonView", "longpressed: " + this);
68815e057b9bb19acd77bf01ecb690b6e9fa85902eJason Monk                if (isLongClickable()) {
69a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    // Just an old-fashioned ImageView
70a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                    performLongClick();
71053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi                    mLongClicked = true;
727e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi                } else if (mSupportsLongpress) {
73815e057b9bb19acd77bf01ecb690b6e9fa85902eJason Monk                    sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
74815e057b9bb19acd77bf01ecb690b6e9fa85902eJason Monk                    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
75053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi                    mLongClicked = true;
76a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler                }
77804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler            }
78804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler        }
79804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler    };
8086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public KeyButtonView(Context context, AttributeSet attrs) {
8286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        this(context, attrs, 0);
8386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
8486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public KeyButtonView(Context context, AttributeSet attrs, int defStyle) {
8686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        super(context, attrs);
8786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
8986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                defStyle, 0);
9086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
9186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
92209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock
9344a4616bf780f131f8d78b46a075844800088860Daniel Sandler        mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
94a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler
953bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos        TypedValue value = new TypedValue();
963bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos        if (a.getValue(R.styleable.KeyButtonView_android_contentDescription, value)) {
973bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos            mContentDescriptionRes = value.resourceId;
983bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos        }
993bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos
10086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        a.recycle();
10186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
1023bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos
103641bad449ba3b971500843c6bf7bf6f08363d09eJoe Onorato        setClickable(true);
104aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
1050c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
106072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        setBackground(new KeyButtonRipple(context, this));
10786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
10886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
1098457ad89a851323288561d85ac86c6c26666c904Jason Monk    public void setCode(int code) {
1108457ad89a851323288561d85ac86c6c26666c904Jason Monk        mCode = code;
1118457ad89a851323288561d85ac86c6c26666c904Jason Monk    }
1128457ad89a851323288561d85ac86c6c26666c904Jason Monk
11305bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi    @Override
11405bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi    public void setOnClickListener(OnClickListener onClickListener) {
11505bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi        super.setOnClickListener(onClickListener);
11605bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi        mOnClickListener = onClickListener;
11705bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi    }
11805bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi
1198457ad89a851323288561d85ac86c6c26666c904Jason Monk    public void loadAsync(String uri) {
1208457ad89a851323288561d85ac86c6c26666c904Jason Monk        new AsyncTask<String, Void, Drawable>() {
1218457ad89a851323288561d85ac86c6c26666c904Jason Monk            @Override
1228457ad89a851323288561d85ac86c6c26666c904Jason Monk            protected Drawable doInBackground(String... params) {
1238457ad89a851323288561d85ac86c6c26666c904Jason Monk                return Icon.createWithContentUri(params[0]).loadDrawable(mContext);
1248457ad89a851323288561d85ac86c6c26666c904Jason Monk            }
1258457ad89a851323288561d85ac86c6c26666c904Jason Monk
1268457ad89a851323288561d85ac86c6c26666c904Jason Monk            @Override
1278457ad89a851323288561d85ac86c6c26666c904Jason Monk            protected void onPostExecute(Drawable drawable) {
1288457ad89a851323288561d85ac86c6c26666c904Jason Monk                setImageDrawable(drawable);
1298457ad89a851323288561d85ac86c6c26666c904Jason Monk            }
1308457ad89a851323288561d85ac86c6c26666c904Jason Monk        }.execute(uri);
1318457ad89a851323288561d85ac86c6c26666c904Jason Monk    }
1328457ad89a851323288561d85ac86c6c26666c904Jason Monk
1337beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi    @Override
1343bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos    protected void onConfigurationChanged(Configuration newConfig) {
1353bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos        super.onConfigurationChanged(newConfig);
1363bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos
1373bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos        if (mContentDescriptionRes != 0) {
1383bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos            setContentDescription(mContext.getString(mContentDescriptionRes));
1393bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos        }
1403bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos    }
1413bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos
1423bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos    @Override
1437beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
1447beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi        super.onInitializeAccessibilityNodeInfo(info);
1457beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi        if (mCode != 0) {
1467beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null));
1477e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi            if (mSupportsLongpress || isLongClickable()) {
1487beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi                info.addAction(
1497beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi                        new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null));
1507beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            }
1517beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi        }
1527beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi    }
1537beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi
1547beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi    @Override
155b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi    protected void onWindowVisibilityChanged(int visibility) {
156b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi        super.onWindowVisibilityChanged(visibility);
157b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi        if (visibility != View.VISIBLE) {
158b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi            jumpDrawablesToCurrentState();
159b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi        }
160b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi    }
161b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi
162b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi    @Override
163a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
1647beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi        if (action == ACTION_CLICK && mCode != 0) {
1657beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            sendEvent(KeyEvent.ACTION_DOWN, 0, SystemClock.uptimeMillis());
1667beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            sendEvent(KeyEvent.ACTION_UP, 0);
1677beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
1687beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            playSoundEffect(SoundEffectConstants.CLICK);
1697beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            return true;
1707e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi        } else if (action == ACTION_LONG_CLICK && mCode != 0) {
1717beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
1727beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            sendEvent(KeyEvent.ACTION_UP, 0);
1737beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
1747beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi            return true;
1757beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi        }
176a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        return super.performAccessibilityActionInternal(action, arguments);
1777beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi    }
1787beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi
17986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public boolean onTouchEvent(MotionEvent ev) {
18086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        final int action = ev.getAction();
18186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        int x, y;
1822fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi        if (action == MotionEvent.ACTION_DOWN) {
1832fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi            mGestureAborted = false;
1842fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi        }
1852fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi        if (mGestureAborted) {
1862fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi            return false;
1872fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi        }
18886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
18986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        switch (action) {
19086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_DOWN:
19186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                mDownTime = SystemClock.uptimeMillis();
192053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi                mLongClicked = false;
19344a4616bf780f131f8d78b46a075844800088860Daniel Sandler                setPressed(true);
19498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                if (mCode != 0) {
19598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
19698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                } else {
19798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    // Provide the same haptic feedback that the system offers for virtual keys.
19898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
19998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                }
20005bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi                playSoundEffect(SoundEffectConstants.CLICK);
2017e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi                removeCallbacks(mCheckLongPress);
2027e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi                postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
20386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
20486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_MOVE:
20598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                x = (int)ev.getX();
20698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                y = (int)ev.getY();
20798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                setPressed(x >= -mTouchSlop
20898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        && x < getWidth() + mTouchSlop
20998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        && y >= -mTouchSlop
21098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        && y < getHeight() + mTouchSlop);
21186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
21286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_CANCEL:
213804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                setPressed(false);
21498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                if (mCode != 0) {
21598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
21698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                }
2177e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi                removeCallbacks(mCheckLongPress);
218abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                break;
219abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato            case MotionEvent.ACTION_UP:
220053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi                final boolean doIt = isPressed() && !mLongClicked;
221abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                setPressed(false);
22298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                if (mCode != 0) {
22398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    if (doIt) {
22498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        sendEvent(KeyEvent.ACTION_UP, 0);
22598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
2265ee1a3daf0fb274b2a5fdea797748b569495a621Patrick Dubroy                    } else {
22798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                        sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
228aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler                    }
22998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                } else {
23098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    // no key code, just a regular ImageView
23105bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi                    if (doIt && mOnClickListener != null) {
23205bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi                        mOnClickListener.onClick(this);
23305bce15da90eb01f171b4ffcf0ec4f6a8175a728Jorim Jaggi                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
23498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                    }
23598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                }
2367e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi                removeCallbacks(mCheckLongPress);
23786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
23886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        }
23986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
24086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        return true;
24186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
24286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
2430c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk    public void playSoundEffect(int soundConstant) {
2440c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
2450c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk    };
2460c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk
247815e057b9bb19acd77bf01ecb690b6e9fa85902eJason Monk    public void sendEvent(int action, int flags) {
248bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown        sendEvent(action, flags, SystemClock.uptimeMillis());
24986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
25086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
251bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown    void sendEvent(int action, int flags, long when) {
25298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown        final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
25398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown        final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
25498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
25598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
25698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown                InputDevice.SOURCE_KEYBOARD);
2579f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown        InputManager.getInstance().injectInputEvent(ev,
2589f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
25986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
2602fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi
2611ea49352cb01ffaac889c52de04571390d32fc31Annie Chin    @Override
2622fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi    public void abortCurrentGesture() {
2632fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi        setPressed(false);
2642fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi        mGestureAborted = true;
2652fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi    }
2661ea49352cb01ffaac889c52de04571390d32fc31Annie Chin
2671ea49352cb01ffaac889c52de04571390d32fc31Annie Chin    @Override
2681ea49352cb01ffaac889c52de04571390d32fc31Annie Chin    public void setImageResource(@DrawableRes int resId) {
2691ea49352cb01ffaac889c52de04571390d32fc31Annie Chin        super.setImageResource(resId);
2701ea49352cb01ffaac889c52de04571390d32fc31Annie Chin    }
2711ea49352cb01ffaac889c52de04571390d32fc31Annie Chin
2721ea49352cb01ffaac889c52de04571390d32fc31Annie Chin    @Override
2731ea49352cb01ffaac889c52de04571390d32fc31Annie Chin    public void setImageDrawable(@Nullable Drawable drawable) {
2741ea49352cb01ffaac889c52de04571390d32fc31Annie Chin        super.setImageDrawable(drawable);
2751ea49352cb01ffaac889c52de04571390d32fc31Annie Chin    }
2766fc4600d6e74fa652215b63c687e725d952a523dAnnie Chin
2776fc4600d6e74fa652215b63c687e725d952a523dAnnie Chin    @Override
2786fc4600d6e74fa652215b63c687e725d952a523dAnnie Chin    public void setLandscape(boolean landscape) {
2796fc4600d6e74fa652215b63c687e725d952a523dAnnie Chin        //no op
2806fc4600d6e74fa652215b63c687e725d952a523dAnnie Chin    }
281389f091892a31f477ce557150ad096da84570583Annie Chin
282389f091892a31f477ce557150ad096da84570583Annie Chin    @Override
283389f091892a31f477ce557150ad096da84570583Annie Chin    public void setCarMode(boolean carMode) {
284389f091892a31f477ce557150ad096da84570583Annie Chin        // no op
285389f091892a31f477ce557150ad096da84570583Annie Chin    }
28686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato}
28786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
28886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
289