TIF 和Hdmi cec hotplug热插拔事件过程梳理一

从Hal开始,具体的code不贴了,只贴下接口。

1.注册接口

hardware\libhardware\include\hardware\hdmi_cec.h

    /*
     * (*register_event_callback)() registers a callback that HDMI-CEC HAL
     * can later use for incoming CEC messages or internal HDMI events.
     * When calling from C++, use the argument arg to pass the calling object.
     * It will be passed back when the callback is invoked so that the context
     * can be retrieved.
     */
    void (*register_event_callback)(const struct hdmi_cec_device* dev,
            event_callback_t callback, void* arg);

2.IHdmiCec callback接口回调实现

Z:\p\hardware\interfaces\tv\cec\1.0\default\HdmiCec.h

如果是HDMI_EVENT_HOT_PLUG,则会带上connected boolean值和对应的portId。如果是盒子的话,portId就是1,TV的话就是从1-4.

    static void eventCallback(const hdmi_event_t* event, void* /* arg */) {
        if (mCallback != nullptr && event != nullptr) {
            if (event->type == HDMI_EVENT_CEC_MESSAGE) {
                size_t length = std::min(event->cec.length,
                        static_cast<size_t>(MaxLength::MESSAGE_BODY));
                CecMessage cecMessage {
                    .initiator = static_cast<CecLogicalAddress>(event->cec.initiator),
                    .destination = static_cast<CecLogicalAddress>(event->cec.destination),
                };
                cecMessage.body.resize(length);
                for (size_t i = 0; i < length; ++i) {
                    cecMessage.body[i] = static_cast<uint8_t>(event->cec.body[i]);
                }
                mCallback->onCecMessage(cecMessage);
            } else if (event->type == HDMI_EVENT_HOT_PLUG) {
                HotplugEvent hotplugEvent {
                    .connected = event->hotplug.connected > 0,
                    .portId = static_cast<uint32_t>(event->hotplug.port_id)
                };
                mCallback->onHotplugEvent(hotplugEvent);
            }
        }
    }

3.android framework jni

会访问到java侧的HdmiCecController的handleHotplug方法。

Z:\p\frameworks\base\services\core\jni\com_android_server_hdmi_HdmiCecController.cpp

Return<void> HdmiCecController::HdmiCecCallback::onHotplugEvent(const HotplugEvent& event) {
    sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(mController, event));
    mController->mLooper->sendMessage(handler, HdmiCecEventHandler::EventType::HOT_PLUG);
    return Void();
}
    void propagateHotplugEvent(const HotplugEvent& event) {
        // Note that this method should be called in service thread.
        JNIEnv* env = AndroidRuntime::getJNIEnv();
        jint port = static_cast<jint>(event.portId);
        jboolean connected = (jboolean) event.connected;
        env->CallVoidMethod(mController->getCallbacksObj(),
                gHdmiCecControllerClassInfo.handleHotplug, port, connected);

        checkAndClearExceptionFromCallback(env, __FUNCTION__);
    }

 4. HdmiCecController

Z:\p\frameworks\base\services\core\java\com\android\server\hdmi\HdmiCecController.java

在打开log.tag.HDMI=DEBUG开关以后,会有port和connected的打印。

    /**
     * Called by native when a hotplug event issues.
     */
    @ServiceThreadOnly
    private void handleHotplug(int port, boolean connected) {
        assertRunOnServiceThread();
        HdmiLogger.debug("Hotplug event:[port:%d, connected:%b]", port, connected);
        mService.onHotplug(port, connected);
    }

5.HdmiControlService

①如果不是tv,就重新分配逻辑地址。

②调用HdmiCecLocalDevice的onHotplug回调,tv会调用HotplugDetectionAction进行设备列表的处理,其他类型的设备则可能会进行唤醒的处理。

③广播HotplugEvent。

广播HotplugEvent是后续事件传输过程的关键,因为下面会交给TIF来处理,更新TvInputManagerService里面Hdmi和Hardware相关设备的更新和对应接口add、remove的回调。

    /**
     * Called when a new hotplug event is issued.
     *
     * @param portId hdmi port number where hot plug event issued.
     * @param connected whether to be plugged in or not
     */
    @ServiceThreadOnly
    void onHotplug(int portId, boolean connected) {
       
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值