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.AnimatorSet; 20a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.animation.ObjectAnimator; 2186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.Context; 2286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.res.TypedArray; 2386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.graphics.drawable.Drawable; 24a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.graphics.Canvas; 25a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.graphics.RectF; 26ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.hardware.input.InputManager; 2786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.RemoteException; 2886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.SystemClock; 2986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.ServiceManager; 3086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.util.AttributeSet; 31aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandlerimport android.view.accessibility.AccessibilityEvent; 32804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.HapticFeedbackConstants; 3386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.IWindowManager; 34bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brownimport android.view.InputDevice; 356b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.view.KeyCharacterMap; 3686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.KeyEvent; 3786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.MotionEvent; 38aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandlerimport android.view.SoundEffectConstants; 39a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.view.View; 40804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.ViewConfiguration; 4186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.widget.ImageView; 4286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 4386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport com.android.systemui.R; 4486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 4586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratopublic class KeyButtonView extends ImageView { 46fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato private static final String TAG = "StatusBar.KeyButtonView"; 47fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato 4896f4818ef41141649337d4dee09f837594e93d09Daniel Sandler final float GLOW_MAX_SCALE_FACTOR = 1.8f; 499345b12b6572d3c2211c0b856bd90034be92bc0aChristian Robertson final float BUTTON_QUIESCENT_ALPHA = 0.70f; 5096f4818ef41141649337d4dee09f837594e93d09Daniel Sandler 5186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato long mDownTime; 5286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato int mCode; 53aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler int mTouchSlop; 54a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler Drawable mGlowBG; 553fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler int mGlowWidth, mGlowHeight; 56a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler float mGlowAlpha = 0f, mGlowScale = 1f, mDrawingAlpha = 1f; 5744a4616bf780f131f8d78b46a075844800088860Daniel Sandler boolean mSupportsLongpress = true; 58c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler RectF mRect = new RectF(0f,0f,0f,0f); 5960bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka AnimatorSet mPressedAnim; 60aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler 61804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler Runnable mCheckLongPress = new Runnable() { 62804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler public void run() { 63804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler if (isPressed()) { 6444a4616bf780f131f8d78b46a075844800088860Daniel Sandler // Slog.d("KeyButtonView", "longpressed: " + this); 65a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mCode != 0) { 6698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); 67a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); 68a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } else { 69a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler // Just an old-fashioned ImageView 70a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler performLongClick(); 71a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 72804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler } 73804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler } 74804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler }; 7586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 7686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato public KeyButtonView(Context context, AttributeSet attrs) { 7786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato this(context, attrs, 0); 7886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 7986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 8086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato public KeyButtonView(Context context, AttributeSet attrs, int defStyle) { 8186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato super(context, attrs); 8286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 8386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView, 8486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato defStyle, 0); 8586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 8686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0); 8744a4616bf780f131f8d78b46a075844800088860Daniel Sandler 8844a4616bf780f131f8d78b46a075844800088860Daniel Sandler mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true); 89a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 90a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground); 91a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG != null) { 920b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka setDrawingAlpha(BUTTON_QUIESCENT_ALPHA); 933fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler mGlowWidth = mGlowBG.getIntrinsicWidth(); 943fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler mGlowHeight = mGlowBG.getIntrinsicHeight(); 9586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 9686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 9786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato a.recycle(); 9886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 99641bad449ba3b971500843c6bf7bf6f08363d09eJoe Onorato setClickable(true); 100aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 10186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 10286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 103a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler @Override 104a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler protected void onDraw(Canvas canvas) { 105a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG != null) { 106a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler canvas.save(); 107a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler final int w = getWidth(); 108a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler final int h = getHeight(); 1093fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler final float aspect = (float)mGlowWidth / mGlowHeight; 1103fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler final int drawW = (int)(h*aspect); 1113fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler final int drawH = h; 1123fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler final int margin = (drawW-w)/2; 113a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler canvas.scale(mGlowScale, mGlowScale, w*0.5f, h*0.5f); 1143fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler mGlowBG.setBounds(-margin, 0, drawW-margin, drawH); 1150b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka mGlowBG.setAlpha((int)(mDrawingAlpha * mGlowAlpha * 255)); 116a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mGlowBG.draw(canvas); 117a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler canvas.restore(); 118c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler mRect.right = w; 119c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler mRect.bottom = h; 120a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 121a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler super.onDraw(canvas); 122a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 123a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 124a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public float getDrawingAlpha() { 125a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return 0; 126a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler return mDrawingAlpha; 127a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 128a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 129a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public void setDrawingAlpha(float x) { 130a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return; 1310b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka // Calling setAlpha(int), which is an ImageView-specific 1320b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka // method that's different from setAlpha(float). This sets 1330b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka // the alpha on this ImageView's drawable directly 1340b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka setAlpha((int) (x * 255)); 135a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mDrawingAlpha = x; 136a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 137a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 138a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public float getGlowAlpha() { 139a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return 0; 140a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler return mGlowAlpha; 141a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 142a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 143a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public void setGlowAlpha(float x) { 144a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return; 145a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mGlowAlpha = x; 146a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler invalidate(); 147a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 148a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 149a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public float getGlowScale() { 150a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return 0; 151a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler return mGlowScale; 152a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 153a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 154a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public void setGlowScale(float x) { 155a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return; 156a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mGlowScale = x; 157a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler final float w = getWidth(); 158a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler final float h = getHeight(); 15996f4818ef41141649337d4dee09f837594e93d09Daniel Sandler if (GLOW_MAX_SCALE_FACTOR <= 1.0f) { 16096f4818ef41141649337d4dee09f837594e93d09Daniel Sandler // this only works if we know the glow will never leave our bounds 161a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler invalidate(); 162a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } else { 16396f4818ef41141649337d4dee09f837594e93d09Daniel Sandler final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f; 16496f4818ef41141649337d4dee09f837594e93d09Daniel Sandler final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f; 165a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler com.android.systemui.SwipeHelper.invalidateGlobalRegion( 166a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler this, 1675298582717494098fcdf115d832c8e871340d0b5Daniel Sandler new RectF(getLeft() - rx, 1685298582717494098fcdf115d832c8e871340d0b5Daniel Sandler getTop() - ry, 1695298582717494098fcdf115d832c8e871340d0b5Daniel Sandler getRight() + rx, 1705298582717494098fcdf115d832c8e871340d0b5Daniel Sandler getBottom() + ry)); 17196f4818ef41141649337d4dee09f837594e93d09Daniel Sandler 17296f4818ef41141649337d4dee09f837594e93d09Daniel Sandler // also invalidate our immediate parent to help avoid situations where nearby glows 17396f4818ef41141649337d4dee09f837594e93d09Daniel Sandler // interfere 17496f4818ef41141649337d4dee09f837594e93d09Daniel Sandler ((View)getParent()).invalidate(); 175a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 176a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 177a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 178a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public void setPressed(boolean pressed) { 179a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG != null) { 180a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (pressed != isPressed()) { 18160bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka if (mPressedAnim != null && mPressedAnim.isRunning()) { 18260bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka mPressedAnim.cancel(); 18360bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka } 18460bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka final AnimatorSet as = mPressedAnim = new AnimatorSet(); 185a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (pressed) { 186bceff71b9231643090d0dad6e3f1e1aac6fda1a2Justin Ho if (mGlowScale < GLOW_MAX_SCALE_FACTOR) 187bceff71b9231643090d0dad6e3f1e1aac6fda1a2Justin Ho mGlowScale = GLOW_MAX_SCALE_FACTOR; 188bceff71b9231643090d0dad6e3f1e1aac6fda1a2Justin Ho if (mGlowAlpha < BUTTON_QUIESCENT_ALPHA) 189bceff71b9231643090d0dad6e3f1e1aac6fda1a2Justin Ho mGlowAlpha = BUTTON_QUIESCENT_ALPHA; 190a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler setDrawingAlpha(1f); 191a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.playTogether( 192a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ObjectAnimator.ofFloat(this, "glowAlpha", 1f), 19396f4818ef41141649337d4dee09f837594e93d09Daniel Sandler ObjectAnimator.ofFloat(this, "glowScale", GLOW_MAX_SCALE_FACTOR) 194a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ); 195a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.setDuration(50); 196a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } else { 197a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.playTogether( 198a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ObjectAnimator.ofFloat(this, "glowAlpha", 0f), 199a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ObjectAnimator.ofFloat(this, "glowScale", 1f), 200bceff71b9231643090d0dad6e3f1e1aac6fda1a2Justin Ho ObjectAnimator.ofFloat(this, "drawingAlpha", BUTTON_QUIESCENT_ALPHA) 201a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ); 202a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.setDuration(500); 203a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 204a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.start(); 205a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 206a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 207a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler super.setPressed(pressed); 208a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 209a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 21086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato public boolean onTouchEvent(MotionEvent ev) { 21186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato final int action = ev.getAction(); 21286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato int x, y; 21386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 21486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato switch (action) { 21586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato case MotionEvent.ACTION_DOWN: 2167a1a2f0e9273afbde398d9804cfaa245f6adbf5dChristopher Tate //Slog.d("KeyButtonView", "press"); 21786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato mDownTime = SystemClock.uptimeMillis(); 21844a4616bf780f131f8d78b46a075844800088860Daniel Sandler setPressed(true); 21998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mCode != 0) { 22098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime); 22198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } else { 22298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown // Provide the same haptic feedback that the system offers for virtual keys. 22398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); 22498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 22544a4616bf780f131f8d78b46a075844800088860Daniel Sandler if (mSupportsLongpress) { 22644a4616bf780f131f8d78b46a075844800088860Daniel Sandler removeCallbacks(mCheckLongPress); 22744a4616bf780f131f8d78b46a075844800088860Daniel Sandler postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); 22844a4616bf780f131f8d78b46a075844800088860Daniel Sandler } 22986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato break; 23086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato case MotionEvent.ACTION_MOVE: 23198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown x = (int)ev.getX(); 23298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown y = (int)ev.getY(); 23398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown setPressed(x >= -mTouchSlop 23498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown && x < getWidth() + mTouchSlop 23598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown && y >= -mTouchSlop 23698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown && y < getHeight() + mTouchSlop); 23786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato break; 23886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato case MotionEvent.ACTION_CANCEL: 239804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler setPressed(false); 24098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mCode != 0) { 24198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED); 24298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 24398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mSupportsLongpress) { 24498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown removeCallbacks(mCheckLongPress); 245abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato } 246abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato break; 247abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato case MotionEvent.ACTION_UP: 248aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler final boolean doIt = isPressed(); 249abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato setPressed(false); 25098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mCode != 0) { 25198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (doIt) { 25298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_UP, 0); 25398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); 25498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown playSoundEffect(SoundEffectConstants.CLICK); 2555ee1a3daf0fb274b2a5fdea797748b569495a621Patrick Dubroy } else { 25698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED); 257aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler } 25898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } else { 25998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown // no key code, just a regular ImageView 26098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (doIt) { 26198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown performClick(); 26298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 26398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 26498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mSupportsLongpress) { 26598392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown removeCallbacks(mCheckLongPress); 26686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 26786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato break; 26886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 26986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 27086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato return true; 27186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 27286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 273bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown void sendEvent(int action, int flags) { 274bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown sendEvent(action, flags, SystemClock.uptimeMillis()); 27586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 27686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 277bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown void sendEvent(int action, int flags, long when) { 27898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0; 27998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount, 28098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 28198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, 28298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown InputDevice.SOURCE_KEYBOARD); 2839f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown InputManager.getInstance().injectInputEvent(ev, 2849f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 28586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 28686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato} 28786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 28886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 289