androidN 打印cts测试fail问题分析

第一部分  打印cts测试fail问题

 

[CTS][7.0r3][GMS][共有]进行CTS测试,CtsPrintTestCases—

android.print.cts.PrintJobTest#testStateTransitions—fai

gitclone gitadmin@gitsrv01.spreadtrum.com:android/platform/cts-b android-cts-7.0_r3

 

PrintActivity调用到 PrintJobTest中 call()过程。

 

1.   先从cts来看,基类 BasePrintTest,子类PrintJobTest

 

基类方法

setUp():初始化信息,创建 启动PrintDocumentActivity。

clickPrintButton():

获取PrintActivity的 id/print_button按键,模拟点击。

waitForServiceOnPrintJobQueuedCallbackCalled(testCaseNum+ 1);等待60秒CallCounter 的call()被调用(调用条件重要),否则,超时失败。

 

子类方法

baseTest():基础测试,初始化设置callBack及print(adapter)、clickPrintButton();

         

testStateTransitions():用建立的数组,双层循环打印状态,来调用baseTest()

 

2.   PrintActivity类处理

 

当cts中模拟时,会调用clickPrintButton(),就会启动PrintActivity,并响应处理点击事件。

private ImageView mPrintButton;

mPrintButton = (ImageView)findViewById(R.id.print_button);

 

处理逻辑就是: confirmPrint() 或者cancelPrint()

正常情况下会确认打印调用。

 

confirmPrint方法主要更新ui状态及是否请求创建pdf文件或者finish调用。

 

第三行会打印对应log信息, 最后的判断很重要。

 

  如果当前printer正确,会启动创建DocumentActivity. 否则,doFinish结束。

 

 

启动Intent.ACTION_CREATE_DOCUMENT对应的activity.

 

当PrintActivity调用以上时,会调用自己的onPause().会根据当前的状态去做对应处理,包括以下几种状态:

STATE_INITIALIZING

STATE_PRINT_COMPLETED

STATE_CREATE_FILE_FAILED

 会依据状态调用:

PrintSpoolerService---setPrintJobState(PrintJobId printJobId, int state, String error)

当开始打印完成时,会设置打印任务状态,PrintJobInfo.STATE_QUEUED

 

3.      PrintSpoolerService类处理

 

在setPrintJobState方法在,主要做以下几件事:

 

设置状态信息 printJob

     log打印 MetricsLogger.histogram(this,"print_job_state", state);

     是否删除打印任务文件 removePrintJobFileLocked(printJob.getId());

     是否发送所以打印任务给服务

     是否发送队列发送打印任务。

 

 

 

 

 

sendOnPrintJobQueued 发送打印任务

 

  主要通过handler消息机制发送消息: MSG_ON_PRINT_JOB_QUEUED

 

 

 HandlerCallerCallback的 executeMessage 执行接受消息。

 客户端 AIDL方式: IPrintSpoolerClient 调用 onPrintJobQueued()

4.      RemotePrintService远程客户端调用 onPrintJobQueued

 

onPrintJobQueued() 通过MyHandler.MSG_ON_PRINT_JOB_QUEUED消息发送;


接受后进行处理(当然也有许多其他情况,比如:取消、所有打印job等)

 

handleOnPrintJobQueued():

  

如果还没有绑定,用一个线程循环处理;否则,IPrintService 远程调用 :

mPrintService.onPrintJobQueued(printJob);

实际调用的是 PrintService的onBind()中绑定到IBinder的回调。

 

5.      PrintService的处理

 

通过远程回调到该onPrintJobQueued方法发消息MSG_ON_PRINTJOB_QUEUED

 继续调用PrintService的抽象方法:

  protected abstract voidonPrintJobQueued(PrintJob printJob);

 

由于PrintService是一个抽象类,因此,必须有对应的实现类;

具体需要查找确认?

  本问题是由cts测试,因此,是与cts相关的实现类。

public abstract class StubbablePrintServiceextends PrintService

 

6.      StubbablePrintService的处理逻辑

这个类继承PrintService,并实现一些方法。

  此处是通过PrintServiceCallbacks  callbacks来回调的。查找确认,是由其他类继承该抽象类 StubbablePrintService,并复写该方法。

 

