Android TIF provides manufacturers with a standard API for creating input modules that can control Android TV and allow them to search and recommend live TV content through metadata published by TV Input.
For specific introduction, please refer to official documents TV Input Framework | Android Open Source Project (google.cn)
The key processing flow of TIF is also introduced in the official text, which is relatively simple, as shown in the figure below. When there are problems, it is not enough. Therefore, here we combed the code flow involved in keys.
First of all, it is recommended to read first android -- distribution and processing flow analysis of key event KeyEvent_ Xiaoxiner's column - CSDN blog_ android key event distribution process In this article, understand the processing flow of keys in general.
Next, enter the text. In the TIF framework, when interacting with the user's keys, the keys of TvView class are passed to tvinputservice through dispatchKeyEvent() Session. You can see its comments.
/** * Displays TV contents. The TvView class provides a high level interface for applications to show * TV programs from various TV sources that implement {@link TvInputService}. (Note that the list of * TV inputs available on the system can be obtained by calling * {@link TvInputManager#getTvInputList() TvInputManager.getTvInputList()}.) * * <p>Once the application supplies the URI for a specific TV channel to {@link #tune} * method, it takes care of underlying service binding (and unbinding if the current TvView is * already bound to a service) and automatically allocates/deallocates resources needed. In addition * to a few essential methods to control how the contents are presented, it also provides a way to * dispatch input events to the connected TvInputService in order to enable custom key actions for * the TV input. */
There are also several ways to call dispatchKeyEvent in TvView:
- If TvView itself can get the focus, it will automatically go through activity: dispatchKeyEvent - > TvView: dispatchKeyEvent - > tis by default (do not override the dispatchKeyEvent of activity)
- TvView itself can not get focus, it needs manual programming, calling TvView:dispatchKeyEvent ->TIS in Activity:dispatchKeyEvent, (dispatchKeyEvent of override Activity).
- TvView itself can not get focus, it needs manual programming, calling TvView:dispatchKeyEvent ->TIS in Activity:onKeyDown/onKeyUp, (onKeyDown/onKeyUp of override Activity).
You can choose to use one according to your own scene;
The first disadvantage is that after the TvView is blocked, there is no way to pass the key to the TvView. The latter two are commonly used, and some keys that do not need to be passed to TvView/TIS can be intercepted as needed.
The second thing to note is that after the bottom layer consumes the keys, the Activity:dispatchKeyEvent theoretically returns true, and the onKeyDown/onKeyUp of the Activity will not be triggered again.
Take example 2,
The sending process of app side keys is: activity: dispatchkeyevent - > tvview: dispatchkeyevent - > tvinputmanager Session:dispatchInputEvent
-> TvInputManager.Session:sendInputEventOnMainLooperLocked -> TvInputEventSender:sendInputEvent -> nativeSendKeyEvent,
Finally, it is sent to the receiver through InputChannel, that is, the tvinputservice created through the TvView Session.
TvInputService. The receiving process of session key is as follows:
ITvInputSessionWrapper:TvInputEventReceiver:onInputEvent -> TvInputService.Session:dispatchInputEvent -> keyEvent.dispatch -> mOverlayViewContainer.getViewRootImpl().dispatchInputEvent
Keyevent Dispatch will continue to call tvinputservice onKeyDown/onKeyUp in session realizes the transfer of key. If onKeyDown/onKeyUp returns true, that is, after the key is consumed, the key will not continue to be sent to the overlay view for processing.
If it is a navigation key and the overlay view contains the ability to obtain the focus (whether the focus is currently obtained or not), the key will also be considered to be consumed and return to DISPATCH_HANDLED. Otherwise, follow the process of distributing keys in android viewGroup, find the appropriate view in the overlay viewcontainer to handle key events, and android -- distribution and processing flow analysis of key event KeyEvent_ Xiaoxiner's column - CSDN blog_ android key event distribution process Already introduced.
if (isNavigationKey && mOverlayViewContainer.hasFocusable()) { // If mOverlayView has focusable views, navigation key events should be always // handled. If not, it can make the application UI navigation messed up. // For example, in the case that the left-most view is focused, a left key event // will not be handled in ViewRootImpl. Then, the left key event will be handled in // the application during the UI navigation of the TV input. mOverlayViewContainer.getViewRootImpl().dispatchInputEvent(event); return TvInputManager.Session.DISPATCH_HANDLED; } else { mOverlayViewContainer.getViewRootImpl().dispatchInputEvent(event, receiver); return TvInputManager.Session.DISPATCH_IN_PROGRESS; }
At the end of the function, there are two different return s, which will affect onunhandledinputeventlistener in TvView Whether onunhandledinputevent will be called back to.
We're looking at tvview dispatchKeyEvent
When a key distribution is completed (may or may not be consumed), the inputeventsender is called back dispatchInputEventFinished -> InputEventSender. onInputEventFinished.
For TIF, its implementation is TvInputEventSender.
private final class TvInputEventSender extends InputEventSender { public TvInputEventSender(InputChannel inputChannel, Looper looper) { super(inputChannel, looper); } @Override public void onInputEventFinished(int seq, boolean handled) { finishedInputEvent(seq, handled, false); } }
TvInputManager.Session:finishedInputEvent -> TvInputManager.Session:invokeFinishedInputEventCallback -> TvInputManager.PendingEvent:run -> mCallback.onFinishedInputEvent.
The mCallback is in tvinputmanager Session. When dispatchinputevent, the FinishedInputEventCallback passed from TvView and assigned it to PendingEvent.
There is a judgment in onfinished inputevent. If the key has been consumed at the bottom, it will be returned directly.
Otherwise, call back to onunhandledinputeventlistener set by app Onunhandledinputevent.