Cts框架解析(17)-fastboot状态监听器

Fastboot状态监听器


类图


涉及1个监听器接口,2个实现类,1个执行线程。


Cts框架解析(17)-fastboot状态监听器_第1张图片


解释


这些类实际运用的是观察者模式,所有的Listener都会被添加到Set<IFastbootListener>中,然后执行线程FastbootMonitor每隔5秒钟运行一次,来检索目前处于fastboot状态下的设备,然后更新设备状态后,通知所有的listener,逐个调用listener的stateUpdated方法通知到各个listener。


代码


监听器接口IFastbootListener:


public static interface IFastbootListener {
        /**
         * Callback when fastboot state has been updated for all devices.
         */
        public void stateUpdated();
    }

2个实现类,都是DeviceStateMonitor类的私有类。


NotifyFastbootListener:通过Object类的notify通知在该对象上拥有锁的且处于wait状态的对象,你可以往下执行了。


private static class NotifyFastbootListener implements IFastbootListener {
        @Override
        public void stateUpdated() {
            synchronized (this) {
                notify();
            }
        }
    }


StubFastbootListener:不做任何事


private static class StubFastbootListener implements IFastbootListener {
        @Override
        public void stateUpdated() {
            // ignore
        }
    }

线程类FastbootMonitor,DeviceManager的私有类。

在该线程run方法中:

1.首先会通过cmd命令“fastboot devices”的执行结果,解析出处于fastboot的设备的SN号。

2.然后判断可分配的设备中是否含有这些设备,如果有,需要更新这些设备的状态至FASTBOOT。

3.接着要判断已分配设备中是否含有这些设备,如果有,需要更新这些设备的状态值NOT_AVAILABLE。(至于为什么和第2项中更新的不一样,以后会讲)。

4.通知所有监听器,我已更新完当次的fastboot状态。


private class FastbootMonitor extends Thread {

		private boolean mQuit = false;

		FastbootMonitor() {
			super("FastbootMonitor");
		}

		public void terminate() {
			mQuit = true;
			interrupt();
		}

		@Override
		public void run() {
			while (!mQuit) {
				// only poll fastboot devices if there are listeners, as polling
				// it
				// indiscriminately can cause fastboot commands to hang
				if (!mFastbootListeners.isEmpty()) {
					Set<String> serials = getDevicesOnFastboot();
					if (serials != null) {
						for (String serial : serials) {
							IManagedTestDevice testDevice = mAllocatedDeviceMap.get(serial);
							if (testDevice != null && !testDevice.getDeviceState().equals(TestDeviceState.FASTBOOT)) {
								testDevice.setDeviceState(TestDeviceState.FASTBOOT);
							}
						}
						// now update devices that are no longer on fastboot
						synchronized (mAllocatedDeviceMap) {
							for (IManagedTestDevice testDevice : mAllocatedDeviceMap.values()) {
								if (!serials.contains(testDevice.getSerialNumber()) && testDevice.getDeviceState().equals(TestDeviceState.FASTBOOT)) {
									testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
								}
							}
						}
						// create a copy of listeners for notification to
						// prevent deadlocks
						Collection<IFastbootListener> listenersCopy = new ArrayList<IFastbootListener>(mFastbootListeners.size());
						listenersCopy.addAll(mFastbootListeners);
						for (IFastbootListener listener : listenersCopy) {
							listener.stateUpdated();
						}
					}
				}
				getRunUtil().sleep(FASTBOOT_POLL_WAIT_TIME);
			}
		}
	}

	private Set<String> getDevicesOnFastboot() {
		CommandResult fastbootResult = getRunUtil().runTimedCmd(FASTBOOT_CMD_TIMEOUT, "fastboot", "devices");
		if (fastbootResult.getStatus().equals(CommandStatus.SUCCESS)) {
			CLog.v("fastboot devices returned\n %s", fastbootResult.getStdout());
			return parseDevicesOnFastboot(fastbootResult.getStdout());
		} else {
			CLog.w("'fastboot devices' failed. Result: %s, stderr: %s", fastbootResult.getStatus(), fastbootResult.getStderr());
		}
		return null;
	}

	static Set<String> parseDevicesOnFastboot(String fastbootOutput) {
		Set<String> serials = new HashSet<String>();
		Pattern fastbootPattern = Pattern.compile("([\\w\\d]+)\\s+fastboot\\s*");
		Matcher fastbootMatcher = fastbootPattern.matcher(fastbootOutput);
		while (fastbootMatcher.find()) {
			serials.add(fastbootMatcher.group(1));
		}
		return serials;
	}
}

观察者


哪些地方用到了这个状态监听器呢。也就是那些地方注册成为了观察者。很简单,在DeviceManager类中找到addFastbootListener方法:


Cts框架解析(17)-fastboot状态监听器_第2张图片


右键弹出对话框,点击


Cts框架解析(17)-fastboot状态监听器_第3张图片


就会找到有哪些地方用到了这个监听器。


Cts框架解析(17)-fastboot状态监听器_第4张图片


都在DeviceStateMonitor,其实想想也对,上面监听器的2个实现类都是DeviceStateMonitor的私有类,别人也不能用。


 /**
     * {@inheritDoc}
     */
    @Override
    public boolean waitForDeviceBootloader(long time) {
        if (!mFastbootEnabled) {
            return false;
        }
        long startTime = System.currentTimeMillis();
        // ensure fastboot state is updated at least once
        waitForDeviceBootloaderStateUpdate();
        long elapsedTime = System.currentTimeMillis() - startTime;
        IFastbootListener listener = new StubFastbootListener();
        mMgr.addFastbootListener(listener);
        long waitTime = time - elapsedTime;
        if (waitTime < 0) {
            // wait at least 200ms
            waitTime = 200;
        }
        boolean result =  waitForDeviceState(TestDeviceState.FASTBOOT, waitTime);
        mMgr.removeFastbootListener(listener);
        return result;
    }

@Override
    public void waitForDeviceBootloaderStateUpdate() {
        if (!mFastbootEnabled) {
            return;
        }
        IFastbootListener listener = new NotifyFastbootListener();
        synchronized (listener) {
            mMgr.addFastbootListener(listener);
            try {
                listener.wait();
            } catch (InterruptedException e) {
                Log.w(LOG_TAG, "wait for device bootloader state update interrupted");
            }
        }
        mMgr.removeFastbootListener(listener);
    }

 @Override
    public boolean waitForDeviceNotAvailable(long waitTime) {
        IFastbootListener listener = new StubFastbootListener();
        if (mFastbootEnabled) {
            mMgr.addFastbootListener(listener);
        }
        boolean result = waitForDeviceState(TestDeviceState.NOT_AVAILABLE, waitTime);
        if (mFastbootEnabled) {
            mMgr.removeFastbootListener(listener);
        }
        return result;
    }



你可能感兴趣的:(cts设备管理)