视频播放的时候不拦截OK键
2015-02-03 12:29
120 查看
1.首先分析为了将OK键转换成鼠标左键的工作:
EventHub.h中
(1)定义NEED_CHANGE_MODE:
修改RawEvent的结构,增加 keyCode、flags两个成员
EventHub.cpp中
(2)在EventHub::openDeviceLocked()中不自动获取deviceID,而是通过指定(可能可以优化):
改成:
(3)在InputReader.h中
定义一些会用到的变量:
(4)在InputReader.cpp中做具体修改:
定义全局bool变量,用于判断是否要显示鼠标
在InputReader的构造函数中定义一些局部变量
添加一个移除焦点的函数:
处理在void InputReader::processEventsLocked()函数中:
这里做的工作就是:
1.
if(SENSOR_MOUSE_ID != deviceId && (classes & INPUT_DEVICE_CLASS_CURSOR))
先通过判断是否是鼠标设备。
如果是的话才做处理。
2.
if(!mPowerOn && rawEvent->type== EV_REL){//wake mouse for the first time
mOktoMouseSure = false;//Allows you to convert the OK key to mouse left key
mMousetoFocus = true;//unfade the cursor
mPowerOn = true;// the first use of the mouse after system launch
}
如果不处于开机状态,那么这时候收到一个rawEvent->type == EV_REL事件的时候
就要mPowerOn = true;以便后续根据这个变量点亮屏幕,达到按任意一个按键唤醒电视机的作用。
同时,第一次唤醒的时候,保持焦点模式。
3.
if(mWaitTime==0){
mWaitTime=now;
}else{
if((now-mWaitTime)*0.000000001>15){
if(rawEventLocal->code == SCANCODE_CENTER/*||rawEvent[1].scanCode==28*/){
processEventsForDeviceLocked(deviceId, rawEventLocal, batchSize);
mWaitTime=now;
mMousetoFocus=false;//fade the cursor
break;
}else{
if(rawEventLocal->type==EV_REL){//wake up the mouse after sleep
mOktoMouseSure = false;//Allows you to convert the OK key to mouse left key
mMousetoFocus = true;//unfade the cursor
}else if(rawEventLocal->code == SCANCODE_LEFT_MOUSE
/*The left Key of Mouse of the Remote Controller*/
||rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_LEFT_MOUSE
/*The left Key of Any Mouse*/){
mMousetoFocus=false;//fade the cursor
}else{
mOktoMouseSure=true;//Don't intercept the OK key
mFlags = true;//Mark the mouse after dormancy
}
}
}
mWaitTime=now;
}
这段代码的意思是:
每次收到按键都更新mWaitTime为当前时间。如果这一次的按键离上一次操作的时间超过了15min,也就是进入休眠了。
这个时候,如果按enter键,隐藏鼠标。而如果收到鼠标事件,则mOktoMouseSure = false;这样允许将OK键转换成左键。
mMousetoFocus = true;唤醒鼠标。否则,mOktoMouseSure=true;不对OK键作转换。
这里的mFlags用于标记鼠标处于休眠状态
4.
if(mFlags && rawEventLocal->type==EV_REL){//The mouse be awakened first after dormancy
mOktoMouseSure = false;//Allows you to convert the OK key to mouse left key
mFlags = false;
mMousetoFocus = true;//unfade the cursor
//Change the current event into the eliminational focus event.
removeFocusEventLocked(rawEventLocal, batchSize);
break;
}
这里就是针对鼠标的休眠状态做处理了,利用了前面的mFlags标记
5.
mTrueMouse,是用于标记是否对按键进行拦截的,我们只对down事件进行拦截和转换就可以了。
if(rawEventLocal->code == SCANCODE_LEFT_MOUSE
||rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_LEFT_MOUSE){
if(!mMousetoFocus){
mMousetoFocus=true;//unfade the cursor
mOktoMouseSure=false;//Allows you to convert the OK key to mouse left key
ALOGD("get mouse left click!: deviceid %d scancode: %d", deviceId, rawEvent->code);
//Change the current event into the eliminational focus event.
removeFocusEventLocked(rawEventLocal, batchSize);
break;
}
}
这里是对鼠标左键的处理。
6.
else if(rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_UP
|| rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_DOWN
|| rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_LEFT
|| rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_RIGHT
|| rawEventLocal->code == SCANCODE_DPAD_UP
|| rawEventLocal->code == SCANCODE_DPAD_DOWN
|| rawEventLocal->code == SCANCODE_DPAD_LEFT
|| rawEventLocal->code == SCANCODE_DPAD_RIGHT
/*The direction key of Remote Controller in IR mode.*/
||(rawEventLocal->value>458830&&rawEventLocal->value<458835)
/*The direction key of Keyboard.*/){
mMousetoFocus=false;//fade the cursor
mOktoMouseSure = true;//Don't intercept the OK key
}
这里就是实现对按任意方向键消隐鼠标的地方。
7.
if(!mMousetoFocus/* Drop The Cursor offset event of Mouse */){
for(size_t s=0;s<batchSize;s++){
if(rawEventLocal[s].type == EV_REL){
isCursor = 1;
break;
}
}
if(isCursor){
for(size_t j=0 ; j<batchSize; j++){
rawEventLocal[j].deviceId = 0;
rawEventLocal[j].type = -1;
rawEventLocal[j].code = -1;
rawEventLocal[j].value = -1;
rawEventLocal[j].keyCode = -1;
rawEventLocal[j].flags = -1;
rawEventLocal[j].when = -1;
}
isCursor = 0;
}
}
这就是,如果鼠标处于消隐状态,那么丢掉所有鼠标位移的事件
8
最后就是重点了
对OK键的处理:
if(!mOktoMouseSure && !bEnablePointer){//The OK key is converted to the mouse left key
前面的很多逻辑都是标记mOktoMouseSure【OK键是否要转换成鼠标左键】,(bEnablePointer应该可以去掉)
这里就是实现OK键转换的逻辑了
if(rawEventLocal[LOCAL_INDEX_SECOND].code== SCANCODE_CENTER){
deviceId=SENSOR_MOUSE_ID;
if(rawEventLocal[LOCAL_INDEX_SECOND].value==KEYEVENT_ACTION_DOWN){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_DOWN;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_SECOND].flags=0;
rawEventLocal[LOCAL_INDEX_SECOND].code=0;
rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0;
rawEventLocal[LOCAL_INDEX_SECOND].type=0;
rawEventLocal[LOCAL_INDEX_SECOND].value=0;
rawEventLocal[LOCAL_INDEX_THIRD].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_THIRD].flags=0;
rawEventLocal[LOCAL_INDEX_THIRD].code=0;
rawEventLocal[LOCAL_INDEX_THIRD].keyCode=0;
rawEventLocal[LOCAL_INDEX_THIRD].type=0;
rawEventLocal[LOCAL_INDEX_THIRD].value=0;
mTrueMouse=true;
}
else if(rawEventLocal[LOCAL_INDEX_SECOND].value==KEYEVENT_ACTION_UP){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_UP;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_SECOND].flags=0;
rawEventLocal[LOCAL_INDEX_SECOND].code=0;
rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0;
rawEventLocal[LOCAL_INDEX_SECOND].type=0;
rawEventLocal[LOCAL_INDEX_SECOND].value=0;
rawEventLocal[LOCAL_INDEX_THIRD].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_THIRD].flags=0;
rawEventLocal[LOCAL_INDEX_THIRD].code=0;
rawEventLocal[LOCAL_INDEX_THIRD].keyCode=0;
rawEventLocal[LOCAL_INDEX_THIRD].type=0;
rawEventLocal[LOCAL_INDEX_THIRD].value=0;
mTrueMouse=false;
}
}
else if(rawEventLocal->code== SCANCODE_CENTER/*The enter key / "OK" key event in IR mode*/){
deviceId=SENSOR_MOUSE_ID;
if(rawEventLocal->value==KEYEVENT_ACTION_REPEAT){
mTrueMouse=true;
break;
}
if(batchSize==4){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_DOWN;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_THIRD].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_THIRD].flags=0;
rawEventLocal[LOCAL_INDEX_THIRD].code=SCANCODE_LEFT_MOUSE;
rawEventLocal[LOCAL_INDEX_THIRD].keyCode=0;
rawEventLocal[LOCAL_INDEX_THIRD].type=1;
rawEventLocal[LOCAL_INDEX_THIRD].value=KEYEVENT_ACTION_UP;
rawEventLocal[3].deviceId=SENSOR_MOUSE_ID;
}else{
if(rawEventLocal->value==KEYEVENT_ACTION_DOWN){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_DOWN;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_SECOND].flags=0;
rawEventLocal[LOCAL_INDEX_SECOND].code=0;
rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0;
rawEventLocal[LOCAL_INDEX_SECOND].type=0;
rawEventLocal[LOCAL_INDEX_SECOND].value=0;
mTrueMouse=true;
}
else if(rawEventLocal->value==KEYEVENT_ACTION_UP){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_UP;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_SECOND].flags=0;
rawEventLocal[LOCAL_INDEX_SECOND].code=0;
rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0;
rawEventLocal[LOCAL_INDEX_SECOND].type=0;
rawEventLocal[LOCAL_INDEX_SECOND].value=0;
mTrueMouse=false;
}
}
}
其实就是对
rawEventLocal[LOCAL_INDEX_SECOND].code== SCANCODE_CENTER和rawEventLocal->code== SCANCODE_CENTER两种情况作处理。
(这里rawEventLocal有三组值,通过getevent我们可以看到,每按一个按键,是会有三个数据显示的,类似:
所以判断的时候,要针对DOWN事件的第二组值作处理。
)
那么问题来了。现在鼠标模式下在InputReader.cpp中将所有OK键进行了拦截转换成鼠标左键,以达到按OK键当鼠标左键的作用,那么Android系统中怎么样在视频播放这样一个场景下,不对OK键进行拦截呢?
结论:
这个问题还是当初的设计问题,如果决定在系统层将所有OK键转换成鼠标左键,那么自然上层所有的OK键都是起鼠标左键的效果。这个时候你又要求某一个第三方应用还是保留原来的OK键的效果,很明显是矛盾的。
如果要解决这个问题,只能是在视频全屏播放的时候,不开启空鼠模式!!java层获取到是否是视频播放状态,然后通过jni调用接口来操作C++层,这个方式可行,但是动作太大了。而且在系统层对单一场景特别处理显然不好。
EventHub.h中
(1)定义NEED_CHANGE_MODE:
#define NEED_CHANGE_MODE
修改RawEvent的结构,增加 keyCode、flags两个成员
struct RawEvent { nsecs_t when; int32_t deviceId; int32_t type; int32_t code; int32_t value; int32_t keyCode; uint32_t flags; };
EventHub.cpp中
(2)在EventHub::openDeviceLocked()中不自动获取deviceID,而是通过指定(可能可以优化):
// Allocate device. (The device object takes ownership of the fd at this point.) int32_t deviceId = mNextDeviceId++;
改成:
// Allocate device. (The device object takes ownership of the fd at this point.) int32_t deviceId; #ifdef NEED_CHANGE_MODE if(strstr(identifier.name,"Hillcrest")){//identifier.name=="Hillcrest Labs Virtual Pointer"||identifier.name=="Hillcrest MotionEngine Cursor Mover: #0"){//Compatible with two kinds of Dongle deviceId = SENSOR_MOUSE_ID; }else if(identifier.name=="XXX"){ deviceId = IR_RC_ID; }else{ deviceId = mNextDeviceId++; } #else deviceId = mNextDeviceId++; #endif
(3)在InputReader.h中
定义一些会用到的变量:
#ifdef NEED_CHANGE_MODE #define SCANCODE_LEFT_MOUSE 272 #define SCANCODE_CENTER 28 #define SCANCODE_DPAD_LEFT 105 #define SCANCODE_DPAD_RIGHT 106 #define SCANCODE_DPAD_UP 103 #define SCANCODE_DPAD_DOWN 108 #define SCANCODE_MOUSE_WAKE 704 #define AKEYCODE_MOUSE_WAKE 4021 enum { LOCAL_INDEX_FIRST , LOCAL_INDEX_SECOND , LOCAL_INDEX_THIRD , }; enum{ KEYEVENT_ACTION_UP, KEYEVENT_ACTION_DOWN, KEYEVENT_ACTION_REPEAT, }; bool mMousetoFocus; bool mOktoMouseSure; bool mFlags; bool mTrueMouse; nsecs_t mWaitTime; bool mPowerOn; uint32_t isCursor; void removeFocusEventLocked(RawEvent* rawEvents, size_t count); #endif
(4)在InputReader.cpp中做具体修改:
定义全局bool变量,用于判断是否要显示鼠标
static bool bEnablePointer = false;
在InputReader的构造函数中定义一些局部变量
#ifdef NEED_CHANGE_MODE mMousetoFocus=false; mOktoMouseSure=true; isCursor=0; mFlags=false; mWaitTime=0; mTrueMouse=false; mPowerOn=false; #endif
添加一个移除焦点的函数:
#ifdef NEED_CHANGE_MODE void InputReader::removeFocusEventLocked(RawEvent* rawEvents, size_t count){ RawEvent* rawEvent = rawEvents; int32_t deviceId = IR_RC_ID; rawEvent->deviceId=deviceId; rawEvent->flags=0; rawEvent->keyCode=AKEYCODE_MOUSE_WAKE; rawEvent->code=SCANCODE_MOUSE_WAKE; rawEvent->type=1; rawEvent->value=1; //down event rawEvent[LOCAL_INDEX_SECOND].deviceId=deviceId; rawEvent[LOCAL_INDEX_SECOND].flags=0; rawEvent[LOCAL_INDEX_SECOND].keyCode=AKEYCODE_MOUSE_WAKE; rawEvent[LOCAL_INDEX_SECOND].code=SCANCODE_MOUSE_WAKE; rawEvent[LOCAL_INDEX_SECOND].type=1; rawEvent[LOCAL_INDEX_SECOND].value=0; //up event processEventsForDeviceLocked(deviceId, rawEvent, count); } #endif
处理在void InputReader::processEventsLocked()函数中:
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) { for (const RawEvent* rawEvent = rawEvents; count;) { int32_t type = rawEvent->type; size_t batchSize = 1; if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) { int32_t deviceId = rawEvent->deviceId; while (batchSize < count) { if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT || rawEvent[batchSize].deviceId != deviceId) { break; } batchSize += 1; } #if DEBUG_RAW_EVENTS ALOGD("BatchSize: %d Count: %d", batchSize, count); #endif #ifdef NEED_CHANGE_MODE uint32_t classes = mEventHub->getDeviceClasses(deviceId); if(SENSOR_MOUSE_ID != deviceId && (classes & INPUT_DEVICE_CLASS_CURSOR)){ #if DEBUG_RAW_EVENTS ALOGD("type:%d scancode:%d keycode:%d vlaue:%d flags:%d", rawEvent->type,rawEvent->code,rawEvent->keyCode,rawEvent->value,rawEvent->flags); #endif }else{ if(!mPowerOn && rawEvent->type== EV_REL){//wake mouse for the first time mOktoMouseSure = false;//Allows you to convert the OK key to mouse left key mMousetoFocus = true;//unfade the cursor mPowerOn = true;// the first use of the mouse after system launch } RawEvent* rawEventLocal = const_cast<RawEvent*>(rawEvent); nsecs_t now; now = systemTime(SYSTEM_TIME_MONOTONIC); if(mWaitTime==0){ mWaitTime=now; }else{ if((now-mWaitTime)*0.000000001>15){ if(rawEventLocal->code == SCANCODE_CENTER/*||rawEvent[1].scanCode==28*/){ processEventsForDeviceLocked(deviceId, rawEventLocal, batchSize); mWaitTime=now; mMousetoFocus=false;//fade the cursor break; }else{ if(rawEventLocal->type==EV_REL){//wake up the mouse after sleep mOktoMouseSure = false;//Allows you to convert the OK key to mouse left key mMousetoFocus = true;//unfade the cursor }else if(rawEventLocal->code == SCANCODE_LEFT_MOUSE /*The left Key of Mouse of the Remote Controller*/ ||rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_LEFT_MOUSE /*The left Key of Any Mouse*/){ mMousetoFocus=false;//fade the cursor }else{ mOktoMouseSure=true;//Don't intercept the OK key mFlags = true;//Mark the mouse after dormancy } } } mWaitTime=now; } if(mFlags && rawEventLocal->type==EV_REL){//The mouse be awakened first after dormancy mOktoMouseSure = false;//Allows you to convert the OK key to mouse left key mFlags = false; mMousetoFocus = true;//unfade the cursor //Change the current event into the eliminational focus event. removeFocusEventLocked(rawEventLocal, batchSize); break; } if(!mTrueMouse){ if(rawEventLocal->code == SCANCODE_LEFT_MOUSE ||rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_LEFT_MOUSE){ if(!mMousetoFocus){ mMousetoFocus=true;//unfade the cursor mOktoMouseSure=false;//Allows you to convert the OK key to mouse left key ALOGD("get mouse left click!: deviceid %d scancode: %d", deviceId, rawEvent->code); //Change the current event into the eliminational focus event. removeFocusEventLocked(rawEventLocal, batchSize); break; } } else if(rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_UP || rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_DOWN || rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_LEFT || rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_RIGHT || rawEventLocal->code == SCANCODE_DPAD_UP || rawEventLocal->code == SCANCODE_DPAD_DOWN || rawEventLocal->code == SCANCODE_DPAD_LEFT || rawEventLocal->code == SCANCODE_DPAD_RIGHT /*The direction key of Remote Controller in IR mode.*/ ||(rawEventLocal->value>458830&&rawEventLocal->value<458835) /*The direction key of Keyboard.*/){ mMousetoFocus=false;//fade the cursor mOktoMouseSure = true;//Don't intercept the OK key } if(!mMousetoFocus/* Drop The Cursor offset event of Mouse */){ for(size_t s=0;s<batchSize;s++){ if(rawEventLocal[s].type == EV_REL){ isCursor = 1; break; } } if(isCursor){ for(size_t j=0 ; j<batchSize; j++){ rawEventLocal[j].deviceId = 0; rawEventLocal[j].type = -1; rawEventLocal[j].code = -1; rawEventLocal[j].value = -1; rawEventLocal[j].keyCode = -1; rawEventLocal[j].flags = -1; rawEventLocal[j].when = -1; } isCursor = 0; } } } if(!mOktoMouseSure && !bEnablePointer){//The OK key is converted to the mouse left key if(rawEventLocal[LOCAL_INDEX_SECOND].code== SCANCODE_CENTER){ deviceId=SENSOR_MOUSE_ID; if(rawEventLocal[LOCAL_INDEX_SECOND].value==KEYEVENT_ACTION_DOWN){ rawEventLocal->deviceId=SENSOR_MOUSE_ID; rawEventLocal->flags=0; rawEventLocal->value=KEYEVENT_ACTION_DOWN; rawEventLocal->keyCode=0; rawEventLocal->code=SCANCODE_LEFT_MOUSE; rawEventLocal->type=1; rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID; rawEventLocal[LOCAL_INDEX_SECOND].flags=0; rawEventLocal[LOCAL_INDEX_SECOND].code=0; rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0; rawEventLocal[LOCAL_INDEX_SECOND].type=0; rawEventLocal[LOCAL_INDEX_SECOND].value=0; rawEventLocal[LOCAL_INDEX_THIRD].deviceId=SENSOR_MOUSE_ID; rawEventLocal[LOCAL_INDEX_THIRD].flags=0; rawEventLocal[LOCAL_INDEX_THIRD].code=0; rawEventLocal[LOCAL_INDEX_THIRD].keyCode=0; rawEventLocal[LOCAL_INDEX_THIRD].type=0; rawEventLocal[LOCAL_INDEX_THIRD].value=0; mTrueMouse=true; } else if(rawEventLocal[LOCAL_INDEX_SECOND].value==KEYEVENT_ACTION_UP){ rawEventLocal->deviceId=SENSOR_MOUSE_ID; rawEventLocal->flags=0; rawEventLocal->value=KEYEVENT_ACTION_UP; rawEventLocal->keyCode=0; rawEventLocal->code=SCANCODE_LEFT_MOUSE; rawEventLocal->type=1; rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID; rawEventLocal[LOCAL_INDEX_SECOND].flags=0; rawEventLocal[LOCAL_INDEX_SECOND].code=0; rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0; rawEventLocal[LOCAL_INDEX_SECOND].type=0; rawEventLocal[LOCAL_INDEX_SECOND].value=0; rawEventLocal[LOCAL_INDEX_THIRD].deviceId=SENSOR_MOUSE_ID; rawEventLocal[LOCAL_INDEX_THIRD].flags=0; rawEventLocal[LOCAL_INDEX_THIRD].code=0; rawEventLocal[LOCAL_INDEX_THIRD].keyCode=0; rawEventLocal[LOCAL_INDEX_THIRD].type=0; rawEventLocal[LOCAL_INDEX_THIRD].value=0; mTrueMouse=false; } } else if(rawEventLocal->code== SCANCODE_CENTER/*The enter key / "OK" key event in IR mode*/){ deviceId=SENSOR_MOUSE_ID; if(rawEventLocal->value==KEYEVENT_ACTION_REPEAT){ mTrueMouse=true; break; } if(batchSize==4){ rawEventLocal->deviceId=SENSOR_MOUSE_ID; rawEventLocal->flags=0; rawEventLocal->value=KEYEVENT_ACTION_DOWN; rawEventLocal->keyCode=0; rawEventLocal->code=SCANCODE_LEFT_MOUSE; rawEventLocal->type=1; rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID; rawEventLocal[LOCAL_INDEX_THIRD].deviceId=SENSOR_MOUSE_ID; rawEventLocal[LOCAL_INDEX_THIRD].flags=0; rawEventLocal[LOCAL_INDEX_THIRD].code=SCANCODE_LEFT_MOUSE; rawEventLocal[LOCAL_INDEX_THIRD].keyCode=0; rawEventLocal[LOCAL_INDEX_THIRD].type=1; rawEventLocal[LOCAL_INDEX_THIRD].value=KEYEVENT_ACTION_UP; rawEventLocal[3].deviceId=SENSOR_MOUSE_ID; }else{ if(rawEventLocal->value==KEYEVENT_ACTION_DOWN){ rawEventLocal->deviceId=SENSOR_MOUSE_ID; rawEventLocal->flags=0; rawEventLocal->value=KEYEVENT_ACTION_DOWN; rawEventLocal->keyCode=0; rawEventLocal->code=SCANCODE_LEFT_MOUSE; rawEventLocal->type=1; rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID; rawEventLocal[LOCAL_INDEX_SECOND].flags=0; rawEventLocal[LOCAL_INDEX_SECOND].code=0; rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0; rawEventLocal[LOCAL_INDEX_SECOND].type=0; rawEventLocal[LOCAL_INDEX_SECOND].value=0; mTrueMouse=true; } else if(rawEventLocal->value==KEYEVENT_ACTION_UP){ rawEventLocal->deviceId=SENSOR_MOUSE_ID; rawEventLocal->flags=0; rawEventLocal->value=KEYEVENT_ACTION_UP; rawEventLocal->keyCode=0; rawEventLocal->code=SCANCODE_LEFT_MOUSE; rawEventLocal->type=1; rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID; rawEventLocal[LOCAL_INDEX_SECOND].flags=0; rawEventLocal[LOCAL_INDEX_SECOND].code=0; rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0; rawEventLocal[LOCAL_INDEX_SECOND].type=0; rawEventLocal[LOCAL_INDEX_SECOND].value=0; mTrueMouse=false; } } } } } #endif processEventsForDeviceLocked(deviceId, rawEvent, batchSize); } else { switch (rawEvent->type) { case EventHubInterface::DEVICE_ADDED: addDeviceLocked(rawEvent->when, rawEvent->deviceId); break; case EventHubInterface::DEVICE_REMOVED: removeDeviceLocked(rawEvent->when, rawEvent->deviceId); break; case EventHubInterface::FINISHED_DEVICE_SCAN: handleConfigurationChangedLocked(rawEvent->when); break; default: ALOG_ASSERT(false); // can't happen break; } } count -= batchSize; rawEvent += batchSize; } }
这里做的工作就是:
1.
if(SENSOR_MOUSE_ID != deviceId && (classes & INPUT_DEVICE_CLASS_CURSOR))
先通过判断是否是鼠标设备。
如果是的话才做处理。
2.
if(!mPowerOn && rawEvent->type== EV_REL){//wake mouse for the first time
mOktoMouseSure = false;//Allows you to convert the OK key to mouse left key
mMousetoFocus = true;//unfade the cursor
mPowerOn = true;// the first use of the mouse after system launch
}
如果不处于开机状态,那么这时候收到一个rawEvent->type == EV_REL事件的时候
就要mPowerOn = true;以便后续根据这个变量点亮屏幕,达到按任意一个按键唤醒电视机的作用。
同时,第一次唤醒的时候,保持焦点模式。
3.
if(mWaitTime==0){
mWaitTime=now;
}else{
if((now-mWaitTime)*0.000000001>15){
if(rawEventLocal->code == SCANCODE_CENTER/*||rawEvent[1].scanCode==28*/){
processEventsForDeviceLocked(deviceId, rawEventLocal, batchSize);
mWaitTime=now;
mMousetoFocus=false;//fade the cursor
break;
}else{
if(rawEventLocal->type==EV_REL){//wake up the mouse after sleep
mOktoMouseSure = false;//Allows you to convert the OK key to mouse left key
mMousetoFocus = true;//unfade the cursor
}else if(rawEventLocal->code == SCANCODE_LEFT_MOUSE
/*The left Key of Mouse of the Remote Controller*/
||rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_LEFT_MOUSE
/*The left Key of Any Mouse*/){
mMousetoFocus=false;//fade the cursor
}else{
mOktoMouseSure=true;//Don't intercept the OK key
mFlags = true;//Mark the mouse after dormancy
}
}
}
mWaitTime=now;
}
这段代码的意思是:
每次收到按键都更新mWaitTime为当前时间。如果这一次的按键离上一次操作的时间超过了15min,也就是进入休眠了。
这个时候,如果按enter键,隐藏鼠标。而如果收到鼠标事件,则mOktoMouseSure = false;这样允许将OK键转换成左键。
mMousetoFocus = true;唤醒鼠标。否则,mOktoMouseSure=true;不对OK键作转换。
这里的mFlags用于标记鼠标处于休眠状态
4.
if(mFlags && rawEventLocal->type==EV_REL){//The mouse be awakened first after dormancy
mOktoMouseSure = false;//Allows you to convert the OK key to mouse left key
mFlags = false;
mMousetoFocus = true;//unfade the cursor
//Change the current event into the eliminational focus event.
removeFocusEventLocked(rawEventLocal, batchSize);
break;
}
这里就是针对鼠标的休眠状态做处理了,利用了前面的mFlags标记
5.
mTrueMouse,是用于标记是否对按键进行拦截的,我们只对down事件进行拦截和转换就可以了。
if(rawEventLocal->code == SCANCODE_LEFT_MOUSE
||rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_LEFT_MOUSE){
if(!mMousetoFocus){
mMousetoFocus=true;//unfade the cursor
mOktoMouseSure=false;//Allows you to convert the OK key to mouse left key
ALOGD("get mouse left click!: deviceid %d scancode: %d", deviceId, rawEvent->code);
//Change the current event into the eliminational focus event.
removeFocusEventLocked(rawEventLocal, batchSize);
break;
}
}
这里是对鼠标左键的处理。
6.
else if(rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_UP
|| rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_DOWN
|| rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_LEFT
|| rawEventLocal[LOCAL_INDEX_SECOND].code == SCANCODE_DPAD_RIGHT
|| rawEventLocal->code == SCANCODE_DPAD_UP
|| rawEventLocal->code == SCANCODE_DPAD_DOWN
|| rawEventLocal->code == SCANCODE_DPAD_LEFT
|| rawEventLocal->code == SCANCODE_DPAD_RIGHT
/*The direction key of Remote Controller in IR mode.*/
||(rawEventLocal->value>458830&&rawEventLocal->value<458835)
/*The direction key of Keyboard.*/){
mMousetoFocus=false;//fade the cursor
mOktoMouseSure = true;//Don't intercept the OK key
}
这里就是实现对按任意方向键消隐鼠标的地方。
7.
if(!mMousetoFocus/* Drop The Cursor offset event of Mouse */){
for(size_t s=0;s<batchSize;s++){
if(rawEventLocal[s].type == EV_REL){
isCursor = 1;
break;
}
}
if(isCursor){
for(size_t j=0 ; j<batchSize; j++){
rawEventLocal[j].deviceId = 0;
rawEventLocal[j].type = -1;
rawEventLocal[j].code = -1;
rawEventLocal[j].value = -1;
rawEventLocal[j].keyCode = -1;
rawEventLocal[j].flags = -1;
rawEventLocal[j].when = -1;
}
isCursor = 0;
}
}
这就是,如果鼠标处于消隐状态,那么丢掉所有鼠标位移的事件
8
最后就是重点了
对OK键的处理:
if(!mOktoMouseSure && !bEnablePointer){//The OK key is converted to the mouse left key
前面的很多逻辑都是标记mOktoMouseSure【OK键是否要转换成鼠标左键】,(bEnablePointer应该可以去掉)
这里就是实现OK键转换的逻辑了
if(rawEventLocal[LOCAL_INDEX_SECOND].code== SCANCODE_CENTER){
deviceId=SENSOR_MOUSE_ID;
if(rawEventLocal[LOCAL_INDEX_SECOND].value==KEYEVENT_ACTION_DOWN){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_DOWN;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_SECOND].flags=0;
rawEventLocal[LOCAL_INDEX_SECOND].code=0;
rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0;
rawEventLocal[LOCAL_INDEX_SECOND].type=0;
rawEventLocal[LOCAL_INDEX_SECOND].value=0;
rawEventLocal[LOCAL_INDEX_THIRD].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_THIRD].flags=0;
rawEventLocal[LOCAL_INDEX_THIRD].code=0;
rawEventLocal[LOCAL_INDEX_THIRD].keyCode=0;
rawEventLocal[LOCAL_INDEX_THIRD].type=0;
rawEventLocal[LOCAL_INDEX_THIRD].value=0;
mTrueMouse=true;
}
else if(rawEventLocal[LOCAL_INDEX_SECOND].value==KEYEVENT_ACTION_UP){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_UP;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_SECOND].flags=0;
rawEventLocal[LOCAL_INDEX_SECOND].code=0;
rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0;
rawEventLocal[LOCAL_INDEX_SECOND].type=0;
rawEventLocal[LOCAL_INDEX_SECOND].value=0;
rawEventLocal[LOCAL_INDEX_THIRD].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_THIRD].flags=0;
rawEventLocal[LOCAL_INDEX_THIRD].code=0;
rawEventLocal[LOCAL_INDEX_THIRD].keyCode=0;
rawEventLocal[LOCAL_INDEX_THIRD].type=0;
rawEventLocal[LOCAL_INDEX_THIRD].value=0;
mTrueMouse=false;
}
}
else if(rawEventLocal->code== SCANCODE_CENTER/*The enter key / "OK" key event in IR mode*/){
deviceId=SENSOR_MOUSE_ID;
if(rawEventLocal->value==KEYEVENT_ACTION_REPEAT){
mTrueMouse=true;
break;
}
if(batchSize==4){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_DOWN;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_THIRD].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_THIRD].flags=0;
rawEventLocal[LOCAL_INDEX_THIRD].code=SCANCODE_LEFT_MOUSE;
rawEventLocal[LOCAL_INDEX_THIRD].keyCode=0;
rawEventLocal[LOCAL_INDEX_THIRD].type=1;
rawEventLocal[LOCAL_INDEX_THIRD].value=KEYEVENT_ACTION_UP;
rawEventLocal[3].deviceId=SENSOR_MOUSE_ID;
}else{
if(rawEventLocal->value==KEYEVENT_ACTION_DOWN){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_DOWN;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_SECOND].flags=0;
rawEventLocal[LOCAL_INDEX_SECOND].code=0;
rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0;
rawEventLocal[LOCAL_INDEX_SECOND].type=0;
rawEventLocal[LOCAL_INDEX_SECOND].value=0;
mTrueMouse=true;
}
else if(rawEventLocal->value==KEYEVENT_ACTION_UP){
rawEventLocal->deviceId=SENSOR_MOUSE_ID;
rawEventLocal->flags=0;
rawEventLocal->value=KEYEVENT_ACTION_UP;
rawEventLocal->keyCode=0;
rawEventLocal->code=SCANCODE_LEFT_MOUSE;
rawEventLocal->type=1;
rawEventLocal[LOCAL_INDEX_SECOND].deviceId=SENSOR_MOUSE_ID;
rawEventLocal[LOCAL_INDEX_SECOND].flags=0;
rawEventLocal[LOCAL_INDEX_SECOND].code=0;
rawEventLocal[LOCAL_INDEX_SECOND].keyCode=0;
rawEventLocal[LOCAL_INDEX_SECOND].type=0;
rawEventLocal[LOCAL_INDEX_SECOND].value=0;
mTrueMouse=false;
}
}
}
其实就是对
rawEventLocal[LOCAL_INDEX_SECOND].code== SCANCODE_CENTER和rawEventLocal->code== SCANCODE_CENTER两种情况作处理。
(这里rawEventLocal有三组值,通过getevent我们可以看到,每按一个按键,是会有三个数据显示的,类似:
# getevent /dev/input/event0: EV_MSC MSC_SCAN 0000f00b /dev/input/event0: EV_KEY KEY_ENTER DOWN /dev/input/event0: EV_SYN SYN_REPORT 00000000 /dev/input/event0: EV_KEY KEY_ENTER UP /dev/input/event0: EV_SYN SYN_REPORT 00000000
所以判断的时候,要针对DOWN事件的第二组值作处理。
)
那么问题来了。现在鼠标模式下在InputReader.cpp中将所有OK键进行了拦截转换成鼠标左键,以达到按OK键当鼠标左键的作用,那么Android系统中怎么样在视频播放这样一个场景下,不对OK键进行拦截呢?
结论:
这个问题还是当初的设计问题,如果决定在系统层将所有OK键转换成鼠标左键,那么自然上层所有的OK键都是起鼠标左键的效果。这个时候你又要求某一个第三方应用还是保留原来的OK键的效果,很明显是矛盾的。
如果要解决这个问题,只能是在视频全屏播放的时候,不开启空鼠模式!!java层获取到是否是视频播放状态,然后通过jni调用接口来操作C++层,这个方式可行,但是动作太大了。而且在系统层对单一场景特别处理显然不好。
相关文章推荐
- 解决三星等设备video标签播放hls视频时候只有声音没有视频。。。
- iOS - 视频播放处理全屏/横屏时候遇见的坑
- 视频播放时候如何在静音模式下有声音
- 当webView关闭的时候,音乐或者视频还在播放,没有停止
- iOS播放视频时候,忽略设备静音按钮
- android 使用mediaplayer播放视频的时候设置请求头header
- bugfix:录音的时候,webview不能播放视频
- C#如何播放视频,全屏且播放视频时候锁定鼠标和键盘
- 【转】 iOS播放视频时候,忽略设备静音按钮
- Rxjava +Retrofit+ok+GreenDao视频播放
- 【Android】Android实现视频播放的时候滑动屏幕调节亮度和音量
- iOS - 模拟器播放视频的时候出现异常崩溃
- 七牛云 播放的时候显示错误信息:视频解析异常 请重试
- 【bug整理】Android声音并发问题:播放视频的时候,用第三方应用播放音乐,存在音视频声音并发问题
- ios开发 只让播放视频的 时候能够全屏横屏 其他全部非全屏非横屏
- mediaPlayer的一些坑爹问题 以及解决surfview播放视频时候有黑屏闪现的问题
- [导入]CZoneSoft 视频互动 : 新增音乐盒 方便个人K歌的时候播放伴奏音乐
- (ios)MPMoviePlayerController首次播放视频的时候,没有控制条
- vlc for android 2016 8月版本 在播放vlc视频时候进入以及退出卡顿1分钟的问题
- VideoView播放视频的时候出现播放前透明问题