input event的flag赋值流程

本文详细解析了触摸输入映射中的关键流程,包括cookAndDispatch、consumeRawTouches、dispatchVirtualKey等函数的作用及其实现细节,并跟踪记录了policyFlags标志位的变化过程。





void TouchInputMapper::cookAndDispatch(nsecs_t when) {
             ......
              uint32_t policyFlags = 0;
             ......


 if (consumeRawTouches(when, policyFlags)) {
        mCurrentRawState.rawPointerData.clear();
    }


}


到了bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
           ......
           dispatchVirtualKey(when, policyFlags,
                        AKEY_EVENT_ACTION_UP,
                        AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
            }
           ......
}

之后是void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
        int32_t keyEventAction, int32_t keyEventFlags) {

                       ......

                      policyFlags |= POLICY_FLAG_VIRTUAL;

                      .......

                      NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
                    getListener()->notifyKey(&args);

                     ......

}


到void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {

               ......

                  if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
        policyFlags |= POLICY_FLAG_VIRTUAL;
        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
    }
    if (policyFlags & POLICY_FLAG_FUNCTION) {
        metaState |= AMETA_FUNCTION_ON;
    }


    policyFlags |= POLICY_FLAG_TRUSTED;
ALOGE("matt-policyFlags1=0x%x",policyFlags);

               ......

KeyEvent event;
    event.initialize(args->deviceId, args->source, args->action,
            flags, keyCode, args->scanCode, metaState, 0,
            args->downTime, args->eventTime);


    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);

             .......

}


到了void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
        uint32_t& policyFlags) {

 bool interactive = mInteractive.load();
ALOGE("matt-policyFlags2=0x%x",policyFlags);
    if (interactive) {
        policyFlags |= POLICY_FLAG_INTERACTIVE;
    }
    if ((policyFlags & POLICY_FLAG_TRUSTED)) {
ALOGE("matt-policyFlags & POLICY_FLAG_TRUSTED");
        nsecs_t when = keyEvent->getEventTime();
        JNIEnv* env = jniEnv();
        jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
        jint wmActions;
        if (keyEventObj) {
            wmActions = env->CallIntMethod(mServiceObj,
                    gServiceClassInfo.interceptKeyBeforeQueueing,
                    keyEventObj, policyFlags);
            if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
                wmActions = 0;
            }
            android_view_KeyEvent_recycle(env, keyEventObj);
            env->DeleteLocalRef(keyEventObj);
        } else {
            ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
            wmActions = 0;
        }


        handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
    } else {
        if (interactive) {
            policyFlags |= POLICY_FLAG_PASS_TO_USER;
        }
    }
ALOGE("matt-policyFlags3=0x%x",policyFlags);
}    

log入下:

09-15 10:34:49.914  2343  3332 E InputReader: matt-policyFlags=0
09-15 10:34:49.914  2343  3332 D InputDispatcher: matt-notifyKey - eventTime=94196055000, deviceId=9, source=0x101, policyFlags=0x2, action=0x1, flags=0x48, keyCode=0x3, scanCode=0x66, metaState=0x0, downTime=94153105000
09-15 10:34:49.914  2343  3332 E InputDispatcher: matt-policyFlags1=0x2000002
09-15 10:34:49.914  2343  3332 E InputManager-JNI: matt-policyFlags2=0x2000002
09-15 10:34:49.914  2343  3332 E InputManager-JNI: matt-policyFlags & POLICY_FLAG_TRUSTED
09-15 10:34:49.914  2343  3332 E InputManager-JNI: matt-policyFlags3=0x62000002


整个flag的赋值流程就结束了













