Firefly开源社区

Android7.1下显示/隐藏鼠标

105

积分

0

威望

0

贡献

技术小白

积分
105
发表于 2017-8-9 16:14:57     
本帖最后由 lxp 于 2017-8-9 16:16 编辑

功能:长按遥控的search键后,切换为飞鼠模式。

问题:

1.切换飞鼠模式鼠标没有显示出来(要按其他上下左右按钮才开始显示)

2.切换回按键模式后,鼠标是自动等待一段时间消失,而不是立即消失


从下面这个博客得到启示

http://blog.csdn.net/myarrow/article/details/12708185

画鼠标流程


鼠标由PointerController.cpp控制。

文件在framework/base/libs/input/PointerController.cpp

鼠标隐藏的方法
  1. void PointerController::fade(Transition transition) {
  2.     AutoMutex _l(mLock);

  3.     // Remove the inactivity timeout, since we are fading now.
  4.     removeInactivityTimeoutLocked();

  5.     // Start fading.
  6.     if (transition == TRANSITION_IMMEDIATE) {
  7.         mLocked.pointerFadeDirection = 0;
  8.         mLocked.pointerAlpha = 0.0f;
  9.         updatePointerLocked();
  10.     } else {
  11.         mLocked.pointerFadeDirection = -1;
  12.         startAnimationLocked();
  13.     }
  14. }
复制代码




本次补丁是framework/base/services/core/java/com/android/server/policy/PhoneWindowManaer.java
  1. +    Runnable HPHRunable = new Runnable(){
  2. +            public void run(){
  3. +                mEscPressd = true;
  4. +               Log.e(TAG,"linjc:HPHRunable");
  5. +               mstate=SystemProperties.get("sys.KeyMouse.mKeyMouseState");
  6. +               if(mstate.equals("on"))
  7. +               {
  8. +                       SystemProperties.set("sys.KeyMouse.mKeyMouseState","off");
  9. +                              Toast.makeText(mContext, "Restore the default button mode", Toast.LENGTH_LONG).show();
  10. +               //             Toast.makeText(getActivity(), "Restore the default button mode", Toast.LENGTH_LONG).show();
  11. +                      }
  12. +                      else
  13. +                      {
  14. +                              SystemProperties.set("sys.KeyMouse.mKeyMouseState","on");
  15. +                              Toast.makeText(mContext, "Into Mouse mode,click this key again out of this mode", Toast.LENGTH_LONG).show();
  16. +               //             Toast.makeText(getActivity(), "Into Mouse mode,click this key again out of this mode", Toast.LENGTH_LONG).show();
  17. +               }
  18. +            }
  19. +    };
  20. +
复制代码


他主要是设置sys.KeyMouse.mKeyMouseState这个全局属性。
sys.KeyMouse.mKeyMouseState在interceptKeyBeforeDispatching函数里
  1. @Override
  2.     public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
  3.         final boolean keyguardOn = keyguardOn();
  4.         final int keyCode = event.getKeyCode();
  5.         final int repeatCount = event.getRepeatCount();
  6.         final int metaState = event.getMetaState();
  7.         final int flags = event.getFlags();
  8.         final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
  9.         final boolean canceled = event.isCanceled();

  10.         if (DEBUG_INPUT) {
  11.             Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
  12.                     + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
  13.                     + " canceled=" + canceled);
  14.         }

  15.         mstate = SystemProperties.get("sys.KeyMouse.mKeyMouseState");
  16.         if (mstate.equals("on") && ((keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_LEFT)
  17.                 || (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_RIGHT)
  18.                 || (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_UP)
  19.                 || (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_DOWN)
  20.                 || (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_MODE_SWITCH))) {
  21.             keydown = down;
  22.             mKeyMouseHandler.sendEmptyMessage(keyCode);            
  23.             //return -1;
  24.         }

  25.         if (mstate.equals("on") && ((keyCode == KeyEvent.KEYCODE_ENTER)
  26.                 ||(keyCode == KeyEvent.KEYCODE_DPAD_CENTER))) {
  27.             return -1;
  28.         }
  29.         
  30.         ...
  31.         
复制代码
当sys.KeyMouse.mKeyMouseState为on的时候,截取一些keycode交给mKeyMouseHandler处理
  1. public Handler mKeyMouseHandler = new Handler() {
  2.         public void handleMessage(Message msg) {
  3.             switch(msg.what){
  4.             case KeyEvent.KEYCODE_TV_KEYMOUSE_LEFT:
  5.                 mdeltax = -1.0f;
  6.                 mdeltay = 0;
  7.                 break;
  8.             case KeyEvent.KEYCODE_TV_KEYMOUSE_RIGHT:
  9.                 mdeltax = 1.0f;
  10.                 mdeltay = 0;
  11.                 break;
  12.             case KeyEvent.KEYCODE_TV_KEYMOUSE_UP:
  13.                 mdeltax = 0;
  14.                 mdeltay = -1.0f;
  15.                 break;
  16.             case KeyEvent.KEYCODE_TV_KEYMOUSE_DOWN:
  17.                 mdeltax = 0;
  18.                 mdeltay = 1.0f;
  19.                 break;
  20.             case KeyEvent.KEYCODE_TV_KEYMOUSE_MODE_SWITCH:
  21.                 mdeltax = 0;
  22.                 mdeltay = 0;
  23.                 break;
  24.             default:
  25.                 break;
  26.             }

  27.             try {
  28.                 mWindowManager.dispatchMouse(mdeltax,mdeltay,screenWidth,screenHeight);
  29.             } catch (Exception e){
  30.                 e.printStackTrace();
  31.             }

  32.             if (keydown) {
  33.                 mKeyMouseHandler.sendEmptyMessageDelayed(msg.what,30);
  34.             }
  35.         }
  36.     };
