在init.rc中添加event

init.rc中添加event,在触摸屏加载后把pointercal参数输送给驱动。结果-效果实现细节:

扩展init-proper_serivce系统支持的属性权限,对自定义的特殊系统属性进行权限开放。使用自定义系统属性在init.rc中on property事件中处理pointercal的读写权限。使用自定义系统属性触摸屏校准程序.apk和InputDevice.java中的输入事件的同步。(在触摸屏校准期间inputDevice在输入事件中不能采用算法。校准程序完成有inputDevice重新启用校准算法)模拟器中至今无法进入device.absX/Y!=null的代码,需要了解以下inputDevice被调用的步骤。触摸屏的时间流程:驱动层:

/**Touchscreen absolute values**These parameters are used to help the input layer discard out of*range readings and reduce jitter etc.**o min,max:-indicate the min and max values your touch screen returns*o fuzz:-use ahigher number to reduce jitter**The default values correspond to Mainstone II in QVGA mode**Please read*Documentation/input/input-programming.txt for more details.*/static int abs_x3={350,3900,5};module_param_arrayabs_x,int,NULL,0;MODULE_PARM_DESCabs_x,"Touchscreen absolute Xmin,max,fuzz";static int abs_y3={320,3750,40};module_param_arrayabs_y,int,NULL,0;MODULE_PARM_DESCabs_y,"Touchscreen absolute Ymin,max,fuzz";static int abs_p3={0,150,4};module_param_arrayabs_p,int,NULL,0;MODULE_PARM_DESCabs_p,"Touchscreen absolute Pressure min,max,fuzz";

/*

*对设备进行初始化设置

*/

set_bit(EV_ABS,wm-input_dev-evbit);set_bit(ABS_X,wm-input_dev-absbit);set_bit(ABS_Y,wm-input_dev-absbit);set_bit(ABS_PRESSURE,wm-input_dev-absbit);input_set_abs_params(wm-input_dev,ABS_X,abs_x[0],abs_x[1],abs_x[2],0);input_set_abs_params(wm-input_dev,ABS_Y,abs_y[0],abs_y[1],abs_y[2],0);input_set_abs_params(wm-input_dev,ABS_PRESSURE,abs_p[0],abs_p[1],abs_p[2],0);

/*

*事件发生时,提供原始点

*/

input_report_abs(wm-input_dev,ABS_X,data.x&0xfff);input_report_abs(wm-input_dev,ABS_Y,data.y&0xfff);input_report_abs(wm-input_dev,ABS_PRESSURE,data.p&0xfff);

/*

*提供给驱动外查询input_dev的接口

*struct input_absinfo info;

*ioctl(fd,EVIOCGABS(axis),&info)

*src file:evDev.c

*/

if((_IOC_NR(cmd)&~ABS_MAX)==_IOC_NR(EVIOCGABS(0))){t=_IOC_NR(cmd)&ABS_MAX;abs.value=dev-abs[t];abs.minimum=dev-absmin[t];abs.maximum=dev-absmax[t];abs.fuzz=dev-absfuzz[t];abs.flat=dev-absflat[t];

Android底层驱动EventHub.cpp static const char*device_path="/dev/input";openPlatformInputvoid scan_dirdevice_path;open_devicedevname;

fd=open(deviceName,O_RDWR);

/*

*对外接口,getEvent,

*inotify监控device_path目录,使用poll机制轮询inotify和各个输入设备的可用状态。解析事件或输入信息,放入各个传出参数中。

*/

bool EventHub:getEvent(int32_t*outDeviceId,int32_t*outType,int32_t*outScancode,int32_t*outKeycode,uint32_t*outFlags,int32_t*outValue,nsecs_t*outWhen)

JNI部分:com_android_server_KeyInputQueue.cpp.提供接口

static JNINativeMethod gInputMethods={/*name,signature,funcPtr*/{"readEvent","(Landroid/view/RawInputEvent;)Z",void*android_server_KeyInputQueue_readEvent},{"getDeviceClasses","(I)I",void*android_server_KeyInputQueue_getDeviceClasses},{"getDeviceName","(I)Ljava/lang/String;",void*android_server_KeyInputQueue_getDeviceName},{"getAbsoluteInfo","(IILcom/android/server/InputDevice$AbsoluteInfo;)Z",void*android_server_KeyInputQueue_getAbsoluteInfo},{"getSwitchState","(I)I",void*android_server_KeyInputQueue_getSwitchState},{"getSwitchState","(II)I",void*android_server_KeyInputQueue_getSwitchStateDevice},{"getScancodeState","(I)I",void*android_server_KeyInputQueue_getScancodeState},{"getScancodeState","(II)I",void*android_server_KeyInputQueue_getScancodeStateDevice},{"getKeycodeState","(I)I",void*android_server_KeyInputQueue_getKeycodeState},{"getKeycodeState","(II)I",void*android_server_KeyInputQueue_getKeycodeStateDevice},{"hasKeys","([I[Z)Z",void*android_server_KeyInputQueue_hasKeys},};

java service部分:KeyInputQueue.java.循环查询输入设备信息或目录状态并处理

Thread mThread=new Thread"InputDeviceReader"{public void run{android.os.Process.setThreadPriority android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY;try{RawInputEvent ev=new RawInputEvent;while true{InputDevice di;//block,doesn't release the monitor readEventev);boolean send=false;boolean configChanged=false;.

//检测到新设备后if ev.type==RawInputEvent.EV_DEVICE_ADDED{synchronized mFirst{di=newInputDeviceev.deviceId;mDevices.putev.deviceId,di;configChanged=true;}}//对触摸屏设备

InputDevice.AbsoluteInfo absX;InputDevice.AbsoluteInfo absY;InputDevice.AbsoluteInfo absPressure;InputDevice.AbsoluteInfo absSize;if((classes&RawInputEvent.CLASS_TOUCHSCREEN)!=0){absX=loadAbsoluteInfo(deviceId,RawInputEvent.ABS_X,"X");absY=loadAbsoluteInfo(deviceId,RawInputEvent.ABS_Y,"Y");absPressure=loadAbsoluteInfo(deviceId,RawInputEvent.ABS_PRESSURE,"Pressure");absSize=loadAbsoluteInfo(deviceId,RawInputEvent.ABS_TOOL_WIDTH,"Size");}else{absX=null;absY=null;absPressure=null;absSize=null;}return new InputDevice(deviceId,classes,name,absX,absY,absPressure,absSize);

我们对触摸屏的数据修订是在InputDevice.java中基于absX,absY,absPressure!=null的状态下的,当绝对原始点数据从驱动报上来之后,传递到InputDevice.java经过我们的校准后再dispatch出去到windowManager-activity。这样就是起到了校准效果。需要注意的补助说明EventHub中有使用IOCTL对触摸屏的EVIOCGABS(axis)进行了采样,取出内容struct input_absinfo info;

struct input_absinfo{__s32 value;__s32 minimum;__s32 maximum;__s32 fuzz;__s32 flat;__s32 resolution;};define EVIOCGABSabs _IOR'E',0x40+abs,struct input_absinfo/*get abs value/limits*/

取出的是触摸屏的最大值,最小值等,这些值在com_android_server_KeyInputQueue.cpp中会把这些值传递给InputDevice.cpp中使用,即把报上来的位置通过算法进行计算成绝对坐标值

scaledX=scaledX-device.absX.minValue/device.absX.range*w;

当然如果出现了X,Y轴相反或者坐标反向等问题都可通过改写这条语句来进行实际操作。


你可能感兴趣的:(Android,TouchScree)