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