Loading services/core/java/com/android/server/hdmi/HdmiCecKeycode.java +74 −10 Original line number Diff line number Diff line Loading @@ -175,15 +175,21 @@ public class HdmiCecKeycode { private final int mAndroidKeycode; private final int mCecKeycode; private final int mParam; private final boolean mIsRepeatable; private KeycodeEntry(int androidKeycode, int cecKeycode, int param) { this.mAndroidKeycode = androidKeycode; this.mCecKeycode = cecKeycode; this.mParam = param; private KeycodeEntry(int androidKeycode, int cecKeycode, int param, boolean isRepeatable) { mAndroidKeycode = androidKeycode; mCecKeycode = cecKeycode; mParam = param; mIsRepeatable = isRepeatable; } private KeycodeEntry(int androidKeycode, int cecKeycode) { this(androidKeycode, cecKeycode, NO_PARAM); this(androidKeycode, cecKeycode, NO_PARAM, true); } private KeycodeEntry(int androidKeycode, int cecKeycode, boolean isRepeatable) { this(androidKeycode, cecKeycode, NO_PARAM, isRepeatable); } private byte[] toCecKeycodeIfMatched(int androidKeycode) { Loading @@ -210,6 +216,14 @@ public class HdmiCecKeycode { return UNSUPPORTED_KEYCODE; } } private Boolean isRepeatableIfMatched(int androidKeycode) { if (mAndroidKeycode == androidKeycode) { return mIsRepeatable; } else { return null; } } } // Keycode entry container for all mappings. Loading @@ -221,19 +235,26 @@ public class HdmiCecKeycode { new KeycodeEntry(KeyEvent.KEYCODE_DPAD_LEFT, CEC_KEYCODE_LEFT), new KeycodeEntry(KeyEvent.KEYCODE_DPAD_RIGHT, CEC_KEYCODE_RIGHT), // No Android keycode defined for CEC_KEYCODE_RIGHT_UP new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RIGHT_UP), // No Android keycode defined for CEC_KEYCODE_RIGHT_DOWN new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RIGHT_DOWN), // No Android keycode defined for CEC_KEYCODE_LEFT_UP new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_LEFT_UP), // No Android keycode defined for CEC_KEYCODE_LEFT_DOWN new KeycodeEntry(KeyEvent.KEYCODE_HOME, CEC_KEYCODE_ROOT_MENU), new KeycodeEntry(KeyEvent.KEYCODE_SETTINGS, CEC_KEYCODE_SETUP_MENU), new KeycodeEntry(KeyEvent.KEYCODE_MENU, CEC_KEYCODE_CONTENTS_MENU), new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_LEFT_DOWN), new KeycodeEntry(KeyEvent.KEYCODE_HOME, CEC_KEYCODE_ROOT_MENU, false), new KeycodeEntry(KeyEvent.KEYCODE_SETTINGS, CEC_KEYCODE_SETUP_MENU, false), new KeycodeEntry(KeyEvent.KEYCODE_MENU, CEC_KEYCODE_CONTENTS_MENU, false), // No Android keycode defined for CEC_KEYCODE_FAVORITE_MENU new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_FAVORITE_MENU), new KeycodeEntry(KeyEvent.KEYCODE_BACK, CEC_KEYCODE_EXIT), // RESERVED new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_TOP_MENU, CEC_KEYCODE_MEDIA_TOP_MENU), // No Android keycode defined for CEC_KEYCODE_MEDIA_CONTEXT_SENSITIVE_MENU new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_MEDIA_CONTEXT_SENSITIVE_MENU), // RESERVED // No Android keycode defined for CEC_KEYCODE_NUMBER_ENTRY_MODE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_NUMBER_ENTRY_MODE), new KeycodeEntry(KeyEvent.KEYCODE_11, CEC_KEYCODE_NUMBER_11), new KeycodeEntry(KeyEvent.KEYCODE_12, CEC_KEYCODE_NUMBER_12), new KeycodeEntry(KeyEvent.KEYCODE_0, CEC_KEYCODE_NUMBER_0_OR_NUMBER_10), Loading @@ -251,20 +272,23 @@ public class HdmiCecKeycode { new KeycodeEntry(KeyEvent.KEYCODE_CLEAR, CEC_KEYCODE_CLEAR), // RESERVED // No Android keycode defined for CEC_KEYCODE_NEXT_FAVORITE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_NEXT_FAVORITE), new KeycodeEntry(KeyEvent.KEYCODE_CHANNEL_UP, CEC_KEYCODE_CHANNEL_UP), new KeycodeEntry(KeyEvent.KEYCODE_CHANNEL_DOWN, CEC_KEYCODE_CHANNEL_DOWN), new KeycodeEntry(KeyEvent.KEYCODE_LAST_CHANNEL, CEC_KEYCODE_PREVIOUS_CHANNEL), // No Android keycode defined for CEC_KEYCODE_SOUND_SELECT new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SOUND_SELECT), new KeycodeEntry(KeyEvent.KEYCODE_TV_INPUT, CEC_KEYCODE_INPUT_SELECT), new KeycodeEntry(KeyEvent.KEYCODE_INFO, CEC_KEYCODE_DISPLAY_INFORMATION), // No Android keycode defined for CEC_KEYCODE_HELP new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_HELP), new KeycodeEntry(KeyEvent.KEYCODE_PAGE_UP, CEC_KEYCODE_PAGE_UP), new KeycodeEntry(KeyEvent.KEYCODE_PAGE_DOWN, CEC_KEYCODE_PAGE_DOWN), // RESERVED new KeycodeEntry(KeyEvent.KEYCODE_POWER, CEC_KEYCODE_POWER), new KeycodeEntry(KeyEvent.KEYCODE_POWER, CEC_KEYCODE_POWER, false), new KeycodeEntry(KeyEvent.KEYCODE_VOLUME_UP, CEC_KEYCODE_VOLUME_UP), new KeycodeEntry(KeyEvent.KEYCODE_VOLUME_DOWN, CEC_KEYCODE_VOLUME_DOWN), new KeycodeEntry(KeyEvent.KEYCODE_VOLUME_MUTE, CEC_KEYCODE_MUTE), new KeycodeEntry(KeyEvent.KEYCODE_VOLUME_MUTE, CEC_KEYCODE_MUTE, false), new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_PLAY, CEC_KEYCODE_PLAY), new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_STOP, CEC_KEYCODE_STOP), new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_PAUSE, CEC_KEYCODE_PAUSE), Loading @@ -275,33 +299,57 @@ public class HdmiCecKeycode { new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_NEXT, CEC_KEYCODE_FORWARD), new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_PREVIOUS, CEC_KEYCODE_BACKWARD), // No Android keycode defined for CEC_KEYCODE_STOP_RECORD new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_STOP_RECORD), // No Android keycode defined for CEC_KEYCODE_PAUSE_RECORD new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_RECORD), // No Android keycode defined for CEC_KEYCODE_RESERVED new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RESERVED), // No Android keycode defined for CEC_KEYCODE_ANGLE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_ANGLE), // No Android keycode defined for CEC_KEYCODE_SUB_PICTURE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SUB_PICTURE), // No Android keycode defined for CEC_KEYCODE_VIDEO_ON_DEMAND new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_VIDEO_ON_DEMAND), new KeycodeEntry(KeyEvent.KEYCODE_GUIDE, CEC_KEYCODE_ELECTRONIC_PROGRAM_GUIDE), // No Android keycode defined for CEC_KEYCODE_TIMER_PROGRAMMING new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_TIMER_PROGRAMMING), // No Android keycode defined for CEC_KEYCODE_INITIAL_CONFIGURATION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_INITIAL_CONFIGURATION), // No Android keycode defined for CEC_KEYCODE_SELECT_BROADCAST_TYPE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_BROADCAST_TYPE), // No Android keycode defined for CEC_KEYCODE_SELECT_SOUND_PRESENTATION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_SOUND_PRESENTATION), // RESERVED // The following deterministic key definitions do not need key mapping // since they are supposed to be generated programmatically only. // No Android keycode defined for CEC_KEYCODE_PLAY_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PLAY_FUNCTION), // No Android keycode defined for CEC_KEYCODE_PAUSE_PLAY_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_PLAY_FUNCTION), // No Android keycode defined for CEC_KEYCODE_RECORD_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RECORD_FUNCTION), // No Android keycode defined for CEC_KEYCODE_PAUSE_RECORD_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_RECORD_FUNCTION), // No Android keycode defined for CEC_KEYCODE_STOP_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_STOP_FUNCTION), // No Android keycode defined for CEC_KEYCODE_MUTE_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_MUTE_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_RESTORE_VOLUME_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RESTORE_VOLUME_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_TUNE_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_TUNE_FUNCTION), // No Android keycode defined for CEC_KEYCODE_SELECT_MEDIA_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_MEDIA_FUNCTION), // No Android keycode defined for CEC_KEYCODE_SELECT_AV_INPUT_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_AV_INPUT_FUNCTION), // No Android keycode defined for CEC_KEYCODE_SELECT_AUDIO_INPUT_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_AUDIO_INPUT_FUNCTION), // No Android keycode defined for CEC_KEYCODE_POWER_TOGGLE_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_TOGGLE_FUNCTION), // No Android keycode defined for CEC_KEYCODE_POWER_OFF_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_OFF_FUNCTION), // No Android keycode defined for CEC_KEYCODE_POWER_ON_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_ON_FUNCTION, false), // RESERVED new KeycodeEntry(KeyEvent.KEYCODE_PROG_BLUE, CEC_KEYCODE_F1_BLUE), new KeycodeEntry(KeyEvent.KEYCODE_PROG_RED, CEC_KEYCODE_F2_RED), Loading Loading @@ -346,4 +394,20 @@ public class HdmiCecKeycode { } return UNSUPPORTED_KEYCODE; } /** * Whether the given {@code androidKeycode} is repeatable key or not. * * @param androidKeycode keycode of android * @return false if the given {@code androidKeycode} is not supported key code */ static boolean isRepeatableKey(int androidKeycode) { for (int i = 0; i < KEYCODE_ENTRIES.length; ++i) { Boolean isRepeatable = KEYCODE_ENTRIES[i].isRepeatableIfMatched(androidKeycode); if (isRepeatable != null) { return isRepeatable; } } return false; } } services/core/java/com/android/server/hdmi/SendKeyAction.java +29 −18 Original line number Diff line number Diff line Loading @@ -44,24 +44,30 @@ final class SendKeyAction extends FeatureAction { private final int mTargetAddress; // The key code of the last key press event the action is passed via processKeyEvent. private int mLastKeyCode; private int mLastKeycode; /** * 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} * @param keycode remote control key code as defined in {@link KeyEvent} */ SendKeyAction(HdmiCecLocalDevice source, int targetAddress, int keyCode) { SendKeyAction(HdmiCecLocalDevice source, int targetAddress, int keycode) { super(source); mTargetAddress = targetAddress; mLastKeyCode = keyCode; mLastKeycode = keycode; } @Override public boolean start() { sendKeyDown(mLastKeyCode); sendKeyDown(mLastKeycode); // finish action for non-repeatable key. if (!HdmiCecKeycode.isRepeatableKey(mLastKeycode)) { sendKeyUp(); finish(); return true; } mState = STATE_PROCESSING_KEYCODE; addTimer(mState, IRT_MS); return true; Loading @@ -70,10 +76,10 @@ final class SendKeyAction extends FeatureAction { /** * Called when a key event should be handled for the action. * * @param keyCode key code of {@link KeyEvent} object * @param keycode key code of {@link KeyEvent} object * @param isPressed true if the key event is of {@link KeyEvent#ACTION_DOWN} */ void processKeyEvent(int keyCode, boolean isPressed) { void processKeyEvent(int keycode, boolean isPressed) { if (mState != STATE_PROCESSING_KEYCODE) { Slog.w(TAG, "Not in a valid state"); return; Loading @@ -84,27 +90,32 @@ final class SendKeyAction extends FeatureAction { // Key release event indicates that the action shall be finished. Send UCR // command and terminate the action. Other release events are ignored. if (isPressed) { if (keyCode != mLastKeyCode) { if (keycode != mLastKeycode) { if (!HdmiCecKeycode.isRepeatableKey(keycode)) { sendKeyUp(); finish(); return; } mActionTimer.clearTimerMessage(); sendKeyDown(keyCode); sendKeyDown(keycode); addTimer(mState, IRT_MS); mLastKeyCode = keyCode; mLastKeycode = keycode; } } else { if (keyCode == mLastKeyCode) { if (keycode == mLastKeycode) { sendKeyUp(); finish(); } } } private void sendKeyDown(int keyCode) { byte[] keyCodeAndParam = getCecKeyCodeAndParam(keyCode); if (keyCodeAndParam == null) { private void sendKeyDown(int keycode) { byte[] keycodeAndParam = getCecKeycodeAndParam(keycode); if (keycodeAndParam == null) { return; } sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(), mTargetAddress, keyCodeAndParam)); mTargetAddress, keycodeAndParam)); } private void sendKeyUp() { Loading @@ -128,7 +139,7 @@ final class SendKeyAction extends FeatureAction { Slog.w(TAG, "Not in a valid state"); return; } sendKeyDown(mLastKeyCode); sendKeyDown(mLastKeycode); addTimer(mState, IRT_MS); } Loading @@ -137,7 +148,7 @@ final class SendKeyAction extends FeatureAction { // Broadcast' with the parameter 'cable', for instance, shall have its counterpart such as // KeyEvent.KEYCODE_TV_BROADCAST_CABLE. // The return byte array contains both UI command (keycode) and optional parameter. private byte[] getCecKeyCodeAndParam(int keyCode) { return HdmiCecKeycode.androidKeyToCecKey(keyCode); private byte[] getCecKeycodeAndParam(int keycode) { return HdmiCecKeycode.androidKeyToCecKey(keycode); } } Loading
services/core/java/com/android/server/hdmi/HdmiCecKeycode.java +74 −10 Original line number Diff line number Diff line Loading @@ -175,15 +175,21 @@ public class HdmiCecKeycode { private final int mAndroidKeycode; private final int mCecKeycode; private final int mParam; private final boolean mIsRepeatable; private KeycodeEntry(int androidKeycode, int cecKeycode, int param) { this.mAndroidKeycode = androidKeycode; this.mCecKeycode = cecKeycode; this.mParam = param; private KeycodeEntry(int androidKeycode, int cecKeycode, int param, boolean isRepeatable) { mAndroidKeycode = androidKeycode; mCecKeycode = cecKeycode; mParam = param; mIsRepeatable = isRepeatable; } private KeycodeEntry(int androidKeycode, int cecKeycode) { this(androidKeycode, cecKeycode, NO_PARAM); this(androidKeycode, cecKeycode, NO_PARAM, true); } private KeycodeEntry(int androidKeycode, int cecKeycode, boolean isRepeatable) { this(androidKeycode, cecKeycode, NO_PARAM, isRepeatable); } private byte[] toCecKeycodeIfMatched(int androidKeycode) { Loading @@ -210,6 +216,14 @@ public class HdmiCecKeycode { return UNSUPPORTED_KEYCODE; } } private Boolean isRepeatableIfMatched(int androidKeycode) { if (mAndroidKeycode == androidKeycode) { return mIsRepeatable; } else { return null; } } } // Keycode entry container for all mappings. Loading @@ -221,19 +235,26 @@ public class HdmiCecKeycode { new KeycodeEntry(KeyEvent.KEYCODE_DPAD_LEFT, CEC_KEYCODE_LEFT), new KeycodeEntry(KeyEvent.KEYCODE_DPAD_RIGHT, CEC_KEYCODE_RIGHT), // No Android keycode defined for CEC_KEYCODE_RIGHT_UP new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RIGHT_UP), // No Android keycode defined for CEC_KEYCODE_RIGHT_DOWN new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RIGHT_DOWN), // No Android keycode defined for CEC_KEYCODE_LEFT_UP new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_LEFT_UP), // No Android keycode defined for CEC_KEYCODE_LEFT_DOWN new KeycodeEntry(KeyEvent.KEYCODE_HOME, CEC_KEYCODE_ROOT_MENU), new KeycodeEntry(KeyEvent.KEYCODE_SETTINGS, CEC_KEYCODE_SETUP_MENU), new KeycodeEntry(KeyEvent.KEYCODE_MENU, CEC_KEYCODE_CONTENTS_MENU), new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_LEFT_DOWN), new KeycodeEntry(KeyEvent.KEYCODE_HOME, CEC_KEYCODE_ROOT_MENU, false), new KeycodeEntry(KeyEvent.KEYCODE_SETTINGS, CEC_KEYCODE_SETUP_MENU, false), new KeycodeEntry(KeyEvent.KEYCODE_MENU, CEC_KEYCODE_CONTENTS_MENU, false), // No Android keycode defined for CEC_KEYCODE_FAVORITE_MENU new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_FAVORITE_MENU), new KeycodeEntry(KeyEvent.KEYCODE_BACK, CEC_KEYCODE_EXIT), // RESERVED new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_TOP_MENU, CEC_KEYCODE_MEDIA_TOP_MENU), // No Android keycode defined for CEC_KEYCODE_MEDIA_CONTEXT_SENSITIVE_MENU new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_MEDIA_CONTEXT_SENSITIVE_MENU), // RESERVED // No Android keycode defined for CEC_KEYCODE_NUMBER_ENTRY_MODE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_NUMBER_ENTRY_MODE), new KeycodeEntry(KeyEvent.KEYCODE_11, CEC_KEYCODE_NUMBER_11), new KeycodeEntry(KeyEvent.KEYCODE_12, CEC_KEYCODE_NUMBER_12), new KeycodeEntry(KeyEvent.KEYCODE_0, CEC_KEYCODE_NUMBER_0_OR_NUMBER_10), Loading @@ -251,20 +272,23 @@ public class HdmiCecKeycode { new KeycodeEntry(KeyEvent.KEYCODE_CLEAR, CEC_KEYCODE_CLEAR), // RESERVED // No Android keycode defined for CEC_KEYCODE_NEXT_FAVORITE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_NEXT_FAVORITE), new KeycodeEntry(KeyEvent.KEYCODE_CHANNEL_UP, CEC_KEYCODE_CHANNEL_UP), new KeycodeEntry(KeyEvent.KEYCODE_CHANNEL_DOWN, CEC_KEYCODE_CHANNEL_DOWN), new KeycodeEntry(KeyEvent.KEYCODE_LAST_CHANNEL, CEC_KEYCODE_PREVIOUS_CHANNEL), // No Android keycode defined for CEC_KEYCODE_SOUND_SELECT new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SOUND_SELECT), new KeycodeEntry(KeyEvent.KEYCODE_TV_INPUT, CEC_KEYCODE_INPUT_SELECT), new KeycodeEntry(KeyEvent.KEYCODE_INFO, CEC_KEYCODE_DISPLAY_INFORMATION), // No Android keycode defined for CEC_KEYCODE_HELP new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_HELP), new KeycodeEntry(KeyEvent.KEYCODE_PAGE_UP, CEC_KEYCODE_PAGE_UP), new KeycodeEntry(KeyEvent.KEYCODE_PAGE_DOWN, CEC_KEYCODE_PAGE_DOWN), // RESERVED new KeycodeEntry(KeyEvent.KEYCODE_POWER, CEC_KEYCODE_POWER), new KeycodeEntry(KeyEvent.KEYCODE_POWER, CEC_KEYCODE_POWER, false), new KeycodeEntry(KeyEvent.KEYCODE_VOLUME_UP, CEC_KEYCODE_VOLUME_UP), new KeycodeEntry(KeyEvent.KEYCODE_VOLUME_DOWN, CEC_KEYCODE_VOLUME_DOWN), new KeycodeEntry(KeyEvent.KEYCODE_VOLUME_MUTE, CEC_KEYCODE_MUTE), new KeycodeEntry(KeyEvent.KEYCODE_VOLUME_MUTE, CEC_KEYCODE_MUTE, false), new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_PLAY, CEC_KEYCODE_PLAY), new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_STOP, CEC_KEYCODE_STOP), new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_PAUSE, CEC_KEYCODE_PAUSE), Loading @@ -275,33 +299,57 @@ public class HdmiCecKeycode { new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_NEXT, CEC_KEYCODE_FORWARD), new KeycodeEntry(KeyEvent.KEYCODE_MEDIA_PREVIOUS, CEC_KEYCODE_BACKWARD), // No Android keycode defined for CEC_KEYCODE_STOP_RECORD new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_STOP_RECORD), // No Android keycode defined for CEC_KEYCODE_PAUSE_RECORD new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_RECORD), // No Android keycode defined for CEC_KEYCODE_RESERVED new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RESERVED), // No Android keycode defined for CEC_KEYCODE_ANGLE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_ANGLE), // No Android keycode defined for CEC_KEYCODE_SUB_PICTURE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SUB_PICTURE), // No Android keycode defined for CEC_KEYCODE_VIDEO_ON_DEMAND new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_VIDEO_ON_DEMAND), new KeycodeEntry(KeyEvent.KEYCODE_GUIDE, CEC_KEYCODE_ELECTRONIC_PROGRAM_GUIDE), // No Android keycode defined for CEC_KEYCODE_TIMER_PROGRAMMING new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_TIMER_PROGRAMMING), // No Android keycode defined for CEC_KEYCODE_INITIAL_CONFIGURATION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_INITIAL_CONFIGURATION), // No Android keycode defined for CEC_KEYCODE_SELECT_BROADCAST_TYPE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_BROADCAST_TYPE), // No Android keycode defined for CEC_KEYCODE_SELECT_SOUND_PRESENTATION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_SOUND_PRESENTATION), // RESERVED // The following deterministic key definitions do not need key mapping // since they are supposed to be generated programmatically only. // No Android keycode defined for CEC_KEYCODE_PLAY_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PLAY_FUNCTION), // No Android keycode defined for CEC_KEYCODE_PAUSE_PLAY_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_PLAY_FUNCTION), // No Android keycode defined for CEC_KEYCODE_RECORD_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RECORD_FUNCTION), // No Android keycode defined for CEC_KEYCODE_PAUSE_RECORD_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_RECORD_FUNCTION), // No Android keycode defined for CEC_KEYCODE_STOP_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_STOP_FUNCTION), // No Android keycode defined for CEC_KEYCODE_MUTE_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_MUTE_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_RESTORE_VOLUME_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RESTORE_VOLUME_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_TUNE_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_TUNE_FUNCTION), // No Android keycode defined for CEC_KEYCODE_SELECT_MEDIA_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_MEDIA_FUNCTION), // No Android keycode defined for CEC_KEYCODE_SELECT_AV_INPUT_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_AV_INPUT_FUNCTION), // No Android keycode defined for CEC_KEYCODE_SELECT_AUDIO_INPUT_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_AUDIO_INPUT_FUNCTION), // No Android keycode defined for CEC_KEYCODE_POWER_TOGGLE_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_TOGGLE_FUNCTION), // No Android keycode defined for CEC_KEYCODE_POWER_OFF_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_OFF_FUNCTION), // No Android keycode defined for CEC_KEYCODE_POWER_ON_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_ON_FUNCTION, false), // RESERVED new KeycodeEntry(KeyEvent.KEYCODE_PROG_BLUE, CEC_KEYCODE_F1_BLUE), new KeycodeEntry(KeyEvent.KEYCODE_PROG_RED, CEC_KEYCODE_F2_RED), Loading Loading @@ -346,4 +394,20 @@ public class HdmiCecKeycode { } return UNSUPPORTED_KEYCODE; } /** * Whether the given {@code androidKeycode} is repeatable key or not. * * @param androidKeycode keycode of android * @return false if the given {@code androidKeycode} is not supported key code */ static boolean isRepeatableKey(int androidKeycode) { for (int i = 0; i < KEYCODE_ENTRIES.length; ++i) { Boolean isRepeatable = KEYCODE_ENTRIES[i].isRepeatableIfMatched(androidKeycode); if (isRepeatable != null) { return isRepeatable; } } return false; } }
services/core/java/com/android/server/hdmi/SendKeyAction.java +29 −18 Original line number Diff line number Diff line Loading @@ -44,24 +44,30 @@ final class SendKeyAction extends FeatureAction { private final int mTargetAddress; // The key code of the last key press event the action is passed via processKeyEvent. private int mLastKeyCode; private int mLastKeycode; /** * 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} * @param keycode remote control key code as defined in {@link KeyEvent} */ SendKeyAction(HdmiCecLocalDevice source, int targetAddress, int keyCode) { SendKeyAction(HdmiCecLocalDevice source, int targetAddress, int keycode) { super(source); mTargetAddress = targetAddress; mLastKeyCode = keyCode; mLastKeycode = keycode; } @Override public boolean start() { sendKeyDown(mLastKeyCode); sendKeyDown(mLastKeycode); // finish action for non-repeatable key. if (!HdmiCecKeycode.isRepeatableKey(mLastKeycode)) { sendKeyUp(); finish(); return true; } mState = STATE_PROCESSING_KEYCODE; addTimer(mState, IRT_MS); return true; Loading @@ -70,10 +76,10 @@ final class SendKeyAction extends FeatureAction { /** * Called when a key event should be handled for the action. * * @param keyCode key code of {@link KeyEvent} object * @param keycode key code of {@link KeyEvent} object * @param isPressed true if the key event is of {@link KeyEvent#ACTION_DOWN} */ void processKeyEvent(int keyCode, boolean isPressed) { void processKeyEvent(int keycode, boolean isPressed) { if (mState != STATE_PROCESSING_KEYCODE) { Slog.w(TAG, "Not in a valid state"); return; Loading @@ -84,27 +90,32 @@ final class SendKeyAction extends FeatureAction { // Key release event indicates that the action shall be finished. Send UCR // command and terminate the action. Other release events are ignored. if (isPressed) { if (keyCode != mLastKeyCode) { if (keycode != mLastKeycode) { if (!HdmiCecKeycode.isRepeatableKey(keycode)) { sendKeyUp(); finish(); return; } mActionTimer.clearTimerMessage(); sendKeyDown(keyCode); sendKeyDown(keycode); addTimer(mState, IRT_MS); mLastKeyCode = keyCode; mLastKeycode = keycode; } } else { if (keyCode == mLastKeyCode) { if (keycode == mLastKeycode) { sendKeyUp(); finish(); } } } private void sendKeyDown(int keyCode) { byte[] keyCodeAndParam = getCecKeyCodeAndParam(keyCode); if (keyCodeAndParam == null) { private void sendKeyDown(int keycode) { byte[] keycodeAndParam = getCecKeycodeAndParam(keycode); if (keycodeAndParam == null) { return; } sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(), mTargetAddress, keyCodeAndParam)); mTargetAddress, keycodeAndParam)); } private void sendKeyUp() { Loading @@ -128,7 +139,7 @@ final class SendKeyAction extends FeatureAction { Slog.w(TAG, "Not in a valid state"); return; } sendKeyDown(mLastKeyCode); sendKeyDown(mLastKeycode); addTimer(mState, IRT_MS); } Loading @@ -137,7 +148,7 @@ final class SendKeyAction extends FeatureAction { // Broadcast' with the parameter 'cable', for instance, shall have its counterpart such as // KeyEvent.KEYCODE_TV_BROADCAST_CABLE. // The return byte array contains both UI command (keycode) and optional parameter. private byte[] getCecKeyCodeAndParam(int keyCode) { return HdmiCecKeycode.androidKeyToCecKey(keyCode); private byte[] getCecKeycodeAndParam(int keycode) { return HdmiCecKeycode.androidKeyToCecKey(keycode); } }