Merge "Use FLAG_LONG_PRESS for headset long press interactions." into jb-dev

This commit is contained in:
Jeff Brown
2012-05-17 15:14:12 -07:00
committed by Android (Google) Code Review

View File

@@ -3699,38 +3699,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
/**
* The minimum duration during which a user must press to trigger voice-based interactions
*/
private final static int MEDIABUTTON_LONG_PRESS_DURATION_MS = 300;
/**
* The different states of the state machine to handle the launch of voice-based interactions,
* stored in mVoiceButtonState.
*/
private final static int VOICEBUTTON_STATE_IDLE = 0;
private final static int VOICEBUTTON_STATE_DOWN = 1;
private final static int VOICEBUTTON_STATE_DOWN_IGNORE_NEW = 2;
/**
* The different actions after state transitions on mVoiceButtonState.
* The different actions performed in response to a voice button key event.
*/
private final static int VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS = 1;
private final static int VOICEBUTTON_ACTION_START_VOICE_INPUT = 2;
private final static int VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS = 3;
private final Object mVoiceEventLock = new Object();
private int mVoiceButtonState = VOICEBUTTON_STATE_IDLE;
private long mVoiceButtonDownTime = 0;
/**
* Log an error when an unexpected action is encountered in the state machine to filter
* key events.
* @param keyAction the unexpected action of the key event being filtered
* @param stateName the string corresponding to the state in which the error occurred
*/
private static void logErrorForKeyAction(int keyAction, String stateName) {
Log.e(TAG, "unexpected action "
+ KeyEvent.actionToString(keyAction)
+ " in " + stateName + " state");
}
private boolean mVoiceButtonDown;
private boolean mVoiceButtonHandled;
/**
* Filter key events that may be used for voice-based interactions
@@ -3740,67 +3717,32 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
* is dispatched.
*/
private void filterVoiceInputKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
if (DEBUG_RC) {
Log.v(TAG, "voice input key event: " + keyEvent + ", needWakeLock=" + needWakeLock);
}
int voiceButtonAction = VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS;
int keyAction = keyEvent.getAction();
synchronized (mVoiceEventLock) {
// state machine on mVoiceButtonState
switch (mVoiceButtonState) {
case VOICEBUTTON_STATE_IDLE:
if (keyAction == KeyEvent.ACTION_DOWN) {
mVoiceButtonDownTime = keyEvent.getDownTime();
// valid state transition
mVoiceButtonState = VOICEBUTTON_STATE_DOWN;
} else if (keyAction == KeyEvent.ACTION_UP) {
// no state transition
// action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS
} else {
logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_IDLE");
if (keyAction == KeyEvent.ACTION_DOWN) {
if (keyEvent.getRepeatCount() == 0) {
// initial down
mVoiceButtonDown = true;
mVoiceButtonHandled = false;
} else if (mVoiceButtonDown && !mVoiceButtonHandled
&& (keyEvent.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
// long-press, start voice-based interactions
mVoiceButtonHandled = true;
voiceButtonAction = VOICEBUTTON_ACTION_START_VOICE_INPUT;
}
} else if (keyAction == KeyEvent.ACTION_UP) {
if (mVoiceButtonDown) {
// voice button up
mVoiceButtonDown = false;
if (!mVoiceButtonHandled && !keyEvent.isCanceled()) {
voiceButtonAction = VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS;
}
break;
case VOICEBUTTON_STATE_DOWN:
if ((keyEvent.getEventTime() - mVoiceButtonDownTime)
>= MEDIABUTTON_LONG_PRESS_DURATION_MS) {
// press was long enough, start voice-based interactions, regardless of
// whether this was a DOWN or UP key event
voiceButtonAction = VOICEBUTTON_ACTION_START_VOICE_INPUT;
if (keyAction == KeyEvent.ACTION_UP) {
// done tracking the key press, so transition back to idle state
mVoiceButtonState = VOICEBUTTON_STATE_IDLE;
} else if (keyAction == KeyEvent.ACTION_DOWN) {
// no need to observe the upcoming key events
mVoiceButtonState = VOICEBUTTON_STATE_DOWN_IGNORE_NEW;
} else {
logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_DOWN");
}
} else {
if (keyAction == KeyEvent.ACTION_UP) {
// press wasn't long enough, simulate complete key press
voiceButtonAction = VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS;
// not tracking the key press anymore, so transition back to idle state
mVoiceButtonState = VOICEBUTTON_STATE_IDLE;
} else if (keyAction == KeyEvent.ACTION_DOWN) {
// no state transition
// action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS
} else {
logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_DOWN");
}
}
break;
case VOICEBUTTON_STATE_DOWN_IGNORE_NEW:
if (keyAction == KeyEvent.ACTION_UP) {
// done tracking the key press, so transition back to idle state
mVoiceButtonState = VOICEBUTTON_STATE_IDLE;
// action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS
} else if (keyAction == KeyEvent.ACTION_DOWN) {
// no state transition: we've already launched voice-based interactions
// action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS
} else {
logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_DOWN_IGNORE_NEW");
}
break;
}
}
}//synchronized (mVoiceEventLock)