Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 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 | |
| 17 | package com.android.systemui.statusbar; |
| 18 | |
| 19 | import android.content.Context; |
| 20 | import android.content.res.TypedArray; |
| 21 | import android.graphics.drawable.AnimationDrawable; |
| 22 | import android.graphics.drawable.Drawable; |
| 23 | import android.os.RemoteException; |
| 24 | import android.os.SystemClock; |
| 25 | import android.os.ServiceManager; |
| 26 | import android.util.AttributeSet; |
| 27 | import android.util.Slog; |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 28 | import android.view.HapticFeedbackConstants; |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 29 | import android.view.IWindowManager; |
Jeff Brown | bbda99d | 2010-07-28 15:48:59 -0700 | [diff] [blame] | 30 | import android.view.InputDevice; |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 31 | import android.view.KeyEvent; |
| 32 | import android.view.MotionEvent; |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 33 | import android.view.ViewConfiguration; |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 34 | import android.widget.ImageView; |
| 35 | import android.widget.RemoteViews.RemoteView; |
| 36 | |
| 37 | import com.android.systemui.R; |
| 38 | |
| 39 | public class KeyButtonView extends ImageView { |
| 40 | IWindowManager mWindowManager; |
| 41 | long mDownTime; |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 42 | boolean mSending, mLongPressed; |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 43 | int mCode; |
| 44 | int mRepeat; |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 45 | Runnable mCheckLongPress = new Runnable() { |
| 46 | public void run() { |
| 47 | Slog.d("KeyButtonView", "longpress"); |
| 48 | if (isPressed()) { |
| 49 | mLongPressed = true; |
| 50 | mRepeat++; |
| 51 | sendEvent(KeyEvent.ACTION_DOWN, |
| 52 | KeyEvent.FLAG_FROM_SYSTEM |
| 53 | | KeyEvent.FLAG_VIRTUAL_HARD_KEY |
| 54 | | KeyEvent.FLAG_LONG_PRESS); |
| 55 | } |
| 56 | } |
| 57 | }; |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 58 | |
| 59 | public KeyButtonView(Context context, AttributeSet attrs) { |
| 60 | this(context, attrs, 0); |
| 61 | } |
| 62 | |
| 63 | public KeyButtonView(Context context, AttributeSet attrs, int defStyle) { |
| 64 | super(context, attrs); |
| 65 | |
| 66 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView, |
| 67 | defStyle, 0); |
| 68 | |
| 69 | mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0); |
| 70 | if (mCode == 0) { |
| 71 | Slog.w(StatusBarService.TAG, "KeyButtonView without key code id=0x" |
| 72 | + Integer.toHexString(getId())); |
| 73 | } |
| 74 | |
| 75 | a.recycle(); |
| 76 | |
| 77 | mWindowManager = IWindowManager.Stub.asInterface( |
| 78 | ServiceManager.getService(Context.WINDOW_SERVICE)); |
| 79 | } |
| 80 | |
| 81 | public boolean onTouchEvent(MotionEvent ev) { |
| 82 | final int action = ev.getAction(); |
| 83 | int x, y; |
| 84 | |
| 85 | switch (action) { |
| 86 | case MotionEvent.ACTION_DOWN: |
Christopher Tate | 7a1a2f0 | 2010-09-09 12:22:40 -0700 | [diff] [blame^] | 87 | //Slog.d("KeyButtonView", "press"); |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 88 | mDownTime = SystemClock.uptimeMillis(); |
| 89 | mRepeat = 0; |
| 90 | mSending = true; |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 91 | mLongPressed = false; |
Jeff Brown | bbda99d | 2010-07-28 15:48:59 -0700 | [diff] [blame] | 92 | sendEvent(KeyEvent.ACTION_DOWN, |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 93 | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime); |
Daniel Sandler | a101f8f | 2010-07-21 16:13:30 -0400 | [diff] [blame] | 94 | setPressed(true); |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 95 | removeCallbacks(mCheckLongPress); |
| 96 | postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 97 | break; |
| 98 | case MotionEvent.ACTION_MOVE: |
| 99 | if (mSending) { |
| 100 | x = (int)ev.getX(); |
| 101 | y = (int)ev.getY(); |
| 102 | if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) { |
| 103 | mSending = false; |
Jeff Brown | bbda99d | 2010-07-28 15:48:59 -0700 | [diff] [blame] | 104 | sendEvent(KeyEvent.ACTION_UP, |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 105 | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY |
Jeff Brown | bbda99d | 2010-07-28 15:48:59 -0700 | [diff] [blame] | 106 | | KeyEvent.FLAG_CANCELED); |
Daniel Sandler | a101f8f | 2010-07-21 16:13:30 -0400 | [diff] [blame] | 107 | setPressed(false); |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 108 | removeCallbacks(mCheckLongPress); |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 109 | } |
| 110 | } |
| 111 | break; |
| 112 | case MotionEvent.ACTION_UP: |
| 113 | case MotionEvent.ACTION_CANCEL: |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 114 | setPressed(false); |
| 115 | if (mSending && !mLongPressed) { |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 116 | mSending = false; |
Jeff Brown | bbda99d | 2010-07-28 15:48:59 -0700 | [diff] [blame] | 117 | sendEvent(KeyEvent.ACTION_UP, |
Daniel Sandler | 804eb85 | 2010-08-31 15:43:50 -0400 | [diff] [blame] | 118 | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY); |
| 119 | removeCallbacks(mCheckLongPress); |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 120 | } |
| 121 | break; |
| 122 | } |
| 123 | |
| 124 | return true; |
| 125 | } |
| 126 | |
Jeff Brown | bbda99d | 2010-07-28 15:48:59 -0700 | [diff] [blame] | 127 | void sendEvent(int action, int flags) { |
| 128 | sendEvent(action, flags, SystemClock.uptimeMillis()); |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 129 | } |
| 130 | |
Jeff Brown | bbda99d | 2010-07-28 15:48:59 -0700 | [diff] [blame] | 131 | void sendEvent(int action, int flags, long when) { |
| 132 | final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, mRepeat, |
| 133 | 0, 0, 0, flags, InputDevice.SOURCE_KEYBOARD); |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 134 | try { |
Christopher Tate | 7a1a2f0 | 2010-09-09 12:22:40 -0700 | [diff] [blame^] | 135 | //Slog.d(StatusBarService.TAG, "injecting event " + ev); |
Jeff Brown | bbda99d | 2010-07-28 15:48:59 -0700 | [diff] [blame] | 136 | mWindowManager.injectInputEventNoWait(ev); |
Joe Onorato | 86f9bd2 | 2010-06-30 17:03:42 -0400 | [diff] [blame] | 137 | } catch (RemoteException ex) { |
| 138 | // System process is dead |
| 139 | } |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | |