/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.browser; import android.view.KeyEvent; import android.view.ViewConfiguration; class KeyTracker { public enum Stage { DOWN, //!< the key has just been pressed SHORT_REPEAT, //!< repeated key, but duration is under the long-press threshold LONG_REPEAT, //!< repeated key, but duration is over the long-press threshold UP //!< the key is being released } public enum State { KEEP_TRACKING, //!< return this to continue to track the key DONE_TRACKING, //!< return this if you handled the key, but need not track it anymore NOT_TRACKING //!< return this if you will not handle this key } public interface OnKeyTracker { /** Called whenever there is a key event [down, short/long repeat, up] @param keyCode The current keyCode (see KeyEvent class) @param msg The message associated with the keyCode @maram stage The state the key press is in [down, short/long repeat, up] @param duration The number of milliseconds since this key was initially pressed @return your state after seeing the key. If you return DONE_TRACKING or NOT_TRACKING, you will not be called again for the lifetime of this key event. */ public State onKeyTracker(int keyCode, KeyEvent event, Stage stage, int duration); } public KeyTracker(OnKeyTracker tracker) { mTracker = tracker; } public boolean doKeyDown(int keyCode, KeyEvent event) { long now = System.currentTimeMillis(); Stage stage = null; // check if its a new/different key if (mKeyCode != keyCode || event.getRepeatCount() == 0) { mKeyCode = keyCode; mStartMS = now; stage = Stage.DOWN; } else if (mState == State.KEEP_TRACKING) { stage = (now - mStartMS) >= LONG_PRESS_DURATION_MS ? Stage.LONG_REPEAT : Stage.SHORT_REPEAT; } if (stage != null) { mEvent = event; callTracker(stage, now); } return mState != State.NOT_TRACKING; } public boolean doKeyUp(int keyCode, KeyEvent event) { boolean handled = false; if (mState == State.KEEP_TRACKING && mKeyCode == keyCode) { mEvent = event; callTracker(Stage.UP, System.currentTimeMillis()); handled = mState != State.NOT_TRACKING; } mKeyCode = NOT_A_KEYCODE; return handled; } private void callTracker(Stage stage, long now) { mState = mTracker.onKeyTracker(mKeyCode, mEvent, stage, (int)(now - mStartMS)); } private void dump() { System.out.println(" key=" + mKeyCode + " dur=" + (System.currentTimeMillis() - mStartMS) + " state=" + mState); } private int mKeyCode = NOT_A_KEYCODE; private KeyEvent mEvent; private long mStartMS; private State mState; private OnKeyTracker mTracker; private static final int LONG_PRESS_DURATION_MS = ViewConfiguration.getLongPressTimeout(); private static final int NOT_A_KEYCODE = -123456; }