前段时间为了解决客户一个触屏震动太弱的问题,我研究了一下Android原码中触屏震动的相关知识点,现梳理了整个流程。代码是基于MTK平台的,如有雷同纯属巧合,若有不同仅限参考。
1.修改触屏震动,我首先考虑从虚拟按键的点击事件作为切入点分析,即查看SystemUI中关于虚拟按键事件的处理,的确有关于vibrater相关的调用,但只有找到home键的长按vibrater事件,感觉方向还得切到framework中。
2.注意MTK平台Framework的代码有两个地方,vendor/mediatek/properietary/frameworks以及根目录下的frameworks,所以当你调试根目录framework代码无效时则需要查看是否是vendor下的代码。
frameworks/base/services/core/java/com/android/server/vibrator/VibrationSettings.java
frameworks/base/services/core/java/com/android/server/vibrator/VibratorManagerService.java
frameworks/base/core/res/res/values/config.xml
根据VibrationSettings可知震动相关配置是在config.xml。
我迫不及待的修改config_virtualKeyVibePattern的配置,remake调试验证却无任何效果。而且vendor下并无config.xml。
没有办法,只能继续通过framework的代码往下跟。
3.流程梳理:VibratorManagerService/vibrate->fillVibrationFallbacks-startVibrationLocked->startVibrationThreadLocked(VibrationThread extends Thread)
VibrationThread{run->playVibration->StepQueue/consumeNext->Step~StartVibrateStep/play->startVibrating->SingleVibratorStep/play->ComposePrimitivesStep?/play->VibratorController/on...}
->vendor/mediatek/proprietary/hardware/libvibrator/aidl/default/Vibrator.cpp
VibratorController/on...->C++层。这里即jni部分的内容:
(1)这里重写了几个on的方法,都是调用mNativeWrapper(VibratorController的静态内部类)的方法,举例其中一个如:perform->native performEffect。
(2)frameworks/base/services/core/jni/com_android_server_vibrator_VibratorController.cpp
这里实现了java<->C++方法映射。根据此cpp文件的Android.bp可知这个cpp会被编入libservices.core的so库。但是没有找到System.loadLibrary(libservices.core),只是frameworks/base/services/Android.bp中有关联,后面在研究......
(3)后面是hal层的调用逻辑,最终定位到vendor/mediatek/proprietary/hardware/libvibrator/aidl/default/Vibrator.cpp。果不其然,Vibrator.cpp中定义了WAVEFORM_CLICK_EFFECT=30,所以实际震动使用的是其私有定义的值,这也解释了为啥修改framework下config.xml配置无效的原因。WAVEFORM_CLICK_EFFECT=50解决了问题。