博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
和菜鸟一起学android4.0.3源码之touchscreen配置+调试记录
阅读量:5203 次
发布时间:2019-06-13

本文共 40311 字,大约阅读时间需要 134 分钟。

        记得应该是上上周了,终于毕业了,离开了学校,就得面对现实的社会,以前学校实验室里,老师给了钥匙,那电脑随便用,那元器件随便玩,什么51单片机啊,PIC单片机啊,FPGA啊,arm11啊什么的。想着做什么就直接万用版+电烙铁什么的一起搞定。调试,写程序,焊板子都是自己一手操办啊,多么自由啊。到了公司,可不依你,对于上市公司来说,管理什么的总归还是有些规范化的。

        对于嵌入式,虽然早有所耳闻,大三也玩过arm7,编了几个基于GUI的贪吃蛇啊,黑白棋啊,连连看啊什么的。自己也买来arm11,烧写linux系统,搭建环境,最终也成功完成了hello world驱动模块。待以后有时间再好好整理整理。废话不多说了,既然是anrdroid下的touchscreen的配置,那就专心点,不东扯西扯了。
     都说android4.0.3的touchscreen有了很大的变化,菜鸟也不知道这么庞大的代码,各个功能模块式干嘛的。只能找找资料,瞎折腾了。公司的任务,触摸屏得上了,android的东西,只用鼠标可不好玩啊。开始调试SPI模式的ads7846的电阻屏,板子没有SPI接口,于是就用GPIO模拟SPI的方式来实现SPI的功能,在此要说明下,这个嵌入式的板子就是和51,PIC的板子用起来不一样啊,什么工作队列,什么中断下半部分工作,什么总线啊,I2C啊,SPI啊,I2S啊,USB啊,都这么纠结,顿时觉得学得好少啊,自己又有点懒,什么都想学,至于什么也没学好。调试好驱动后,总算是完成了一半的工作,接着,是否要直接上android去跑呢?android里什么机制都不知道额,虽然一开始android中实现鼠标的时候小研究过android下的input那个框架,不过只是模模糊糊的概念,根本就没有弄清楚。看来得下点功夫啊,要不然怎么混啊。又偏题了,额,正题,正题。。
         直接上android了,突然发现出现了一个小圈圈。向鼠标一样的。貌似触摸屏变成了鼠标了。觉得太怪了,怎么可以这样?肯定那里有问题的,找了好久的资料,终于找到了,原来是android4.0.3,他的touchscreen是需要配置文件的。只要直接创建一个“设备名.idc”的文件,直接放到/system/usr/idc/目录下,就可以了,设备名是驱动中定义的,在android中的Eventhub中也是可以加打印在logcat中看出来的。

# Basic Parameters   touch.deviceType = touchScreen   touch.orientationAware = 1   # Size   touch.size.calibration = diameter   touch.size.scale = 10   touch.size.bias = 0   touch.size.isSummed = 0   # Pressure   # Driver reports signal strength as pressure.   #   # A normal thumb touch typically registers about 200 signal strength   # units although we don't expect these values to be accurate.   touch.pressure.calibration = amplitude   touch.pressure.scale = 0.005   # Orientation   touch.orientation.calibration = none

        但是就知道了这个配置文件,具体那里实现的呢?怎么配置进去的呢?怎么看着你个是touch.deviceType = touchScreen这个决定的。不多说来代码
frameworks/base/services/input/InputReader.cpp