<think>好的,用户想查找g_input_status函数未被触发的原因。首先,我需要回忆一下V4L2子设备的相关知识,以及可能的代码逻辑。根据用户提供的引用,特别是引用[3],里面提到sub-devices可能通过I2C总线连接,并且涉及到事件订阅的问题。这可能与事件注册或订阅机制有关。 接下来,用户提到要检查事件订阅、状态查询逻辑和初始化过程。首先,事件订阅部分,V4L2中通常使用v4l2_subdev_subscribe_event函数来订阅事件。如果这里没有正确调用,或者参数设置错误,比如event_type不正确,可能导致事件无法触发。比如,用户可能订阅了错误的事件类型,或者没有启用相应的通知。 然后,状态查询逻辑。g_input_status函数可能被设计为在特定事件发生时被调用,比如输入状态变化。如果硬件没有正确上报状态,或者驱动中的状态检测逻辑存在问题,比如没有正确读取寄存器的值,或者中断处理函数没有正确触发,那么这个函数可能不会被调用。需要检查驱动中是否有轮询机制或者中断处理,确保硬件状态变化能被及时捕获。 初始化过程也很关键。在初始化子设备时,可能漏掉了事件订阅的步骤,或者相关的v4l2_subdev结构体中的操作函数没有正确设置,比如.subscribe_event回调没有正确赋值。引用[2]提到打开设备时调用uvc_v4l2_open,可能在初始化过程中需要注册事件处理函数,如果这里遗漏了,就会导致事件无法触发。 另外,硬件连接问题也可能导致事件未被触发。比如,sub-device的I2C通信失败,或者传感器本身没有发送状态变化信号,这时候即使软件正确,硬件问题也会导致函数不被调用。需要检查硬件连接和传感器状态。 还有权限问题,比如用户空间应用没有足够的权限访问设备节点,导致无法接收事件。需要确认/dev下的设备节点权限是否正确,以及应用程序是否有访问权限。 可能还需要检查内核日志,使用dmesg查看是否有相关的错误信息,比如事件订阅失败、I2C通信错误等,这些日志可以提供线索。另外,确认V4L2的框架中是否有其他模块拦截或处理了事件,导致g_input_status未被调用。 最后,代码逻辑中的条件判断错误,比如在某些条件下跳过了事件处理,或者函数指针未正确赋值,导致g_input_status根本没有被注册到事件处理链中。需要仔细检查相关代码的注册和回调部分,确保每一步都正确执行。</think>根据V4L2驱动框架和引用内容,分析g_input_status未被触发的可能原因及排查步骤: 1. **事件订阅机制失效** - 检查是否调用$v4l2_subdev_subscribe_event()$时未指定$V4L2_EVENT_SOURCE_CHANGE$事件类型 - 确认`struct v4l2_fh`与`v4l2_subdev`的绑定关系是否正确建立 - 验证`v4l2_event_subscribe`返回值是否成功(需排除`-ENOSPC`等错误码) 2. **子设备状态检测异常** ```c // 典型状态检测逻辑示例 static int g_input_status(struct v4l2_subdev *sd, u32 *status) { struct cam_priv *priv = v4l2_get_subdevdata(sd); if (priv->sensor_powered_on) *status |= V4L2_IN_ST_NO_POWER; return 0; } ``` - 检查`sensor_powered_on`等状态标志的更新逻辑 - 验证硬件寄存器读取是否成功(需示波器/I2C嗅探器辅助) 3. **初始化流程缺陷** [^2] - 确认`uvc_v4l2_open`中是否漏掉`v4l2_subdev_call(sd, core, subscribe_event, ...)` - 检查`struct v4l2_subdev_core_ops`是否正确定义: ```c static const struct v4l2_subdev_core_ops cam_subdev_core_ops = { .g_input_status = g_input_status, // 必须显式关联 .subscribe_event = cam_subscribe_event, }; ``` 4. **框架层拦截机制** - 检查`V4L2_BUF_FLAG_DONE`标志处理逻辑是否异常[^1] - 验证`VIDIOC_DQEVENT`调用链是否被其他事件处理函数截断 5. **硬件连接问题** [^3] - 使用`i2cdetect`检测子设备地址是否响应 - 检查`sensor->ISP->主控`的物理连接状态 - 验证MIPI/I2C时钟信号质量 **验证方法建议**: 1. 在`g_input_status`添加`printk`调试输出 2. 通过`v4l2-ctl --subscribe-event=src_change`测试事件订阅 3. 检查`/sys/class/video4linux/videoX/`设备属性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值