概述
Accessibility Service被广泛用于各类自动点击的app,但早期,它并没有提供丰富的API,受到控件的高度约束,能达成的效果与Instrumentation相去甚远。 Android 7.0中,AccessibilityService新加入了dispatchGesture API,开发者可以使用它在屏幕上进行高度定制化的操作,例如点击屏幕上的任意坐标。
网络上已经有大量对performAccessibilityAction相关API的源码分析,但很多人对dispatchGesture知之甚少。因此我对它的调用路径稍作分析,以便于开发和对抗。
对每个部分的源代码,我会附上AOSP的源码链接和关键代码的截图。
源码分析
入口函数:AccessibilityService::dispatchGesture
(AccessibilityService.java)
调用逻辑:

connection在此处初始化:

dispatchGesture方法通过Binder调用sendGesture方法。
该connection对象定义在IAccessibilityServiceConnection.aidl(IAccessibilityServiceConnection.aidl)当中。
实现了该stub的类是AbstractAccessibilityServiceConnection(AbstractAccessibilityServiceConnection)
不了解Stub与aidl的朋友,可以先去找一些Binder与Android IPC的文章补习一下相关知识。
AbstractAccessibilityServiceConnection是一个抽象类,它的实现在AccessibilityServiceConnection(AccessibilityServiceConnection)当中。
其中sendGesture方法的实现调用了motionEventInject对象的InjectEvents方法

mSystemSupport获得的

mSystemSupport的初始化在AbstractAccessibilityServiceConnection类的构造函数当中:通过一个传入的对象初始化。

在AccessibilityManagerService中可以看到,

SystemSupport对象实际上就是this,也就是AccessibilityManagerService本身。
回过头去查看它的getMotionEventInjectorLocked方法:
它返回了一个成员。按照setMotionEventInjector的注释,这个成员在AccessibilityInputFilter当中初始化。

查看AccessibilityInputFilter(AccessibilityInputFilter.java),它的初始化确实就是那么简单,没有什么额外的花样。

再回到MotionEventInjector::injectEvents,其实现如下:
MotionEventInjector.java

它调用了一个handler,这个handler的在构造函数中被初始化,Handler.callback就是这个类本身。

handleMessage函数就在这个类里:

sendMotionEventToNext会将事件传递给下一个handler,不过我们可以先关注injectEventsMainThread。

mHandler处理单个的事件。于是又回到了handleMessage函数,这次需要着重分析的就是sendMotionEventToNext了。

super.onMotionEvent应当是核心。
此方法的实现在EventStreamTransformation(EventStreamTransformation.java)当中。

MotionEventInjector,而是AccessibilityInputFilter初始化时设置的handler。


查看AccessibilityInputFilter的onMotionEvent方法,可以看到:

InputFilterInputFilter中的sendInputEvent方法。


IInputFilterHost发起一个Binder调用。
实现了这个IInputFilterHost.stub的是InputManagerService(InputManagerService.java)。
从这里往后,注入事件的流程就跟Instrumentation相同了。感兴趣的朋友可以去阅读分析Instrumentation事件注入源码的文章。