FileDocCategorySizeDatePackage
SendKeyAction.javaAPI DocAndroid 5.1 API7398Thu Mar 12 22:22:42 GMT 2015com.android.server.hdmi

SendKeyAction

public final class SendKeyAction extends HdmiCecFeatureAction
Feature action that transmits remote control key command (User Control Press/ User Control Release) to CEC bus.

This action is created when a new key event is passed to CEC service. It optionally does key repeat (a.k.a. press-and-hold) operation until it receives a key release event. If another key press event is received before the key in use is released, CEC service does not create a new action but recycles the current one by updating the key used for press-and-hold operation.

Package-private, accessed by {@link HdmiControlService} only.

Fields Summary
private static final String
TAG
private static final int
AWAIT_LONGPRESS_MS
private static final int
AWAIT_RELEASE_KEY_MS
private static final int
STATE_CHECKING_LONGPRESS
private static final int
STATE_PROCESSING_KEYCODE
private final int
mTargetAddress
private int
mLastKeycode
private long
mLastSendKeyTime
Constructors Summary
SendKeyAction(HdmiCecLocalDevice source, int targetAddress, int keycode)
Constructor.

param
source {@link HdmiCecLocalDevice} instance
param
targetAddress logical address of the device to send the keys to
param
keycode remote control key code as defined in {@link KeyEvent}


                                      
          
        super(source);
        mTargetAddress = targetAddress;
        mLastKeycode = keycode;
    
Methods Summary
private longgetCurrentTime()

        return System.currentTimeMillis();
    
public voidhandleTimerEvent(int state)

        switch (mState) {
            case STATE_CHECKING_LONGPRESS:
                // The first key press lasts long enough to start press-and-hold.
                mActionTimer.clearTimerMessage();
                mState = STATE_PROCESSING_KEYCODE;
                sendKeyDown(mLastKeycode);
                mLastSendKeyTime = getCurrentTime();
                addTimer(mState, AWAIT_RELEASE_KEY_MS);
                break;
            case STATE_PROCESSING_KEYCODE:
                // Timeout on waiting for the release key event. Send UCR and quit the action.
                sendKeyUp();
                finish();
                break;
            default:
                Slog.w(TAG, "Not in a valid state");
                break;
        }
    
public booleanprocessCommand(HdmiCecMessage cmd)

        // Send key action doesn't need any incoming CEC command, hence does not consume it.
        return false;
    
voidprocessKeyEvent(int keycode, boolean isPressed)
Called when a key event should be handled for the action.

param
keycode key code of {@link KeyEvent} object
param
isPressed true if the key event is of {@link KeyEvent#ACTION_DOWN}

        if (mState != STATE_CHECKING_LONGPRESS && mState != STATE_PROCESSING_KEYCODE) {
            Slog.w(TAG, "Not in a valid state");
            return;
        }
        if (isPressed) {
            // A new key press event that comes in with a key code different from the last
            // one becomes a new key code to be used for press-and-hold operation.
            if (keycode != mLastKeycode) {
                sendKeyDown(keycode);
                mLastSendKeyTime = getCurrentTime();
                if (!HdmiCecKeycode.isRepeatableKey(keycode)) {
                    sendKeyUp();
                    finish();
                    return;
                }
            } else {
                // Press-and-hold key transmission takes place if Android key inputs are
                // repeatedly coming in and more than IRT_MS has passed since the last
                // press-and-hold key transmission.
                if (getCurrentTime() - mLastSendKeyTime >= IRT_MS) {
                    sendKeyDown(keycode);
                    mLastSendKeyTime = getCurrentTime();
                }
            }
            mActionTimer.clearTimerMessage();
            addTimer(mState, AWAIT_RELEASE_KEY_MS);
            mLastKeycode = keycode;
        } else {
            // Key release event indicates that the action shall be finished. Send UCR
            // command and terminate the action. Other release events are ignored.
            if (keycode == mLastKeycode) {
                sendKeyUp();
                finish();
            }
        }
    
private voidsendKeyDown(int keycode)

        byte[] cecKeycodeAndParams = HdmiCecKeycode.androidKeyToCecKey(keycode);
        if (cecKeycodeAndParams == null) {
            return;
        }
        sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(),
                mTargetAddress, cecKeycodeAndParams));
    
private voidsendKeyUp()

        sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(getSourceAddress(),
                mTargetAddress));
    
public booleanstart()

        sendKeyDown(mLastKeycode);
        mLastSendKeyTime = getCurrentTime();
        // finish action for non-repeatable key.
        if (!HdmiCecKeycode.isRepeatableKey(mLastKeycode)) {
            sendKeyUp();
            finish();
            return true;
        }
        mState = STATE_CHECKING_LONGPRESS;
        addTimer(mState, AWAIT_LONGPRESS_MS);
        return true;