7.      MockPrintServiceextends StubbablePrintService 处理逻辑

 

  此类主要方法,一个静态setCallbacks设置CallBacks,另一个实现:

    @Override

    protected PrintServiceCallbacksgetCallbacks() {

        synchronized (sLock) {

            if (sCallbacks != null) {

                sCallbacks.setService(this);

            }

            return sCallbacks;

        }

}

 

8.      查找 MockPrintService的设置回调逻辑

 

FirstPrintService 与 SecondPrintService 两个服务。

这个要回归到 PrinteJobTest类中。

 

9.      PrintJobTest类中callBack的初始化

 

这个初始化还是在 baseTest()处理的。

 

也就回归到 本文档开始部分的介绍。

可以知道FirstPrintService继承于 MockPrintService。

设置的对应回调对象是: PrintServiceCallbacks serviceCallbacks

 

此对象,是通过调用 PrintJobTest的 createFirstMockPrinterServiceCallbacks方法获得,重点是该方法的实现。

 

 

下面来研究下该方法获取callBack对象的实现:

 

 入参包括:PrintJobTestFn printJobTest ,是一个接口类。

返回值是一个打印 Answer响应回调实现的 PrintServiceCallbacks对象。

 

 

因为,在StubbablePrintService中继承PrintService实现onPrintJobQueued(),

里面是通过callBack 调用callbacks.onPrintJobQueued(printJob);

  因此,当PrintService调用onPrintJobQueued时,实际由对应的callBack去调用具体实现;此callBack就是上面的PrintServiceCallbacks对象。

 

该对象通过基类BasePrintTest中的createMockPrintServiceCallbacks()创建。

 

10.   基类  BasePrintTest的回调创建

 

这里看不出怎么回调onPrintJobQueued。

 

借助cts的log可以知道,是PrintServiceCallbacks_Proxy.onPrintJobQueued调用。

中间过程是 org.mockito.xx包中代码的处理,最后,调用到 PrintJobTest中

createFirstMockPrinterServiceCallbacks()创建时,Answer类中的answer()方法调用。

其中:

  printJobTest.onPrintJobQueued(printJob);  //

  onPrintJobQueuedCalled();     //调用实现CallCounter.call()

 

参考如下log:

 

11.   Cts测试问题分析

[CTS][7.0r3][GMS][共有]进

行CTS测试,CtsPrintTestCases--android.print.cts.PrintJobTest

#testStateTransitions--fai

 

分析: 此测试失败的根本原因在于cts测试时,在模拟找到打印按钮并启动PrintActivity界面后,正常去分发 onClick打印按钮事件,在按钮响应前(时间极短),由于 FusedPrintersProvider 检测到位置变化,会更新打印机,此时打印按钮响应后,会设置 mState状态值为2确认打印,在更新打印机执行后,会逐步调用,极短时间调用了PrintActivity.onPrinterAvailable,使mState状态值初始1,注意:确认打印和更新打印机都会调用 updateDocument(false)。

也就是RemotePrintDocument.java: update调用,更新打印界面的文档加载显示LayoutResultCallback.onLayoutFinished()调用handleOnLayoutFinished(),回调完成 mCommandResultCallback.onDone()去通知更新完成 notifyUpdateCompleted,

然后 (PrintActivity)mUpdateCallbacks.onUpdateCompleted()回调。

  然后,在 PrintActivity中根据mState的值去相应处理,如果是2,则会最终调用到onPause(),将打印任务加入到队列:

spooler.setPrintJobState(mPrintJob.getId(),PrintJobInfo.STATE_QUEUED, null);

 最终会在cts正常回调到call()+1操作,结束60秒等待;如果值是1,仅更新下打印界面UI视图,因此,不会调用到onPause()导致cts测试fail.

 

12.   更新打印机的原因 FusedPrintersProvider

此次失败,是因为位置变化更新了打印机。

如上代码,会根据检测到的location信息与当前的mLocation信息做对比,如果满足条件,会更新打印机。

如下log截图:

 

13.  总结分析

 

cts失败根本原因 是由于在测试是打印按钮点击时,位置发生变化,更新打印机状态(监听到位置变化时会更新打印机),将点击打印后的 2确认打印值 更新为1 初始配置,根据该值如果是2,会正常按照流程执行到 dofinish,调用onPasuse,由于被修改为1,导致状态不对fail。

 

