原以为显示触摸(Show Touches)的圆点的实现方式和PointerLocationView类似,也是注册到WMS的PointerEventDispatcher里面,然后在input分发的时候,显示在一个view上。但其实不是这样,使用input tap 300 300 这样的注入点击进行测试,可以看到点击的坐标点,但是没有触摸图标。
在前面说一下结论,显示触摸(Show Touches)的圆点是在inputReader里面处理好的,根本没有走InputDispatcher。这样就不会被InputFilter屏蔽。
在InputManagerService里有Observer监听设置的修改,之后进行了触摸点的显示
InputManagerService.java
private void registerShowTouchesSettingObserver() {
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.SHOW_TOUCHES), true,
new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
updateShowTouchesFromSettings();
}
}, UserHandle.USER_ALL);
}
public void updateShowTouchesFromSettings() {
int setting = getShowTouchesSetting(0);
nativeSetShowTouches(mPtr, setting != 0);
}
走到
void PointerController::setSpots(const PointerCoords* spotCoords,
const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
void PointerController::Spot::updateSprite(const SpriteIcon* icon, float x, float y) {
sprite->setLayer(Sprite::BASE_LAYER_SPOT + id);
sprite->setAlpha(alpha);
sprite->setTransformationMatrix(SpriteTransformationMatrix(scale, 0.0f, 0.0f, scale));
sprite->setPosition(x, y);
this->x = x;
this->y = y;
if (icon != lastIcon) {
lastIcon = icon;
if (icon) {
sprite->setIcon(*icon);
sprite->setVisible(true);
} else {
sprite->setVisible(false);
}
}
}
调用到
void SpriteController::SpriteImpl::setVisible(bool visible) {
AutoMutex _l(mController->mLock);
if (mLocked.state.visible != visible) {
mLocked.state.visible = visible;
invalidateLocked(DIRTY_VISIBILITY);
}
}
SpriteController里面进行了画图处理,画了接触点的图像。
void SpriteController::invalidateSpriteLocked(const sp<SpriteImpl>& sprite) {
bool wasEmpty = mLocked.invalidatedSprites.isEmpty();
mLocked.invalidatedSprites.push(sprite);
if (wasEmpty) {
if (mLocked.transactionNestingCount != 0) {
mLocked.deferredSpriteUpdate = true;
} else {
mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES));
}
}
}
void SpriteController::doUpdateSprites() {
SkCanvas surfaceCanvas(surfaceBitmap);
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint);
if (outBuffer.width > update.state.icon.bitmap.width()) {
paint.setColor(0); // transparent fill color
surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0,
outBuffer.width, update.state.icon.bitmap.height(), paint);
}
if (outBuffer.height > update.state.icon.bitmap.height()) {
paint.setColor(0); // transparent fill color
surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(),
outBuffer.width, outBuffer.height, paint);
}
status = surface->unlockAndPost();
if (status) {
ALOGE("Error %d unlocking and posting sprite surface after drawing.", status);
} else {
update.state.surfaceDrawn = true;
update.surfaceChanged = surfaceChanged = true;
}
参考资料:
Android源码阅读技巧--查找开发者选项中显示触摸操作源码
https://www.cnblogs.com/songsongman/p/11504744.html
Android4.x 系统显示鼠标
https://blog.csdn.net/lininglive/article/details/80340883