HDMI Events Call Flow to TvInputService
In previous post we understood how HdmiControlManager.DEVICE_EVENT_ADD_DEVICE event is generated in Hdmi framework, now we will check further how this event is reached in TvInputFramework and finaly to a TvInputService implementation.There are 3 categories of events notified from HdmiControlService to TvInputFramework,
1.HotplugEvent and
2.DeviceEvent
3.SystemAudioModeChange
TvInputManagerService registers for these as EventListener in TvInputHardwareManager class.
TvInputHardwareManager manages the hardwares either of TvInputHal(tv_input_device_t) type implemented in tv_input.cpp or hdmi_cec_device Type implemented in HDMI-CEC hal.
public TvInputManagerService(){
mTvInputHardwareManager = new TvInputHardwareManager(context, new HardwareListener());
}
//TvInputHardwareManager.java
public void onBootPhase(int phase) {
mHdmiControlService.addHotplugEventListener(mHdmiHotplugEventListener);
mHdmiControlService.addDeviceEventListener(mHdmiDeviceEventListener);
mHdmiControlService.addSystemAudioModeChangeListener(
mHdmiSystemAudioModeChangeListener);
mHdmiDeviceList.addAll(mHdmiControlService.getInputDevices());
}
HdmiHotplugEventListener extends IHdmiHotplugEventListener.Stub {
public void onReceived(HdmiHotplugEvent event) {
mHdmiStateMap.put(event.getPort(), event.isConnected());
mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
convertConnectedToState(event.isConnected()), 0, inputId).sendToTarget();
}
HdmiDeviceEventListener extends IHdmiDeviceEventListener.Stub {
public void onStatusChanged(HdmiDeviceInfo deviceInfo, int status) {
switch (status) {
case HdmiControlManager.DEVICE_EVENT_ADD_DEVICE: {
mHdmiDeviceList.add(deviceInfo);
messageType = ListenerHandler.HDMI_DEVICE_ADDED;
}
case HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE: {
if (!mHdmiDeviceList.remove(originalDeviceInfo))
messageType = ListenerHandler.HDMI_DEVICE_REMOVED;
}
case HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE: {
if (!mHdmiDeviceList.remove(originalDeviceInfo)) {
mHdmiDeviceList.add(deviceInfo);
messageType = ListenerHandler.HDMI_DEVICE_UPDATED;
}
Message msg = mHandler.obtainMessage(messageType, 0, 0, obj);
msg.sendToTarget();
}
This handler notifies to TvInputManagerService.
ListenerHandler extends Handler {
public final void handleMessage(Message msg) {
switch (msg.what) {
case STATE_CHANGED: {
mListener.onStateChanged(inputId, state);
break;
}
case HDMI_DEVICE_ADDED: {
mListener.onHdmiDeviceAdded(info);
break;
}
case HDMI_DEVICE_REMOVED: {
mListener.onHdmiDeviceRemoved(info);
break;
}
TvInputManagerService broadcasts this event to all services currently available in system.
public void onHdmiDeviceAdded(HdmiDeviceInfo deviceInfo) {
// Broadcast the event to all hardware inputs.
serviceState.service.notifyHdmiDeviceAdded(deviceInfo);
}
TvInputService gets the event and posts to its handler which will call the onHdmiDeviceAdded.
TvInputService.java
void notifyHdmiDeviceAdded(HdmiDeviceInfo deviceInfo) {
mServiceHandler.obtainMessage(ServiceHandler.DO_ADD_HDMI_TV_INPUT,
deviceInfo).sendToTarget();
}
ServiceHandler extends Handler {
case DO_ADD_HDMI_TV_INPUT: {
HdmiDeviceInfo deviceInfo = (HdmiDeviceInfo) msg.obj;
TvInputInfo inputInfo = onHdmiDeviceAdded(deviceInfo);
if (inputInfo != null) {
broadcastAddHdmiTvInput(deviceInfo.getId(), inputInfo);
}
}
Note here that a custom TvInputService must override to modify default behavior of ignoring all HDMI logical input device i.e. build a TvInputInfo using this HdmiDeviceInfo and return it.
public TvInputInfo onHdmiDeviceAdded(HdmiDeviceInfo deviceInfo) {
return null;
}
(How to override this? link TvInputService Implementation : Creating TvInputInfo )
With this TvInputInfo, TvInputService broadcasts to TvInputManagerService so that it can add/update this new TvInputInfo in TvInputList.
broadcastAddHdmiTvInput(int id, TvInputInfo inputInfo) {
mCallbacks.getBroadcastItem(i).addHdmiTvInput(id, inputInfo);
}
In next post we will use this HdmiDeviceInfo/TvInputInfo for CEC communication implementation.
No comments:
Post a Comment