其实很简单,上层对数据的要求是上报的相邻的两个点必须是back+app_switch或者app_switch+back,而我们的手指在按住两个按键的同时本来inputreader在上报的时候无法保证能符合上层的要求,也就是说会出现back+back的情况所以要处理一下
bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
// Check for release of a virtual key.
if (mCurrentVirtualKey.down) {
if (mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) {
// Pointer went up while virtual key was down.
mCurrentVirtualKey.down = false;
if (!mCurrentVirtualKey.ignored) {
/*add for screen pin unlock matthew_xuan++++*/ 这里负责手指抬起的时候按照顺序解除
if(screen_unpin&&((mCurrentVirtualKey.keyCode == 4)||(mCurrentVirtualKey.keyCode == 187)))
{
ALOGD("matt-8");
screen_unpin = false;
int current_keycode = 0;
int current_scancode = 0;
current_keycode = mCurrentVirtualKey.keyCode;
current_scancode = mCurrentVirtualKey.scanCode;
if(current_keycode == 4) 如果之前是4先按下那么肯定要先解除187
{
mCurrentVirtualKey.keyCode = 187;
mCurrentVirtualKey.scanCode = 580; //如果发现不好用得看看这些值对不对
dispatchVirtualKey(when, policyFlags,
AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
else
{
mCurrentVirtualKey.keyCode = 4;
mCurrentVirtualKey.scanCode = 158;
dispatchVirtualKey(when, policyFlags,
AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
mCurrentVirtualKey.keyCode = current_keycode;
mCurrentVirtualKey.scanCode = current_scancode;
}
/*add for screen pin unlock matthew_xuan----*/
dispatchVirtualKey(when, policyFlags,
AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
return true;
}
if (mCurrentRawState.rawPointerData.touchingIdBits.count() == 1) { //单点上报走这里
uint32_t id = mCurrentRawState.rawPointerData.touchingIdBits.firstMarkedBit();
const RawPointerData::Pointer& pointer =
mCurrentRawState.rawPointerData.pointerForId(id);
const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
// Pointer is still within the space of the virtual key.
return true;
}
}
// Pointer left virtual key area or another pointer also went down.
// Send key cancellation but do not consume the touch yet.
// This is useful when the user swipes through from the virtual key area
// into the main display surface.
/*mCurrentVirtualKey.down = false;
if (!mCurrentVirtualKey.ignored) {
#if DEBUG_VIRTUAL_KEYS
ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
#endif
dispatchVirtualKey(when, policyFlags,
AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
| AKEY_EVENT_FLAG_CANCELED);
}*/
}
/*add for screen pin unlock matthew_xuan++++*/ 这里确保上报的两个相邻点肯定是其中符合上层要求的格式
ALOGD("matt-touchingIdBits.count=%d",mCurrentRawState.rawPointerData.touchingIdBits.count());
if (!screen_unpin&&mCurrentRawState.rawPointerData.touchingIdBits.count()==2 //同时按下两个点才会是count()==2,有的驱动上报就不够,比如goodix的
&&((mCurrentVirtualKey.keyCode == 4)||(mCurrentVirtualKey.keyCode == 187)))
{
ALOGD("matt-1");
// Pointer just went down.Check for virtual key press or off-screen touches.
//uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
int count_id = 0;
int ii = 0,jj=0;
const VirtualKey* virtualKey_combine[2] = {NULL,NULL};
ii = mCurrentRawState.rawPointerData.touchingIdBits.firstMarkedBit();
ALOGD("matt-2+%d",ii);
// ALOGD("hjptestfor:ii=%d,jj=%d",ii,jj++);
for(;ii<32;ii++)
{
ALOGD("matt-3-");
if(mCurrentRawState.rawPointerData.touchingIdBits.hasBit(ii))
{
ALOGD("matt-3");
const RawPointerData::Pointer& pointer = mCurrentRawState.rawPointerData.pointerForId(ii);
if (!isPointInsideSurface(pointer.x, pointer.y)) //make sure the point is in the field of two key 由于focal的touch的virtual key是上报触点到framework里来转换成key的,所以这里要判断这些触摸是否在virtual key的规定范围内
{
ALOGD("matt-4");
virtualKey_combine[count_id] = findVirtualKeyHit(pointer.x, pointer.y);
if ((virtualKey_combine[count_id] == NULL)||(++count_id>=2)) break; //count id max=2
}
else
{
ALOGD("matt-5");
break;
}
}
}
if(virtualKey_combine[0]&&virtualKey_combine[1]&&
(
((virtualKey_combine[0]->keyCode==187)&&(virtualKey_combine[1]->keyCode==4))
|| ((virtualKey_combine[0]->keyCode==4)&&(virtualKey_combine[1]->keyCode==187))
)
)
{
ALOGD("matt-6+");
for(ii=0;ii<count_id;ii++)
{
mCurrentVirtualKey.down = true;
mCurrentVirtualKey.downTime = when;
mCurrentVirtualKey.keyCode = virtualKey_combine[ii]->keyCode;
mCurrentVirtualKey.scanCode = virtualKey_combine[ii]->scanCode;
mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
when, getDevice(), virtualKey_combine[ii]->keyCode, virtualKey_combine[ii]->scanCode);
// ALOGD("hjptestfor:1back&appswitch down:jj=%d",jj++);
if (!mCurrentVirtualKey.ignored)
{
ALOGD("matt-7");
ALOGD("hjptestfor:2back&appswitch down:jj=%d",jj++);
dispatchVirtualKey(when, policyFlags,
AKEY_EVENT_ACTION_DOWN,
AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
else
break;
}
if(ii >= 2) screen_unpin = true;
else screen_unpin = false;
return true;
}
}
/*add for screen pin unlock matthew_xuan----*/
if (mLastRawState.rawPointerData.touchingIdBits.isEmpty()
&& !mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) {
// Pointer just went down. Check for virtual key press or off-screen touches.
uint32_t id = mCurrentRawState.rawPointerData.touchingIdBits.firstMarkedBit();
const RawPointerData::Pointer& pointer = mCurrentRawState.rawPointerData.pointerForId(id);
if (!isPointInsideSurface(pointer.x, pointer.y)) {
// If exactly one pointer went down, check for virtual key hit.
// Otherwise we will drop the entire stroke.
if (mCurrentRawState.rawPointerData.touchingIdBits.count() == 1) {
const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
if (virtualKey) {
mCurrentVirtualKey.down = true;
mCurrentVirtualKey.downTime = when;
mCurrentVirtualKey.keyCode = virtualKey->keyCode;
mCurrentVirtualKey.scanCode = virtualKey->scanCode;
mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
if (!mCurrentVirtualKey.ignored) {
dispatchVirtualKey(when, policyFlags,
AKEY_EVENT_ACTION_DOWN,
AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
}
}
return true;
}
}
if (mConfig.virtualKeyQuietTime > 0 &&
!mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) {
mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
}
return false;
}