CTS问题分析16 | weiinter105

最近好像和输入法比较有缘啊,又是一个定制的输入法造成的CTS问题;话说,一般第三方app造成CTS问题的情况一般是危险权限之类的,输入法顶多是window遮挡了uiautomator待识别的控件;今天这个问题还真是以前没见过的,因此记录下这个问题

问题初探

测试命令: run cts -m CtsWidgetTestCases -t android.widget.cts.TextViewTest#testUndo_directAppend

测试case如下:

 

fail log:

 

这条case的大意是:首先模拟key down在TextView里传递abc字符串,然后对相应的TextView调用append("def") api;然后执行undo操作;预期结果是将def回退,结果变成了将整个字符串都回退了,mTextView中的Editor变成了空串,因此case fail;

问题分析

首先从undo操作开始看起

 

可以看到就是执行Editor的undo操作

 

就是调用UndoManager的undo操作

 

可以看到UndoManager中维护一个mUndos队列,那么很自然的想到是不是这个队列出了问题,将abc和def合并了? 调一下,发现果然是,当调用undo时,其结果不正确

正常情况下应该为

但是实际上fail时undo队列里只有一个UndoState,其newText为“adcdef";因此可见刚刚的推断是正确的,有一个合并的操作导致的问题

那么为什么会合并呢?或者说正常为什么不会合并呢? 首先看undo的流程

 

看注释,fetches the last undo operation and checks to see if a new edit should be merged into it;这里决定了是否合并

 

当调用到commitState时,会将CanMerge设为false,那么就不会merge了;剩下的就是调试与分析工作了;

发现正常情况下,Editor的mIsUserEdit为false

 

开始edit时为true,结束edit时为false;凭直觉这里也应该成对出现吧;说明肯定哪个地方有了时序上的错乱导致的问题;

调试后发现了,果然出了正常的逻辑的key down,append的逻辑外,fail机器还有一个关键的地方会调用

这个消息的发送处在

 

可以看到是输入法进行了调用,因为是不同进程进行的操作,是有可能造成时序的错乱,当执行到关键位置时,mIsUserEdit = true;导致将两次的操作合并了,因此undo时直接全部回退,case失败;

然后将输入法换成百度的,一测,果然必pass;因此确定是sogou输入法的问题

问题总结

输入法还可能造成Editor的相关fail。虽然表现在Editor上,但未必是其本身的问题;这里只是简单的定位问题,具体该如何修改,需要sogou的同学来看下其内部的实现逻辑了,这个binder call到底是什么情况会调用。

作者: RESSRC

个人资源站

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据