Android7.1下显示/隐藏鼠标
本帖最后由 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;
char *mkeyMouseState=new char;
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_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)。
页:
[1]