void TouchInputMapper::configureParameters() {    // Use the pointer presentation mode for devices that do not support distinct    // multitouch.  The spot-based presentation relies on being able to accurately    // locate two or more fingers on the touch pad.    mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)            ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;    String8 gestureModeString;    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),            gestureModeString)) {        if (gestureModeString == "pointer") {            mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;        } else if (gestureModeString == "spots") {            mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;        } else if (gestureModeString != "default") {            LOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());        }    }    if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {        // The device is a touch screen.        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;    } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {        // The device is a pointing device like a track pad.        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;    } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)            || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {        // The device is a cursor device with a touch pad attached.        // By default don't use the touch pad to move the pointer.        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;    } else {        // The device is a touch pad of unknown purpose.        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;    }    String8 deviceTypeString;    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),            deviceTypeString)) {        if (deviceTypeString == "touchScreen") {            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;        } else if (deviceTypeString == "touchPad") {            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;        } else if (deviceTypeString == "pointer") {            mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;        } else if (deviceTypeString != "default") {            LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());        }    }    mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;    getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),            mParameters.orientationAware);    mParameters.associatedDisplayId = -1;    mParameters.associatedDisplayIsExternal = false;    if (mParameters.orientationAware            || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN            || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {        mParameters.associatedDisplayIsExternal =                mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN                        && getDevice()->isExternal();        mParameters.associatedDisplayId = 0;    }}

     还是英文呢,看到第一行,如果没有配置的话,那就是pointer,pointer不就是鼠标吗?只有定义deviceType为touchScreen,那才是我们要的啊。看来英文真的好重要好重

要啊。那到底是那里去获取配置文件的呢?不是一般都是EventHub下打开什么文件吗?走,咱们去seesee。

frameworks/base/services/input/EventHub.cpp

void EventHub::loadConfigurationLocked(Device* device) {    device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(            device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);    if (device->configurationFile.isEmpty()) {        LOGD("No input device configuration file found for device '%s'.",                device->identifier.name.string());    } else {        status_t status = PropertyMap::load(device->configurationFile,                &device->configuration);        if (status) {            LOGE("Error loading input device configuration file for device '%s'.  "                    "Using default configuration.",                    device->identifier.name.string());        }    }}

     原来就是这里去载入配置文件的。然后再进行配置的,接着我们看看那些配置是什么功能?上面的deviceType就不用说了,就是类型是触摸屏而不是touchPad和pointer。

pointer是鼠标类似的光标,touchPad还没试过,板子上的触摸屏也拆了,也没法跳了。不知道是什么,下次有机会去试试。差不多应该和touchScreen差不多。那么

touch.size.calibration等一些配置是什么?有什么作用呢?还是代码看起

frameworks/base/services/input/InputReader.cpp

void TouchInputMapper::parseCalibration() {    const PropertyMap& in = getDevice()->getConfiguration();    Calibration& out = mCalibration;    // Size    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;    String8 sizeCalibrationString;    if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {        if (sizeCalibrationString == "none") {            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;        } else if (sizeCalibrationString == "geometric") {            out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;        } else if (sizeCalibrationString == "diameter") {            out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;        } else if (sizeCalibrationString == "area") {            out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;        } else if (sizeCalibrationString != "default") {            LOGW("Invalid value for touch.size.calibration: '%s'",                    sizeCalibrationString.string());        }    }    out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),            out.sizeScale);    out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),            out.sizeBias);    out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),            out.sizeIsSummed);    // Pressure    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;    String8 pressureCalibrationString;    if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {        if (pressureCalibrationString == "none") {            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;        } else if (pressureCalibrationString == "physical") {            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;        } else if (pressureCalibrationString == "amplitude") {            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;        } else if (pressureCalibrationString != "default") {            LOGW("Invalid value for touch.pressure.calibration: '%s'",                    pressureCalibrationString.string());        }    }    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),            out.pressureScale);    // Orientation    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;    String8 orientationCalibrationString;    if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {        if (orientationCalibrationString == "none") {            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;        } else if (orientationCalibrationString == "interpolated") {            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;        } else if (orientationCalibrationString == "vector") {            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;        } else if (orientationCalibrationString != "default") {            LOGW("Invalid value for touch.orientation.calibration: '%s'",                    orientationCalibrationString.string());        }    }    // Distance    out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;    String8 distanceCalibrationString;    if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {        if (distanceCalibrationString == "none") {            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;        } else if (distanceCalibrationString == "scaled") {            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;        } else if (distanceCalibrationString != "default") {            LOGW("Invalid value for touch.distance.calibration: '%s'",                    distanceCalibrationString.string());        }    }    out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),            out.distanceScale);}

        touch.size.calibration分为了1、geometric 2、diameter 3、area,老师说不懂的单词要查字典,现在都什么年代了,随便谷歌一下,手机也行。什么牛津字典啊的,那都是浮云了。geometric:几何图形?怪怪的,是不是代表不同的触摸的形状?不懂,diameter倒是还好,直径嘛应该是一个触摸的点是以这个为直径的一个圆,至于area嘛,区域,难道是多点的时候?也许吧。touch.pressure.calibration分为了1、physical 2、amplitude 。physical:物理的,是不是理论上的?amplitude是不是幅度就是压力的大小?不懂额。要不再来看看代码?那些配置之后肯定有执行的。不可能简简单单的就是赋值了。找找看
frameworks/base/services/input/InputReader.cpp

void TouchInputMapper::cookPointerData() {    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;    mCurrentCookedPointerData.clear();    mCurrentCookedPointerData.pointerCount = currentPointerCount;    mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;    mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;    // Walk through the the active pointers and map device coordinates onto    // surface coordinates and adjust for display orientation.    for (uint32_t i = 0; i < currentPointerCount; i++) {        const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];        // Size        float touchMajor, touchMinor, toolMajor, toolMinor, size;        switch (mCalibration.sizeCalibration) {        case Calibration::SIZE_CALIBRATION_GEOMETRIC:        case Calibration::SIZE_CALIBRATION_DIAMETER:        case Calibration::SIZE_CALIBRATION_AREA:            if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {                touchMajor = in.touchMajor;                touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;                toolMajor = in.toolMajor;                toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;                size = mRawPointerAxes.touchMinor.valid                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;            } else if (mRawPointerAxes.touchMajor.valid) {                toolMajor = touchMajor = in.touchMajor;                toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid                        ? in.touchMinor : in.touchMajor;                size = mRawPointerAxes.touchMinor.valid                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;            } else if (mRawPointerAxes.toolMajor.valid) {                touchMajor = toolMajor = in.toolMajor;                touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid                        ? in.toolMinor : in.toolMajor;                size = mRawPointerAxes.toolMinor.valid                        ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;            } else {                LOG_ASSERT(false, "No touch or tool axes.  "                        "Size calibration should have been resolved to NONE.");                touchMajor = 0;                touchMinor = 0;                toolMajor = 0;                toolMinor = 0;                size = 0;            }            if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {                uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();                if (touchingCount > 1) {                    touchMajor /= touchingCount;                    touchMinor /= touchingCount;                    toolMajor /= touchingCount;                    toolMinor /= touchingCount;                    size /= touchingCount;                }            }            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {                touchMajor *= mGeometricScale;                touchMinor *= mGeometricScale;                toolMajor *= mGeometricScale;                toolMinor *= mGeometricScale;            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {                touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;                touchMinor = touchMajor;                toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;                toolMinor = toolMajor;            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {                touchMinor = touchMajor;                toolMinor = toolMajor;            }            mCalibration.applySizeScaleAndBias(&touchMajor);            mCalibration.applySizeScaleAndBias(&touchMinor);            mCalibration.applySizeScaleAndBias(&toolMajor);            mCalibration.applySizeScaleAndBias(&toolMinor);            size *= mSizeScale;            break;        default:            touchMajor = 0;            touchMinor = 0;            toolMajor = 0;            toolMinor = 0;            size = 0;            break;        }        // Pressure        float pressure;        switch (mCalibration.pressureCalibration) {        case Calibration::PRESSURE_CALIBRATION_PHYSICAL:        case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:            pressure = in.pressure * mPressureScale;            break;        default:            pressure = in.isHovering ? 0 : 1;            break;        }        // Tilt and Orientation        float tilt;        float orientation;        if (mHaveTilt) {            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));        } else {            tilt = 0;            switch (mCalibration.orientationCalibration) {            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:                orientation = (in.orientation - mOrientationCenter) * mOrientationScale;                break;            case Calibration::ORIENTATION_CALIBRATION_VECTOR: {                int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);                int32_t c2 = signExtendNybble(in.orientation & 0x0f);                if (c1 != 0 || c2 != 0) {                    orientation = atan2f(c1, c2) * 0.5f;                    float confidence = hypotf(c1, c2);                    float scale = 1.0f + confidence / 16.0f;                    touchMajor *= scale;                    touchMinor /= scale;                    toolMajor *= scale;                    toolMinor /= scale;                } else {                    orientation = 0;                }                break;            }            default:                orientation = 0;            }        }        // Distance        float distance;        switch (mCalibration.distanceCalibration) {        case Calibration::DISTANCE_CALIBRATION_SCALED:            distance = in.distance * mDistanceScale;            break;        default:            distance = 0;        }        // X and Y        // Adjust coords for surface orientation.        float x, y;        switch (mSurfaceOrientation) {        case DISPLAY_ORIENTATION_90:            x = float(in.y - mRawPointerAxes.y.minValue) * mYScale;            y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;            orientation -= M_PI_2;            if (orientation < - M_PI_2) {                orientation += M_PI;            }            break;        case DISPLAY_ORIENTATION_180:            x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;            y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;            break;        case DISPLAY_ORIENTATION_270:            x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;            y = float(in.x - mRawPointerAxes.x.minValue) * mXScale;            orientation += M_PI_2;            if (orientation > M_PI_2) {                orientation -= M_PI;            }            break;        default:            x = float(in.x - mRawPointerAxes.x.minValue) * mXScale;            y = float(in.y - mRawPointerAxes.y.minValue) * mYScale;            break;        }        // Write output coords.        PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];        out.clear();        out.setAxisValue(AMOTION_EVENT_AXIS_X, x);        out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);        out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);        out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);        // Write output properties.        PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];        uint32_t id = in.id;        properties.clear();        properties.id = id;        properties.toolType = in.toolType;        // Write id index.        mCurrentCookedPointerData.idToIndex[id] = i;    }}

    这数据处理的,cookPointerData,哈哈哈,原来都在这里搞定的啊。TouchMajor and TouchMinor表示了触摸时接触面积的大小范围。这个函数会把驱动上传上来的数据,也就是X、Y坐标转换为android设定的分辨率的一个映射。差不多就这样了。具体,碰到问题了在解决了。

    在此,有时候再讲讲自己调试的时候碰到的一个问题,那就是android电源管理中会把背光给关掉,所以点死了触摸屏还是发现没用。所以调试的时候可以把其中的一个

policyFlags设置下,不要drop掉,也就是即使背光关掉了也可以有效。

frameworks/base/services/input/InputDispatcher.cpp

 

   

void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {    nsecs_t currentTime = now();    // Reset the key repeat timer whenever we disallow key events, even if the next event    // is not a key.  This is to ensure that we abort a key repeat if the device is just coming    // out of sleep.    if (!mPolicy->isKeyRepeatEnabled()) {        resetKeyRepeatLocked();    }    // If dispatching is frozen, do not process timeouts or try to deliver any new events.    if (mDispatchFrozen) {#if DEBUG_FOCUS        LOGD("Dispatch frozen.  Waiting some more.");#endif        return;    }    // Optimize latency of app switches.    // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has    // been pressed.  When it expires, we preempt dispatch and drop all other pending events.    bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;    if (mAppSwitchDueTime < *nextWakeupTime) {        *nextWakeupTime = mAppSwitchDueTime;    }    // Ready to start a new event.    // If we don't already have a pending event, go grab one.    if (! mPendingEvent) {        if (mInboundQueue.isEmpty()) {            if (isAppSwitchDue) {                // The inbound queue is empty so the app switch key we were waiting                // for will never arrive.  Stop waiting for it.                resetPendingAppSwitchLocked(false);                isAppSwitchDue = false;            }            // Synthesize a key repeat if appropriate.            if (mKeyRepeatState.lastKeyEntry) {                if (currentTime >= mKeyRepeatState.nextRepeatTime) {                    mPendingEvent = synthesizeKeyRepeatLocked(currentTime);                } else {                    if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {                        *nextWakeupTime = mKeyRepeatState.nextRepeatTime;                    }                }            }            // Nothing to do if there is no pending event.            if (! mPendingEvent) {                if (mActiveConnections.isEmpty()) {                    dispatchIdleLocked();                }                return;            }        } else {            // Inbound queue has at least one entry.            EventEntry* entry = mInboundQueue.head;            // Throttle the entry if it is a move event and there are no            // other events behind it in the queue.  Due to movement batching, additional            // samples may be appended to this event by the time the throttling timeout            // expires.            // TODO Make this smarter and consider throttling per device independently.            if (entry->type == EventEntry::TYPE_MOTION                    && !isAppSwitchDue                    && mDispatchEnabled                    && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)                    && !entry->isInjected()) {                MotionEntry* motionEntry = static_cast
(entry); int32_t deviceId = motionEntry->deviceId; uint32_t source = motionEntry->source; if (! isAppSwitchDue && !motionEntry->next // exactly one event, no successors && (motionEntry->action == AMOTION_EVENT_ACTION_MOVE || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE) && deviceId == mThrottleState.lastDeviceId && source == mThrottleState.lastSource) { nsecs_t nextTime = mThrottleState.lastEventTime + mThrottleState.minTimeBetweenEvents; if (currentTime < nextTime) { // Throttle it!#if DEBUG_THROTTLING LOGD("Throttling - Delaying motion event for " "device %d, source 0x%08x by up to %0.3fms.", deviceId, source, (nextTime - currentTime) * 0.000001);#endif if (nextTime < *nextWakeupTime) { *nextWakeupTime = nextTime; } if (mThrottleState.originalSampleCount == 0) { mThrottleState.originalSampleCount = motionEntry->countSamples(); } return; } }#if DEBUG_THROTTLING if (mThrottleState.originalSampleCount != 0) { uint32_t count = motionEntry->countSamples(); LOGD("Throttling - Motion event sample count grew by %d from %d to %d.", count - mThrottleState.originalSampleCount, mThrottleState.originalSampleCount, count); mThrottleState.originalSampleCount = 0; }#endif mThrottleState.lastEventTime = currentTime; mThrottleState.lastDeviceId = deviceId; mThrottleState.lastSource = source; } mInboundQueue.dequeue(entry); mPendingEvent = entry; } // Poke user activity for this event. if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) { pokeUserActivityLocked(mPendingEvent); } } // Now we have an event to dispatch. // All events are eventually dequeued and processed this way, even if we intend to drop them. LOG_ASSERT(mPendingEvent != NULL); bool done = false; DropReason dropReason = DROP_REASON_NOT_DROPPED; if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) { dropReason = DROP_REASON_POLICY; } else if (!mDispatchEnabled) { dropReason = DROP_REASON_DISABLED; } if (mNextUnblockedEvent == mPendingEvent) { mNextUnblockedEvent = NULL; } switch (mPendingEvent->type) { case EventEntry::TYPE_CONFIGURATION_CHANGED: { ConfigurationChangedEntry* typedEntry = static_cast
(mPendingEvent); done = dispatchConfigurationChangedLocked(currentTime, typedEntry); dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped break; } case EventEntry::TYPE_DEVICE_RESET: { DeviceResetEntry* typedEntry = static_cast
(mPendingEvent); done = dispatchDeviceResetLocked(currentTime, typedEntry); dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped break; } case EventEntry::TYPE_KEY: { KeyEntry* typedEntry = static_cast
(mPendingEvent); if (isAppSwitchDue) { if (isAppSwitchKeyEventLocked(typedEntry)) { resetPendingAppSwitchLocked(true); isAppSwitchDue = false; } else if (dropReason == DROP_REASON_NOT_DROPPED) { dropReason = DROP_REASON_APP_SWITCH; } } if (dropReason == DROP_REASON_NOT_DROPPED && isStaleEventLocked(currentTime, typedEntry)) { dropReason = DROP_REASON_STALE; } if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) { dropReason = DROP_REASON_BLOCKED; } done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime); break; } case EventEntry::TYPE_MOTION: { MotionEntry* typedEntry = static_cast
(mPendingEvent); if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) { dropReason = DROP_REASON_APP_SWITCH; } if (dropReason == DROP_REASON_NOT_DROPPED && isStaleEventLocked(currentTime, typedEntry)) { dropReason = DROP_REASON_STALE; } if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) { dropReason = DROP_REASON_BLOCKED; } done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime); break; } default: LOG_ASSERT(false); break; } if (done) { if (dropReason != DROP_REASON_NOT_DROPPED) { dropInboundEventLocked(mPendingEvent, dropReason); } releasePendingEventLocked(); *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately }}

        只要把下面的东西给注释掉就好了,那具体的policyflags是哪里赋值的呢?真心找了我好久的。

