一、TV应用MainActivity
1.dispatchInputEvent
这里会特殊处理back键,只有Home键才会退出TV应用,back键会传递给cec连接的device处理。如果按键不在黑名单里面,会传递给应用处理。比如音量键就不会传递出去。
public boolean dispatchKeyEvent(KeyEvent event) {
if (SystemProperties.LOG_KEYEVENT.getValue()) Log.d(TAG, "dispatchKeyEvent(" + event + ")");
// If an activity is closed on a back key down event, back key down events with none zero
// repeat count or a back key up event can be happened without the first back key down
// event which should be ignored in this activity.
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
mBackKeyPressed = true;
}
if (!mBackKeyPressed) {
return true;
}
if (event.getAction() == KeyEvent.ACTION_UP) {
mBackKeyPressed = false;
}
}
.......
if (BLACKLIST_KEYCODE_TO_TIS.contains(event.getKeyCode())
|| KeyEvent.isGamepadButton(event.getKeyCode())) {
// If the event is in blacklisted or gamepad key, do not pass it to session.
// Gamepad keys are blacklisted to support TV UIs and here's the detail.
// If there's a TIS granted RECEIVE_INPUT_EVENT, TIF sends key events to TIS
// and return immediately saying that the event is handled.
// In this case, fallback key will be injected but with FLAG_CANCELED
// while gamepads support DPAD_CENTER and BACK by fallback.
// Since we don't expect that TIS want to handle gamepad buttons now,
// blacklist gamepad buttons and wait for next fallback keys.
// TODO: Need to consider other fallback keys (e.g. ESCAPE)
if (SystemProperties.USE_KEY.getValue() || TvSingletons.getSingletons(this).getSystemControlManager().getPropertyBoolean("tv.platform.need_key", false)) {
if (event.getAction() == KeyEvent.ACTION_UP) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
// It takes long time for TV app to finish, so stop TV first.
stopAll(false);
super.onBackPressed();
return true;
}
onKeyUp(event.getKeyCode(), event);
} else if (event.getAction() == KeyEvent.ACTION_DOWN) {
onKeyDown(event.getKeyCode(), event);
}
return true;
} else {
return super.dispatchKeyEvent(event);
}
}
return dispatchKeyEventToSession(event) || super.dispatchKeyEvent(event);
}
2.dispatchKeyEventToSession
这里主要是把KeyEvent交给TvView处理,因为TvView里面保存着对应的Session。
private boolean dispatchKeyEventToSession(final KeyEvent event) {
if (SystemProperties.LOG_KEYEVENT.getValue()) {
Log.d(TAG, "dispatchKeyEventToSession(" + event + ")");
}
.....
boolean handled = false;
if (mTvView != null) {