本帖最后由 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 鼠标隐藏的方法
- void PointerController::fade(Transition transition) {
- AutoMutex _l(mLock);
-
- // Remove the inactivity timeout, since we are fading now.
- removeInactivityTimeoutLocked();
-
- // Start fading.
- if (transition == TRANSITION_IMMEDIATE) {
- mLocked.pointerFadeDirection = 0;
- mLocked.pointerAlpha = 0.0f;
- updatePointerLocked();
- } else {
- mLocked.pointerFadeDirection = -1;
- startAnimationLocked();
- }
- }
复制代码
本次补丁是framework/base/services/core/java/com/android/server/policy/PhoneWindowManaer.java- + Runnable HPHRunable = new Runnable(){
- + public void run(){
- + mEscPressd = true;
- + Log.e(TAG,"linjc:HPHRunable");
- + mstate=SystemProperties.get("sys.KeyMouse.mKeyMouseState");
- + if(mstate.equals("on"))
- + {
- + SystemProperties.set("sys.KeyMouse.mKeyMouseState","off");
- + Toast.makeText(mContext, "Restore the default button mode", Toast.LENGTH_LONG).show();
- + // Toast.makeText(getActivity(), "Restore the default button mode", Toast.LENGTH_LONG).show();
- + }
- + else
- + {
- + SystemProperties.set("sys.KeyMouse.mKeyMouseState","on");
- + Toast.makeText(mContext, "Into Mouse mode,click this key again out of this mode", Toast.LENGTH_LONG).show();
- + // Toast.makeText(getActivity(), "Into Mouse mode,click this key again out of this mode", Toast.LENGTH_LONG).show();
- + }
- + }
- + };
- +
复制代码
他主要是设置sys.KeyMouse.mKeyMouseState这个全局属性。
sys.KeyMouse.mKeyMouseState在interceptKeyBeforeDispatching函数里
- @Override
- public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
- final boolean keyguardOn = keyguardOn();
- final int keyCode = event.getKeyCode();
- final int repeatCount = event.getRepeatCount();
- final int metaState = event.getMetaState();
- final int flags = event.getFlags();
- final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
- final boolean canceled = event.isCanceled();
-
- if (DEBUG_INPUT) {
- Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
- + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
- + " canceled=" + canceled);
- }
-
- mstate = SystemProperties.get("sys.KeyMouse.mKeyMouseState");
- if (mstate.equals("on") && ((keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_LEFT)
- || (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_RIGHT)
- || (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_UP)
- || (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_DOWN)
- || (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_MODE_SWITCH))) {
- keydown = down;
- mKeyMouseHandler.sendEmptyMessage(keyCode);
- //return -1;
- }
-
- if (mstate.equals("on") && ((keyCode == KeyEvent.KEYCODE_ENTER)
- ||(keyCode == KeyEvent.KEYCODE_DPAD_CENTER))) {
- return -1;
- }
-
- ...
-
复制代码 当sys.KeyMouse.mKeyMouseState为on的时候,截取一些keycode交给mKeyMouseHandler处理
- public Handler mKeyMouseHandler = new Handler() {
- public void handleMessage(Message msg) {
- switch(msg.what){
- case KeyEvent.KEYCODE_TV_KEYMOUSE_LEFT:
- mdeltax = -1.0f;
- mdeltay = 0;
- break;
- case KeyEvent.KEYCODE_TV_KEYMOUSE_RIGHT:
- mdeltax = 1.0f;
- mdeltay = 0;
- break;
- case KeyEvent.KEYCODE_TV_KEYMOUSE_UP:
- mdeltax = 0;
- mdeltay = -1.0f;
- break;
- case KeyEvent.KEYCODE_TV_KEYMOUSE_DOWN:
- mdeltax = 0;
- mdeltay = 1.0f;
- break;
- case KeyEvent.KEYCODE_TV_KEYMOUSE_MODE_SWITCH:
- mdeltax = 0;
- mdeltay = 0;
- break;
- default:
- break;
- }
-
- try {
- mWindowManager.dispatchMouse(mdeltax,mdeltay,screenWidth,screenHeight);
- } catch (Exception e){
- e.printStackTrace();
- }
-
- if (keydown) {
- mKeyMouseHandler.sendEmptyMessageDelayed(msg.what,30);
- }
- }
- };
复制代码 mWindowManager.dispatchMouse(mdeltax,mdeltay,screenWidth,screenHeight);
发现鼠标事件由这个方法处理。
mWindowManager是WindowManagerService
跟进dispatchMouse这个方法
framework/base/services/core/java/com/android/server/wm/WindowManagerService.java
- public class WindowManagerService extends IWindowManager.Stub
- implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
- ...
- }
-
- ...
-
- public void dispatchMouse(float x, float y, int w, int h) {
- mInputManager.dispatchMouse(x,y,w,h);
- }
复制代码 mInputManager是InputManagerService类的实例
framework/base/services/core/java/com/android/server/input/InputManagerService.java
- public void dispatchMouse(float x, float y, int w, int h){
- nativedispatchMouse(x, y, w, h, mPtr);
- }
复制代码- 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
- static const JNINativeMethod gInputManagerMethods[] = {
- /* name, signature, funcPtr */
- ...
复制代码 nativedispatchMouse的原型是android_server_InputManager_nativedispatchMouse
- static void android_server_InputManager_nativedispatchMouse(JNIEnv* env,
- jclass clazz,jfloat x,jfloat y,jint w,jint h,jlong ptr) {
- NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
-
- int mID;
- float mx, my;
- float screenWidth,screenHeight;
- char *mgetID=new char[PROPERTY_VALUE_MAX];
- char *mkeyMouseState=new char[PROPERTY_VALUE_MAX];
- screenWidth=(float)w;
- screenHeight=(float)h;
-
- property_get("sys.ID.mID",mgetID,0);
- mID=atoi(mgetID);
-
- mPointerController=im->obtainPointerController(mID);
-
- //start to dispatchMouse
- mPointerController->setPresentation(
- PointerControllerInterface::PRESENTATION_POINTER);
- mPointerController->move(x,y);
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
- mPointerController->getPosition(&mx, &my);
-
- //if((mx<=0)||((mx>=(screenWidth-10.0f))||(my<=0)||(my>=(screenHeight-10.0f)))
- // x=0;y=0;
-
- if (mx == 0) {
- strcpy(mkeyMouseState, "left");
- } else if (mx>=(screenWidth-5.0f)) {
- strcpy(mkeyMouseState, "right");
- } else if (my == 0) {
- strcpy(mkeyMouseState, "up");
- } else if (my >= (screenHeight-5.0f)) {
- strcpy(mkeyMouseState, "down");
- } else {
- strcpy(mkeyMouseState, "Non-boundary");
- }
-
- property_set("sys.keymouselimitstate",mkeyMouseState);
- }
复制代码 终于在这里发现了PointerController的实例了
隐藏鼠标只要模仿dispatchMouse写一个方法就可以了
- static void android_server_InputManager_nativefadeMouse(JNIEnv* env,
- jclass clazz,jlong ptr){
- NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- int mID;
- char *mgetID=new char[PROPERTY_VALUE_MAX];
- property_get("sys.ID.mID",mgetID,0);
- mID=atoi(mgetID);
- mPointerController=im->obtainPointerController(mID);
- //start to dispatchMouse
- mPointerController->setPresentation(
- PointerControllerInterface::PRESENTATION_POINTER);
- mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE);
- }
复制代码gInputManagerMethods[] 数组加上我们新加的方法
- { "nativefadeMouse", "(J)V",
- (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)。
|