51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1546|回复: 0
打印 上一主题 下一主题

CTS 设备管理之设备分类

[复制链接]
  • TA的每日心情
    奋斗
    2021-8-6 16:14
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]测试小兵

    跳转到指定楼层
    1#
    发表于 2018-4-11 15:47:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    设备分类

    cts中将设备分为3种状态:处于验证中的设备,可用设备,执行任务的设备。这三种状态的设备分别用3个集合保存:

    //处于验证中的设备集合
    private Map<String, IDeviceStateMonitor> mCheckDeviceMap;
    //可用设备的集合
    private ConditionPriorityBlockingQueue<IDevice> mAvailableDeviceQueue;
    //执行任务的设备集合
    private Map<String, IManagedTestDevice> mAllocatedDeviceMap;
    1.处于验证中的设备集合

    mCheckDeviceMap是一个Map,key值表示设备的SN号,value值表示当前设备的状态监听器对象IDeviceS
    tateMonitor(以后会讲到)。当一个新设备被检测的时候会首先放到该Map中,然后会调用IDeviceStateMon
    itor.waitForDeviceShell(final long waitTime)来对设备进行一个扫描,扫描通过以后,就会将设备添加到可
    用设备集合mAvailableDeviceQueue中。但是不管扫描成不成功,经过检测步骤后,都会从mCheckDevic
    eMap设备集合中删除该设备。所以可以说该容器这是临时存放设备用的,为的是对设备进行验证是否可
    用,就像机场里过安检一样。

    2.可用的设备集合

    mAvailableDeviceQueue是一个优先队列,且是线程安全的,这是cts自定义的一个队列数据结构。你可
    以传入条件选择设备,比如按设备号选择,按平台号选择都可以。返回的是一个IDevice对象,这是原生
    的ADB中定义的接口类。该集合是一个中间集合,它从mCheckDeviceMap中得到集合,然后等到用户
    使用设备后,就将集合中的某个元素"送给"了执行任务的设备集合mAllocatedDeviceMap。

    3.执行任务的设备集合

    mAllocatedDeviceMap集合是一个Map,key值表示设备的SN号,value值表示的是cts自己定义的设备
    对象的接口IManagedTestDevice。当用户选择一个可用设备后,是从可用设备集合mAvailableDeviceQ
    ueue中得到了一个IDevice,然后cts使用外观模式,将其封装到了继承自IManagedTestDevice接口的对
    象TestDevice(这个类很重要,以后会单独讲)中,里面有很多关于设备的方法可以被调用,那么用户
    实际能操作就是这个TestDevice类。等待任务完成后,该设备将“送还”到可用设备集合中,这只是一
    个借用的过程,用完了就还给了它,这样的话这个设备还可以继续执行其他任务。

    4.总结

    通过上面的介绍,我们用一幅图来描述一下3个集合之间的关系。



    检测设备后分类

    终于到了揭晓庐山真面目的时候,以上的种种解释,包括第一篇文章的铺垫,都是为了下面的内容铺
    垫的,讲代码的东西就是这么的麻烦。先上代码:

    1. private class ManagedDeviceListener implements IDeviceChangeListener {

    2.         /**
    3.          * {@inheritDoc}
    4.          */
    5.         @Override
    6.         public void deviceChanged(IDevice device, int changeMask) {
    7.             IManagedTestDevice testDevice = mAllocatedDeviceMap.get(device.getSerialNumber());
    8.             if ((changeMask & IDevice.CHANGE_STATE) != 0) {
    9.                 if (testDevice != null) {
    10.                     TestDeviceState newState = TestDeviceState.getStateByDdms(device.getState());
    11.                     testDevice.setDeviceState(newState);
    12.                 } else if (mCheckDeviceMap.containsKey(device.getSerialNumber())) {
    13.                     IDeviceStateMonitor monitor = mCheckDeviceMap.get(device.getSerialNumber());
    14.                     monitor.setState(TestDeviceState.getStateByDdms(device.getState()));
    15.                 } else if (!mAvailableDeviceQueue.contains(device) && device.getState() ==IDevice.Devic
    16. eState.ONLINE) {
    17.                     checkAndAddAvailableDevice(device);
    18.                 }
    19.             }
    20.         }

    21.         /**
    22.          * {@inheritDoc}
    23.          */
    24.         @Override
    25.         public void deviceConnected(IDevice device) {
    26.             CLog.d("Detected device connect %s, id %d", device.getSerialNumber(), device.hashCode());
    27.             IManagedTestDevice testDevice = mAllocatedDeviceMap.get(device.getSerialNumber());
    28.             if (testDevice == null) {
    29.                 if (isValidDeviceSerial(device.getSerialNumber()) && device.getState() == IDevice.DeviceState.
    30. ONLINE) {
    31.                     checkAndAddAvailableDevice(device);
    32.                 } else if (mCheckDeviceMap.containsKey(device.getSerialNumber())) {
    33.                     IDeviceStateMonitor monitor = mCheckDeviceMap.get(device.getSerialNumber());
    34.                     monitor.setState(TestDeviceState.getStateByDdms(device.getState()));
    35.                 }
    36.             } else {
    37.                 // this device is known already. However DDMS will allocate a
    38.                 // new IDevice, so need
    39.                 // to update the TestDevice record with the new device
    40.                 CLog.d("Updating IDevice for device %s", device.getSerialNumber());
    41.                 testDevice.setIDevice(device);
    42.                 TestDeviceState newState = TestDeviceState.getStateByDdms(device.getState());
    43.                 testDevice.setDeviceState(newState);
    44.             }
    45.         }

    46.         private boolean isValidDeviceSerial(String serial) {
    47.             return serial.length() > 1 && !serial.contains("?");
    48.         }

    49.         /**
    50.          * {@inheritDoc}
    51.          */
    52.         @Override
    53.         public void deviceDisconnected(IDevice disconnectedDevice) {
    54.             if (mAvailableDeviceQueue.remove(disconnectedDevice)) {
    55.                 CLog.i("Removed disconnected device %s from available queue",disconnectedDevice.getSerialNumber());
    56.             }
    57.             IManagedTestDevice testDevice = mAllocatedDeviceMap.get(disconnectedDevice.getSerialNumber());
    58.             if (testDevice != null) {
    59.                 testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
    60.             } else if (mCheckDeviceMap.containsKey(disconnectedDevice.getSerialNumber())) {
    61.                 IDeviceStateMonitor monitor = mCheckDeviceMap.get(disconnectedDevice.getSerialNumber());
    62.                 monitor.setState(TestDeviceState.NOT_AVAILABLE);
    63.             }
    64.             updateDeviceMonitor();
    65.         }
    66.     }
    复制代码

    上面的代码我在第一篇文章中有涉及,只是那个时候我把三个监听方法里的具体实现给隐藏了,现在终于把
    它展现出来了。

    deviceChanged方法

    该方法会在设备连接的时候调用,但是我们做了个判断,就是设备状态的改变,那就说明该设备连接前AD
    B已经知道了该设备的存在,只是它与之前的状态发生了变化,所以在设备第一次连接的时候,该方法里的
    代码块是不会被调用的。那么再具体说说操作步骤:

    1.首先判断设备的改变是否是状态的改变,因为设备的变化很有多种,我们需要关心的设备于PC连接状态
    的改变,所以需要做判断。

    2.然后从mAllocatedDeviceMap集合中尝试获得发生改变的设备,这一步是为了检查是否会影响到执行任务
    的设备。因为在任务执行过程中,不是每时每刻都能去检测状态,所以cts采用的是被动判断,如果状态发
    生改变,需要通知正在执行任务的设备监听器,由监听器去做相应的处理。

    3.如果确定状态发生改变的设备是正在执行任务的设备,就需要将其状态设置为新状态。

    4.如果不是正在执行任务的设备,那么再去验证是否属于另外2个集合中的设备。

    5.如果是检测集合mCheckDeviceMap中的元素,那么也要重新设置设备状态,不过这个时候是从检测设备
    集合中得到设备再改变它的状态。

    6.如果改变的设备既不是执行任务的设备,也不是检测中的设备,这个时候我们要判断是否是新设备,这
    个时候可能有人会有疑问?为什么不判断是否存在于可分配设备中呢?这得从deviceChanged的调用机制来
    说,deviceChanged只在设备连接进来的时候会调用,设备掉线的时候该方法不会被调用,那么自然这个
    里面无需判断是否是可分配设备中。只需要判断传进来的IDevice的状态是否在线且不在可分配设备列表中
    ,这个时候就要按新设备来处理啦。另外判断是否在该集合中是需要在deviceDisconnected中判断的。

    deviceConnected方法

    这个方法会在有设备连接的时候调用,不管是新设备还是旧设备。它的处理步骤如下:

    1.首先判断该设备是否正在执行任务,如果正在执行任务,ok!我们需要更新该设备的状态。如果不是
    进入第二步:
    2.如果在线且通过判断其SN号是可用的,如果条件不通过,跳到第三步,如果通过的话,这个时候需要
    进行操作判断是否可以放到可用设备集合中。
    3.是否存在于检测设备集合中,如果存在就将其设备更新下。

    deviceDisconnected方法

    这个方法会在设备离线的时候调用,
    1.首先试着从可用集合中删除该设备,然后进入第二步。
    2.剩下的处理方式和上面的deviceConnected一样。

    总结

    设备管理的复杂性较之我所讲的,我所能说的也只是皮毛,希望对此有兴趣研究研究源码。提示一下,
    在研究源码之前先了解一下23种设计模式中常用模式,对你的理解会很有帮助。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-9-20 22:28 , Processed in 0.064085 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表