KeyButtonView.java revision 5ee1a3daf0fb274b2a5fdea797748b569495a621
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.systemui.statusbar.policy; 18 19import android.content.Context; 20import android.content.res.TypedArray; 21import android.graphics.drawable.AnimationDrawable; 22import android.graphics.drawable.Drawable; 23import android.os.RemoteException; 24import android.os.SystemClock; 25import android.os.ServiceManager; 26import android.util.AttributeSet; 27import android.util.Slog; 28import android.view.accessibility.AccessibilityEvent; 29import android.view.HapticFeedbackConstants; 30import android.view.IWindowManager; 31import android.view.InputDevice; 32import android.view.KeyCharacterMap; 33import android.view.KeyEvent; 34import android.view.MotionEvent; 35import android.view.SoundEffectConstants; 36import android.view.ViewConfiguration; 37import android.widget.ImageView; 38import android.widget.RemoteViews.RemoteView; 39 40import com.android.systemui.R; 41 42public class KeyButtonView extends ImageView { 43 private static final String TAG = "StatusBar.KeyButtonView"; 44 45 IWindowManager mWindowManager; 46 long mDownTime; 47 boolean mSending; 48 int mCode; 49 int mRepeat; 50 int mTouchSlop; 51 52 Runnable mCheckLongPress = new Runnable() { 53 public void run() { 54 if (isPressed()) { 55 mRepeat++; 56 sendEvent(KeyEvent.ACTION_DOWN, 57 KeyEvent.FLAG_FROM_SYSTEM 58 | KeyEvent.FLAG_VIRTUAL_HARD_KEY 59 | KeyEvent.FLAG_LONG_PRESS); 60 61 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); 62 //playSoundEffect(SoundEffectConstants.CLICK); 63 } 64 } 65 }; 66 67 public KeyButtonView(Context context, AttributeSet attrs) { 68 this(context, attrs, 0); 69 } 70 71 public KeyButtonView(Context context, AttributeSet attrs, int defStyle) { 72 super(context, attrs); 73 74 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView, 75 defStyle, 0); 76 77 mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0); 78 if (mCode == 0) { 79 Slog.w(TAG, "KeyButtonView without key code id=0x" + Integer.toHexString(getId())); 80 } 81 82 a.recycle(); 83 84 mWindowManager = IWindowManager.Stub.asInterface( 85 ServiceManager.getService(Context.WINDOW_SERVICE)); 86 87 setClickable(true); 88 mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 89 } 90 91 public boolean onTouchEvent(MotionEvent ev) { 92 final int action = ev.getAction(); 93 int x, y; 94 95 switch (action) { 96 case MotionEvent.ACTION_DOWN: 97 //Slog.d("KeyButtonView", "press"); 98 mDownTime = SystemClock.uptimeMillis(); 99 mRepeat = 0; 100 mSending = true; 101 sendEvent(KeyEvent.ACTION_DOWN, 102 KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime); 103 setPressed(true); 104 removeCallbacks(mCheckLongPress); 105 postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); 106 break; 107 case MotionEvent.ACTION_MOVE: 108 if (mSending) { 109 x = (int)ev.getX(); 110 y = (int)ev.getY(); 111 setPressed(x >= -mTouchSlop 112 && x < getWidth() + mTouchSlop 113 && y >= -mTouchSlop 114 && y < getHeight() + mTouchSlop); 115 } 116 break; 117 case MotionEvent.ACTION_CANCEL: 118 setPressed(false); 119 if (mSending) { 120 mSending = false; 121 sendEvent(KeyEvent.ACTION_UP, 122 KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY 123 | KeyEvent.FLAG_CANCELED); 124 removeCallbacks(mCheckLongPress); 125 } 126 break; 127 case MotionEvent.ACTION_UP: 128 final boolean doIt = isPressed(); 129 setPressed(false); 130 if (mSending) { 131 mSending = false; 132 final int flags = KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY; 133 removeCallbacks(mCheckLongPress); 134 if (doIt) { 135 sendEvent(KeyEvent.ACTION_UP, flags); 136 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); 137 playSoundEffect(SoundEffectConstants.CLICK); 138 } else { 139 sendEvent(KeyEvent.ACTION_UP, flags | KeyEvent.FLAG_CANCELED); 140 } 141 } 142 break; 143 } 144 145 return true; 146 } 147 148 void sendEvent(int action, int flags) { 149 sendEvent(action, flags, SystemClock.uptimeMillis()); 150 } 151 152 void sendEvent(int action, int flags, long when) { 153 final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, mRepeat, 154 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags, InputDevice.SOURCE_KEYBOARD); 155 try { 156 //Slog.d(TAG, "injecting event " + ev); 157 mWindowManager.injectInputEventNoWait(ev); 158 } catch (RemoteException ex) { 159 // System process is dead 160 } 161 } 162} 163 164 165