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