复制代码
mWindowManager.dispatchMouse(mdeltax,mdeltay,screenWidth,screenHeight);
发现鼠标事件由这个方法处理。
mWindowManager是WindowManagerService
跟进dispatchMouse这个方法


framework/base/services/core/java/com/android/server/wm/WindowManagerService.java
  1.    public class WindowManagerService extends IWindowManager.Stub
  2.         implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
  3.     ...
  4.         }
  5.   
  6.     ...
  7.   
  8.    public void dispatchMouse(float x, float y, int w, int h) {
  9.             mInputManager.dispatchMouse(x,y,w,h);
  10.     }
复制代码
mInputManager是InputManagerService类的实例

framework/base/services/core/java/com/android/server/input/InputManagerService.java
  1.    public void dispatchMouse(float x, float y, int w, int h){
  2.         nativedispatchMouse(x, y, w, h, mPtr);
  3.     }   
复制代码
  1. private static native void nativedispatchMouse(float x, float y, int w, int h, long ptr);
复制代码
nativedispatchMouse是一个jni方法

查找framework/base/services/core/jni下
发现一个com_android_server_input_InputManagerService.cpp
framework/base/services/core/jni/com_android_server_input_InputManagerService.cpp
  1. static const JNINativeMethod gInputManagerMethods[] = {
  2.     /* name, signature, funcPtr */

  3. ...
复制代码
nativedispatchMouse的原型是android_server_InputManager_nativedispatchMouse

  1. static void android_server_InputManager_nativedispatchMouse(JNIEnv* env,
  2.                 jclass clazz,jfloat x,jfloat y,jint w,jint h,jlong ptr) {
  3.     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);

  4.     int mID;
  5.     float mx, my;
  6.     float screenWidth,screenHeight;
  7.     char *mgetID=new char[PROPERTY_VALUE_MAX];
  8.     char *mkeyMouseState=new char[PROPERTY_VALUE_MAX];
  9.     screenWidth=(float)w;
  10.     screenHeight=(float)h;

  11.     property_get("sys.ID.mID",mgetID,0);
  12.     mID=atoi(mgetID);

  13.     mPointerController=im->obtainPointerController(mID);

  14.     //start to dispatchMouse
  15.     mPointerController->setPresentation(
  16.                     PointerControllerInterface::PRESENTATION_POINTER);
  17.     mPointerController->move(x,y);
  18.     mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
  19.     mPointerController->getPosition(&mx, &my);

  20.     //if((mx<=0)||((mx>=(screenWidth-10.0f))||(my<=0)||(my>=(screenHeight-10.0f)))
  21.     //        x=0;y=0;

  22.     if (mx == 0) {
  23.             strcpy(mkeyMouseState, "left");
  24.     } else if (mx>=(screenWidth-5.0f)) {
  25.             strcpy(mkeyMouseState, "right");
  26.     } else if (my == 0) {
  27.             strcpy(mkeyMouseState, "up");
  28.     } else if (my >= (screenHeight-5.0f)) {
  29.             strcpy(mkeyMouseState, "down");
  30.     } else {
  31.             strcpy(mkeyMouseState, "Non-boundary");
  32.     }

  33.     property_set("sys.keymouselimitstate",mkeyMouseState);
  34. }
复制代码
终于在这里发现了PointerController的实例了
隐藏鼠标只要模仿dispatchMouse写一个方法就可以了


  1. static void android_server_InputManager_nativefadeMouse(JNIEnv* env,
  2. jclass clazz,jlong ptr){
  3. NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
  4.    int mID;
  5.    char *mgetID=new char[PROPERTY_VALUE_MAX];

  6.    property_get("sys.ID.mID",mgetID,0);
  7.    mID=atoi(mgetID);

  8.    mPointerController=im->obtainPointerController(mID);

  9.    //start to dispatchMouse
  10.     mPointerController->setPresentation(
  11.                     PointerControllerInterface::PRESENTATION_POINTER);   
  12.     mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE);
  13. }
复制代码

gInputManagerMethods[] 数组加上我们新加的方法


  1. { "nativefadeMouse", "(J)V",
  2.                 (void*) android_server_InputManager_nativefadeMouse},
复制代码
第二个参数括号里面代表的是函数参数类型,括号外的表示返回类型,一定要对应。具体值百度。

这里要注意的是WindowManagerService是继承了IWindowManager.Stub
要找到IWindowManager.aidl加上对应的方法。
最后,找到文件在
framework/base/core/java/android/view/IWindowManager.aidl
其他中间调用就不写了。

-----------------------------------
鼠标显示的方法
比较简单,看到上面的mKeyMouseHandler。
当sys.KeyMouse.mKeyMouseState设为on的同时,将keydown设为true(为了让鼠标一直显示,直到模式切换回去或者有人按键),mKeyMouseHandler.sendEmptyMessage(KeyEvent.KEYCODE_TV_KEYMOUSE_MODE_SWITCH)。








回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表