视频播放的时候不拦截OK键
1.首先分析為了將OK鍵轉換成鼠標左鍵的工作:
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_MODEif(strstr(identifier.name,"Hillcrest")){//identifier.name=="Hillcrest Labs Virtual Pointer"||identifier.name=="Hillcrest MotionEngine Cursor Mover: #0"){//Compatible with two kinds of DongledeviceId = 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 4021enum {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_MODEmMousetoFocus=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 eventprocessEventsForDeviceLocked(deviceId, rawEvent, count); } #endif
處理在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我們可以看到,每按一個按鍵,是會有三個數據顯示的,類似:
# 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++層,這個方式可行,但是動作太大了。而且在系統層對單一場景特別處理顯然不好。
總結
以上是生活随笔為你收集整理的视频播放的时候不拦截OK键的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python蒙特卡洛仿真_蒙特卡洛模拟I
- 下一篇: Java:Eclipse下载安装教程,以