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 190c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monkimport android.app.ActivityManager; 2086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.Context; 213bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roosimport android.content.res.Configuration; 2286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.res.TypedArray; 238457ad89a851323288561d85ac86c6c26666c904Jason Monkimport android.graphics.drawable.Drawable; 248457ad89a851323288561d85ac86c6c26666c904Jason Monkimport android.graphics.drawable.Icon; 25ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.hardware.input.InputManager; 260c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monkimport android.media.AudioManager; 278457ad89a851323288561d85ac86c6c26666c904Jason Monkimport android.os.AsyncTask; 287beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggiimport android.os.Bundle; 2986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.SystemClock; 3086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.util.AttributeSet; 313bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roosimport android.util.TypedValue; 32804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.HapticFeedbackConstants; 33bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brownimport android.view.InputDevice; 346b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.view.KeyCharacterMap; 3586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.KeyEvent; 3686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.MotionEvent; 37aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandlerimport android.view.SoundEffectConstants; 3842310965fa2c0d2c91bea0a76730a21f6dd308a2Christian Robertsonimport android.view.View; 39804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.ViewConfiguration; 40de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.view.accessibility.AccessibilityEvent; 417beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggiimport android.view.accessibility.AccessibilityNodeInfo; 4286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.widget.ImageView; 4386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 4486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport com.android.systemui.R; 4586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 467beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggiimport static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; 477beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggiimport static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; 487beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi 4986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratopublic class KeyButtonView extends ImageView { 5096f4818ef41141649337d4dee09f837594e93d09Daniel Sandler 513bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos private int mContentDescriptionRes; 52cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos private long mDownTime; 53cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos private int mCode; 54cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos private int mTouchSlop; 55cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos private boolean mSupportsLongpress = true; 560c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk private AudioManager mAudioManager; 572fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi private boolean mGestureAborted; 58053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi private boolean mLongClicked; 59aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler 60cde52d77ebfee9229fa39cc0d8a0e6ad0c839212Adrian Roos private final Runnable mCheckLongPress = new Runnable() { 61804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler public void run() { 62804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler if (isPressed()) { 63cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock // Log.d("KeyButtonView", "longpressed: " + this); 64815e057b9bb19acd77bf01ecb690b6e9fa85902eJason Monk if (isLongClickable()) { 65a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler // Just an old-fashioned ImageView 66a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler performLongClick(); 67053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi mLongClicked = true; 687e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi } else if (mSupportsLongpress) { 69815e057b9bb19acd77bf01ecb690b6e9fa85902eJason Monk sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); 70815e057b9bb19acd77bf01ecb690b6e9fa85902eJason Monk sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); 71053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi mLongClicked = true; 72a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 73804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler } 74804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler } 75804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler }; 7686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 7786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato public KeyButtonView(Context context, AttributeSet attrs) { 7886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato this(context, attrs, 0); 7986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 8086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 8186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato public KeyButtonView(Context context, AttributeSet attrs, int defStyle) { 8286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato super(context, attrs); 8386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 8486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView, 8586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato defStyle, 0); 8686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 8786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0); 88209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 8944a4616bf780f131f8d78b46a075844800088860Daniel Sandler mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true); 90a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 913bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos TypedValue value = new TypedValue(); 923bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos if (a.getValue(R.styleable.KeyButtonView_android_contentDescription, value)) { 933bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos mContentDescriptionRes = value.resourceId; 943bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos } 953bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos 9686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato a.recycle(); 9786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 983bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos 99641bad449ba3b971500843c6bf7bf6f08363d09eJoe Onorato setClickable(true); 100aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 1010c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 102072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi setBackground(new KeyButtonRipple(context, this)); 10386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 10486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 1058457ad89a851323288561d85ac86c6c26666c904Jason Monk public void setCode(int code) { 1068457ad89a851323288561d85ac86c6c26666c904Jason Monk mCode = code; 1078457ad89a851323288561d85ac86c6c26666c904Jason Monk } 1088457ad89a851323288561d85ac86c6c26666c904Jason Monk 1098457ad89a851323288561d85ac86c6c26666c904Jason Monk public void loadAsync(String uri) { 1108457ad89a851323288561d85ac86c6c26666c904Jason Monk new AsyncTask<String, Void, Drawable>() { 1118457ad89a851323288561d85ac86c6c26666c904Jason Monk @Override 1128457ad89a851323288561d85ac86c6c26666c904Jason Monk protected Drawable doInBackground(String... params) { 1138457ad89a851323288561d85ac86c6c26666c904Jason Monk return Icon.createWithContentUri(params[0]).loadDrawable(mContext); 1148457ad89a851323288561d85ac86c6c26666c904Jason Monk } 1158457ad89a851323288561d85ac86c6c26666c904Jason Monk 1168457ad89a851323288561d85ac86c6c26666c904Jason Monk @Override 1178457ad89a851323288561d85ac86c6c26666c904Jason Monk protected void onPostExecute(Drawable drawable) { 1188457ad89a851323288561d85ac86c6c26666c904Jason Monk setImageDrawable(drawable); 1198457ad89a851323288561d85ac86c6c26666c904Jason Monk } 1208457ad89a851323288561d85ac86c6c26666c904Jason Monk }.execute(uri); 1218457ad89a851323288561d85ac86c6c26666c904Jason Monk } 1228457ad89a851323288561d85ac86c6c26666c904Jason Monk 1237beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi @Override 1243bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos protected void onConfigurationChanged(Configuration newConfig) { 1253bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos super.onConfigurationChanged(newConfig); 1263bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos 1273bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos if (mContentDescriptionRes != 0) { 1283bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos setContentDescription(mContext.getString(mContentDescriptionRes)); 1293bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos } 1303bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos } 1313bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos 1323bab515b19da755e0e59c6be83fd92b3ac8d8ea3Adrian Roos @Override 1337beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 1347beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi super.onInitializeAccessibilityNodeInfo(info); 1357beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi if (mCode != 0) { 1367beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null)); 1377e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi if (mSupportsLongpress || isLongClickable()) { 1387beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi info.addAction( 1397beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null)); 1407beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi } 1417beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi } 1427beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi } 1437beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi 1447beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi @Override 145b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi protected void onWindowVisibilityChanged(int visibility) { 146b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi super.onWindowVisibilityChanged(visibility); 147b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi if (visibility != View.VISIBLE) { 148b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi jumpDrawablesToCurrentState(); 149b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi } 150b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi } 151b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi 152b9e290c7136fb7c76b7238426ccd598dec2d2643Jorim Jaggi @Override 153a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette public boolean performAccessibilityActionInternal(int action, Bundle arguments) { 1547beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi if (action == ACTION_CLICK && mCode != 0) { 1557beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi sendEvent(KeyEvent.ACTION_DOWN, 0, SystemClock.uptimeMillis()); 1567beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi sendEvent(KeyEvent.ACTION_UP, 0); 1577beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); 1587beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi playSoundEffect(SoundEffectConstants.CLICK); 1597beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi return true; 1607e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi } else if (action == ACTION_LONG_CLICK && mCode != 0) { 1617beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); 1627beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi sendEvent(KeyEvent.ACTION_UP, 0); 1637beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); 1647beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi return true; 1657beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi } 166a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette return super.performAccessibilityActionInternal(action, arguments); 1677beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi } 1687beadfc714565be2d5f383993bb8cfc8e8f9c118Jorim Jaggi 16986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato public boolean onTouchEvent(MotionEvent ev) { 17086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato final int action = ev.getAction(); 17186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato int x, y; 1722fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi if (action == MotionEvent.ACTION_DOWN) { 1732fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi mGestureAborted = false; 1742fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi } 1752fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi if (mGestureAborted) { 1762fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi return false; 1772fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi } 17886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 17986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato switch (action) { 18086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato case MotionEvent.ACTION_DOWN: 18186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato mDownTime = SystemClock.uptimeMillis(); 182053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi mLongClicked = false; 18344a4616bf780f131f8d78b46a075844800088860Daniel Sandler setPressed(true); 18498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mCode != 0) { 18598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime); 18698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } else { 18798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown // Provide the same haptic feedback that the system offers for virtual keys. 18898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); 18998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 1907e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi removeCallbacks(mCheckLongPress); 1917e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); 19286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato break; 19386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato case MotionEvent.ACTION_MOVE: 19498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown x = (int)ev.getX(); 19598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown y = (int)ev.getY(); 19698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown setPressed(x >= -mTouchSlop 19798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown && x < getWidth() + mTouchSlop 19898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown && y >= -mTouchSlop 19998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown && y < getHeight() + mTouchSlop); 20086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato break; 20186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato case MotionEvent.ACTION_CANCEL: 202804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler setPressed(false); 20398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mCode != 0) { 20498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED); 20598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 2067e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi removeCallbacks(mCheckLongPress); 207abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato break; 208abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato case MotionEvent.ACTION_UP: 209053f21864a731128c2974e89253dd67ed64271d0Jorim Jaggi final boolean doIt = isPressed() && !mLongClicked; 210abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato setPressed(false); 21198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mCode != 0) { 21298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (doIt) { 21398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_UP, 0); 21498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); 21598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown playSoundEffect(SoundEffectConstants.CLICK); 2165ee1a3daf0fb274b2a5fdea797748b569495a621Patrick Dubroy } else { 21798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED); 218aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler } 21998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } else { 22098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown // no key code, just a regular ImageView 22198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (doIt) { 22298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown performClick(); 22398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 22498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 2257e6571f13da776dca4966dee0159e7741102fca9Jorim Jaggi removeCallbacks(mCheckLongPress); 22686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato break; 22786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 22886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 22986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato return true; 23086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 23186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 2320c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk public void playSoundEffect(int soundConstant) { 2330c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser()); 2340c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk }; 2350c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk 236815e057b9bb19acd77bf01ecb690b6e9fa85902eJason Monk public void sendEvent(int action, int flags) { 237bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown sendEvent(action, flags, SystemClock.uptimeMillis()); 23886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 23986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 240bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown void sendEvent(int action, int flags, long when) { 24198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0; 24298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount, 24398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 24498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, 24598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown InputDevice.SOURCE_KEYBOARD); 2469f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown InputManager.getInstance().injectInputEvent(ev, 2479f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 24886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 2492fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi 2502fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi public void abortCurrentGesture() { 2512fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi setPressed(false); 2522fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi mGestureAborted = true; 2532fdeeabe78b0f54f3163b1b3741ac813828b3511Jorim Jaggi } 25486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato} 25586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 25686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 257