KeyButtonView.java revision 6b53e8daa69cba1a2a5a7c95a01e37ce9c53226c
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
1986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.Context;
2086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.res.TypedArray;
2186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.graphics.drawable.AnimationDrawable;
2286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.graphics.drawable.Drawable;
2386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.RemoteException;
2486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.SystemClock;
2586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.ServiceManager;
2686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.util.AttributeSet;
2786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.util.Slog;
28804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.HapticFeedbackConstants;
2986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.IWindowManager;
30bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brownimport android.view.InputDevice;
316b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.view.KeyCharacterMap;
3286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.KeyEvent;
3386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.MotionEvent;
34804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.ViewConfiguration;
3586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.widget.ImageView;
3686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.widget.RemoteViews.RemoteView;
3786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
3886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport com.android.systemui.R;
3986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
4086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratopublic class KeyButtonView extends ImageView {
41fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    private static final String TAG = "StatusBar.KeyButtonView";
42fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
4386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    IWindowManager mWindowManager;
4486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    long mDownTime;
45804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler    boolean mSending, mLongPressed;
4686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    int mCode;
4786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    int mRepeat;
48804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler    Runnable mCheckLongPress = new Runnable() {
49804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler        public void run() {
50804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler            Slog.d("KeyButtonView", "longpress");
51804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler            if (isPressed()) {
52804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                mLongPressed = true;
53804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                mRepeat++;
54804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                sendEvent(KeyEvent.ACTION_DOWN,
55804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                        KeyEvent.FLAG_FROM_SYSTEM
56804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                        | KeyEvent.FLAG_VIRTUAL_HARD_KEY
57804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                        | KeyEvent.FLAG_LONG_PRESS);
58804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler            }
59804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler        }
60804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler    };
6186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
6286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public KeyButtonView(Context context, AttributeSet attrs) {
6386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        this(context, attrs, 0);
6486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
6586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
6686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public KeyButtonView(Context context, AttributeSet attrs, int defStyle) {
6786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        super(context, attrs);
6886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
6986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
7086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                defStyle, 0);
7186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
7286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
7386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        if (mCode == 0) {
74fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            Slog.w(TAG, "KeyButtonView without key code id=0x" + Integer.toHexString(getId()));
7586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        }
7686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
7786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        a.recycle();
7886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
7986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        mWindowManager = IWindowManager.Stub.asInterface(
8086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                ServiceManager.getService(Context.WINDOW_SERVICE));
8186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
8286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    public boolean onTouchEvent(MotionEvent ev) {
8486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        final int action = ev.getAction();
8586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        int x, y;
8686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
8786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        switch (action) {
8886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_DOWN:
897a1a2f0e9273afbde398d9804cfaa245f6adbf5dChristopher Tate                //Slog.d("KeyButtonView", "press");
9086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                mDownTime = SystemClock.uptimeMillis();
9186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                mRepeat = 0;
9286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                mSending = true;
93804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                mLongPressed = false;
94bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown                sendEvent(KeyEvent.ACTION_DOWN,
95804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                        KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime);
96a101f8f6ef1c730f3f008256734cde54417e22ccDaniel Sandler                setPressed(true);
97804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                removeCallbacks(mCheckLongPress);
98804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
9986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
10086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_MOVE:
10186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                if (mSending) {
10286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                    x = (int)ev.getX();
10386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                    y = (int)ev.getY();
104abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                    setPressed(x >= 0 && x < getWidth() && y >= 0 &&  y < getHeight());
10586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                }
10686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
10786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            case MotionEvent.ACTION_CANCEL:
108804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                setPressed(false);
109804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                if (mSending && !mLongPressed) {
11086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                    mSending = false;
111bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown                    sendEvent(KeyEvent.ACTION_UP,
112abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                            KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
113abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                                | KeyEvent.FLAG_CANCELED);
114abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                    removeCallbacks(mCheckLongPress);
115abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                }
116abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                break;
117abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato            case MotionEvent.ACTION_UP:
118abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                setPressed(false);
119abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                if (mSending && !mLongPressed) {
120abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                    mSending = false;
121abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato                    sendEvent(KeyEvent.ACTION_UP,
122804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                            KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY);
123804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler                    removeCallbacks(mCheckLongPress);
12486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                }
12586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato                break;
12686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        }
12786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
12886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        return true;
12986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
13086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
131bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown    void sendEvent(int action, int flags) {
132bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown        sendEvent(action, flags, SystemClock.uptimeMillis());
13386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
13486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
135bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown    void sendEvent(int action, int flags, long when) {
136bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown        final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, mRepeat,
1376b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags, InputDevice.SOURCE_KEYBOARD);
13886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        try {
139fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            //Slog.d(TAG, "injecting event " + ev);
140bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown            mWindowManager.injectInputEventNoWait(ev);
14186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        } catch (RemoteException ex) {
14286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato            // System process is dead
14386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato        }
14486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato    }
14586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato}
14686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
14786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato
148