失败cts测试的分析过程:

 cts测试循环一次开始

A001-1311:32:19.247 24683 25510 I PrintJobTest: Test 3 -> 7 -> 3

// 启动打印界面

A001-1311:32:19.354 25570 25570 W PrintActivity: onCreate ...

// 位置信息

A001-1311:32:17.588   768   796 D LocationManagerService: incominglocation: Location[network 39.147421,117.389143 acc=50 et=+15h30m50s912ms

A001-1311:32:21.005   768   796 D LocationManagerService: incominglocation: Location[fused 39.147421,117.389143 acc=14 et=+15h30m54s362ms]

// 位置变化引起回调,onLoadFinished执行堆栈,会发消息调用onPrintersChanged

A001-1311:32:21.044 25570 25570 D  xuehao :  PrinterRegistry: onLoadFinished...start

A001-1311:32:21.044 25570 25570 D  xuehao :java.lang.Exception

A001-1311:32:21.044 25570 25570 D  xuehao :    atcom.android.printspooler.ui.PrinterRegistry$1.onLoadFinished(PrinterRegistry.java:136)

A001-1311:32:21.044 25570 25570 D  xuehao :    atcom.android.printspooler.ui.PrinterRegistry$1.onLoadFinished(PrinterRegistry.java:134)

A001-1311:32:21.044 25570 25570 D  xuehao :    atandroid.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:486)

A001-1311:32:21.044 25570 25570 D  xuehao :    atandroid.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:454)

A001-1311:32:21.044 25570 25570 D  xuehao :    atandroid.content.Loader.deliverResult(Loader.java:144)

A001-1311:32:21.044 25570 25570 D  xuehao :    atcom.android.printspooler.ui.FusedPrintersProvider.computeAndDeliverResult(FusedPrintersProvider.java:248)

A001-1311:32:21.044 25570 25570 D  xuehao :    atcom.android.printspooler.ui.FusedPrintersProvider.updatePrinters(FusedPrintersProvider.java:368)

A001-1311:32:21.044 25570 25570 D  xuehao :    atcom.android.printspooler.ui.FusedPrintersProvider.onLocationChanged(FusedPrintersProvider.java:453)

A001-1311:32:21.044 25570 25570 D  xuehao :    atandroid.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:301)

A001-1311:32:21.044 25570 25570 D  xuehao :    at android.location.LocationManager$ListenerTransport.-wrap0(LocationManager.java)

A001-1311:32:21.044 25570 25570 D  xuehao :    atandroid.location.LocationManager$ListenerTransport$2.handleMessage(LocationManager.java:253)

/ 位置信息

A001-1311:32:21.048   768   796 D LocationManagerService: incominglocation: Location[fused 39.147421,117.389143 acc=14 et=+15h30m54s362ms]

A001-1311:32:21.055   768   796 D LocationManagerService: incominglocation: Location[network 39.147421,117.389143 acc=50 et=+15h30m54s362ms {Bundle[mParcelledData.dataSize=476]}]

// 打印按钮执行

A001-1311:32:21.068 25570 25570 I PrintActivity: MyClickListener  ... onClick: mPrintButton

// 状态2表示确认打印,如果一直是此状态

A001-1311:32:21.074 25570 25570 I PrintActivity: [state]2

A001-1311:32:21.074 25570 25570 D xuehao  :PrintActivity: confirmPrint start..

 

// 由于上面onPrintersChanged调用,调用onPrinterAvailable堆栈,该调用会设置打印状态为 1,导致fail

A001-1311:32:21.132 25570 25570 D  xuehao :  PrintActivity: onPrinterAvailable...

A001-1311:32:21.132 25570 25570 D  xuehao : java.lang.Exception

A001-1311:32:21.132 25570 25570 D  xuehao :    atcom.android.printspooler.ui.PrintActivity.onPrinterAvailable(PrintActivity.java:2041)

A001-1311:32:21.132 25570 25570 D  xuehao :    atcom.android.printspooler.ui.PrintActivity$DestinationAdapter.onPrintersChanged(PrintActivity.java:2555)

A001-1311:32:21.132 25570 25570 D  xuehao :    atcom.android.printspooler.ui.PrinterRegistry$MyHandler.handleMessage(PrinterRegistry.java:180)

// 状态已经有2被位置改变最终修改为1

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值