frameworks/base/services/input/InputDispatcher.cpp

 

if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {        dropReason = DROP_REASON_POLICY;    } else if (!mDispatchEnabled) {        dropReason = DROP_REASON_DISABLED;    }

frameworks/base/services/input/InputDispatcher.cpp 

void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {#if DEBUG_INBOUND_EVENT_DETAILS    LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "            "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "            "xPrecision=%f, yPrecision=%f, downTime=%lld",            args->eventTime, args->deviceId, args->source, args->policyFlags,            args->action, args->flags, args->metaState, args->buttonState,            args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);    for (uint32_t i = 0; i < args->pointerCount; i++) {        LOGD("  Pointer %d: id=%d, toolType=%d, "                "x=%f, y=%f, pressure=%f, size=%f, "                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "                "orientation=%f",                i, args->pointerProperties[i].id,                args->pointerProperties[i].toolType,                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));    }#endif    if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {        return;    }    uint32_t policyFlags = args->policyFlags;    policyFlags |= POLICY_FLAG_TRUSTED;    mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);    bool needWake;    { // acquire lock        mLock.lock();        if (mInputFilterEnabled) {            mLock.unlock();            MotionEvent event;            event.initialize(args->deviceId, args->source, args->action, args->flags,                    args->edgeFlags, args->metaState, args->buttonState, 0, 0,                    args->xPrecision, args->yPrecision,                    args->downTime, args->eventTime,                    args->pointerCount, args->pointerProperties, args->pointerCoords);            policyFlags |= POLICY_FLAG_FILTERED;            if (!mPolicy->filterInputEvent(&event, policyFlags)) {                return; // event was consumed by the filter            }            mLock.lock();        }        // Attempt batching and streaming of move events.        if (args->action == AMOTION_EVENT_ACTION_MOVE                || args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) {            // BATCHING CASE            //            // Try to append a move sample to the tail of the inbound queue for this device.            // Give up if we encounter a non-move motion event for this device since that            // means we cannot append any new samples until a new motion event has started.            for (EventEntry* entry = mInboundQueue.tail; entry; entry = entry->prev) {                if (entry->type != EventEntry::TYPE_MOTION) {                    // Keep looking for motion events.                    continue;                }                MotionEntry* motionEntry = static_cast
(entry); if (motionEntry->deviceId != args->deviceId || motionEntry->source != args->source) { // Keep looking for this device and source. continue; } if (!motionEntry->canAppendSamples(args->action, args->pointerCount, args->pointerProperties)) { // Last motion event in the queue for this device and source is // not compatible for appending new samples. Stop here. goto NoBatchingOrStreaming; } // Do the batching magic. batchMotionLocked(motionEntry, args->eventTime, args->metaState, args->pointerCoords, "most recent motion event for this device and source in the inbound queue"); mLock.unlock(); return; // done! } // BATCHING ONTO PENDING EVENT CASE // // Try to append a move sample to the currently pending event, if there is one. // We can do this as long as we are still waiting to find the targets for the // event. Once the targets are locked-in we can only do streaming. if (mPendingEvent && (!mPendingEvent->dispatchInProgress || !mCurrentInputTargetsValid) && mPendingEvent->type == EventEntry::TYPE_MOTION) { MotionEntry* motionEntry = static_cast
(mPendingEvent); if (motionEntry->deviceId == args->deviceId && motionEntry->source == args->source) { if (!motionEntry->canAppendSamples(args->action, args->pointerCount, args->pointerProperties)) { // Pending motion event is for this device and source but it is // not compatible for appending new samples. Stop here. goto NoBatchingOrStreaming; } // Do the batching magic. batchMotionLocked(motionEntry, args->eventTime, args->metaState, args->pointerCoords, "pending motion event"); mLock.unlock(); return; // done! } } // STREAMING CASE // // There is no pending motion event (of any kind) for this device in the inbound queue. // Search the outbound queue for the current foreground targets to find a dispatched // motion event that is still in progress. If found, then, appen the new sample to // that event and push it out to all current targets. The logic in // prepareDispatchCycleLocked takes care of the case where some targets may // already have consumed the motion event by starting a new dispatch cycle if needed. if (mCurrentInputTargetsValid) { for (size_t i = 0; i < mCurrentInputTargets.size(); i++) { const InputTarget& inputTarget = mCurrentInputTargets[i]; if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) { // Skip non-foreground targets. We only want to stream if there is at // least one foreground target whose dispatch is still in progress. continue; } ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel); if (connectionIndex < 0) { // Connection must no longer be valid. continue; } sp
connection = mConnectionsByReceiveFd.valueAt(connectionIndex); if (connection->outboundQueue.isEmpty()) { // This foreground target has an empty outbound queue. continue; } DispatchEntry* dispatchEntry = connection->outboundQueue.head; if (! dispatchEntry->inProgress || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION || dispatchEntry->isSplit()) { // No motion event is being dispatched, or it is being split across // windows in which case we cannot stream. continue; } MotionEntry* motionEntry = static_cast
( dispatchEntry->eventEntry); if (motionEntry->action != args->action || motionEntry->deviceId != args->deviceId || motionEntry->source != args->source || motionEntry->pointerCount != args->pointerCount || motionEntry->isInjected()) { // The motion event is not compatible with this move. continue; } if (args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) { if (mLastHoverWindowHandle == NULL) {#if DEBUG_BATCHING LOGD("Not streaming hover move because there is no " "last hovered window.");#endif goto NoBatchingOrStreaming; } sp
hoverWindowHandle = findTouchedWindowAtLocked( args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y)); if (mLastHoverWindowHandle != hoverWindowHandle) {#if DEBUG_BATCHING LOGD("Not streaming hover move because the last hovered window " "is '%s' but the currently hovered window is '%s'.", mLastHoverWindowHandle->getName().string(), hoverWindowHandle != NULL ? hoverWindowHandle->getName().string() : "
");#endif goto NoBatchingOrStreaming; } } // Hurray! This foreground target is currently dispatching a move event // that we can stream onto. Append the motion sample and resume dispatch. motionEntry->appendSample(args->eventTime, args->pointerCoords);#if DEBUG_BATCHING LOGD("Appended motion sample onto batch for most recently dispatched " "motion event for this device and source in the outbound queues. " "Attempting to stream the motion sample.");#endif nsecs_t currentTime = now(); dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry, true /*resumeWithAppendedMotionSample*/); runCommandsLockedInterruptible(); mLock.unlock(); return; // done! } }NoBatchingOrStreaming:; } // Just enqueue a new motion event. MotionEntry* newEntry = new MotionEntry(args->eventTime, args->deviceId, args->source, policyFlags, args->action, args->flags, args->metaState, args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime, args->pointerCount, args->pointerProperties, args->pointerCoords); needWake = enqueueInboundEventLocked(newEntry); mLock.unlock(); } // release lock if (needWake) { mLooper->wake(); }}

 

看到了吗?就是这里了,interceptMotionBeforeQueueing()函数,

   

uint32_t policyFlags = args->policyFlags;    policyFlags |= POLICY_FLAG_TRUSTED;    mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);

 

void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {    // Policy:    // - Ignore untrusted events and pass them along.    // - No special filtering for injected events required at this time.    // - Filter normal events based on screen state.    // - For normal events brighten (but do not wake) the screen if currently dim.    if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {        if (isScreenOn()) {            policyFlags |= POLICY_FLAG_PASS_TO_USER;            if (!isScreenBright()) {                policyFlags |= POLICY_FLAG_BRIGHT_HERE;            }        } else {            JNIEnv* env = jniEnv();            jint wmActions = env->CallIntMethod(mCallbacksObj,                        gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,                        policyFlags);            if (checkAndClearExceptionFromCallback(env,                    "interceptMotionBeforeQueueingWhenScreenOff")) {                wmActions = 0;            }            policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;            handleInterceptActions(wmActions, when, /*byref*/ policyFlags);        }    } else {        policyFlags |= POLICY_FLAG_PASS_TO_USER;    }}

原来如此呢, if (isScreenOn()) 。搞定,收工,回去睡觉了,哈哈。。。

转载于:https://www.cnblogs.com/wuyida/archive/2012/06/27/6300096.html

你可能感兴趣的文章
css样式写一个三角形
查看>>
比callback更简洁的链式执行promise
查看>>
android permission
查看>>
javascript获取textarea中所选文本的开始位置、结束位置和选择的文本
查看>>
【译】在Asp.Net中操作PDF - iTextSharp - 使用字体
查看>>
事务备份还原分离附加
查看>>
JSch - Java实现的SFTP(文件上传详解篇)
查看>>
一些注意点
查看>>
.net 文本框只允许输入XX,(正则表达式)
查看>>
获得Windows系统的远程桌面连接历史记录
查看>>
C#修饰符
查看>>
20.核心初始化之异常向量表
查看>>
[BSGS][哈希]luogu P3846 可爱的质数
查看>>
Python 第四十五章 MySQL 内容回顾
查看>>
iostat参数说明
查看>>
js 封装获取元素的第一个元素
查看>>
iOS 获取Home键指纹验证
查看>>
Python-Mac 安装 PyQt4
查看>>
P2571 [SCOI2010]传送带
查看>>
哈希表1
查看>>