Cts框架解析(9)-IDeviceRecovery

来源:互联网 发布:传智播客php培训 编辑:程序博客网 时间:2024/06/06 00:25

当设备处于offline状态时,cts框架就要调用IDeviceRecovery接口类去做相应的恢复工作。


接口


/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.android.tradefed.device;/** * Interface for recovering a device that has gone offline. */public interface IDeviceRecovery {    /**     * Attempt to recover the given device that can no longer be communicated with.     * <p/>     * Method should block and only return when device is in requested state.     *     * @param monitor the {@link IDeviceStateMonitor} to use.     * @param recoverUntilOnline if true, method should return as soon as device is online on adb.     *            If false, method should block until device is fully available for testing (ie     *            {@link IDeviceStateMonitor#waitForDeviceAvailable()} succeeds.     * @throws DeviceNotAvailableException if device could not be recovered     */    public void recoverDevice(IDeviceStateMonitor monitor, boolean recoverUntilOnline)            throws DeviceNotAvailableException;    /**     * Attempt to recover the given unresponsive device in recovery mode.     *     * @param monitor the {@link IDeviceStateMonitor} to use.     * @throws DeviceNotAvailableException if device could not be recovered     */    public void recoverDeviceRecovery(IDeviceStateMonitor monitor)            throws DeviceNotAvailableException;    /**     * Attempt to recover the given unresponsive device in bootloader mode.     *     * @param monitor the {@link IDeviceStateMonitor} to use.     * @throws DeviceNotAvailableException if device could not be recovered     */    public void recoverDeviceBootloader(IDeviceStateMonitor monitor)            throws DeviceNotAvailableException;}


该接口中要三个方法:

recoverDevice:连接不再通信的设备

recoverDeviceRecovery:当手机处于Recovery工程模式下,已经发送信息,但是没有反应,就需要调用该方法再次重连。
recoverDeviceBootloader:恢复没有反馈的设备,与上面不同的是当前设备处于BootLoader模式下。


实现类


cts模式的实现类为WaitDeviceRecovery:


/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.android.tradefed.device;import com.android.ddmlib.AdbCommandRejectedException;import com.android.ddmlib.IDevice;import com.android.ddmlib.Log;import com.android.ddmlib.TimeoutException;import com.android.tradefed.config.Option;import com.android.tradefed.log.LogUtil.CLog;import com.android.tradefed.util.IRunUtil;import com.android.tradefed.util.RunUtil;import java.io.IOException;/** * A simple implementation of a {@link IDeviceRecovery} that waits for device to be online and * respond to simple commands. */public class WaitDeviceRecovery implements IDeviceRecovery {    private static final String LOG_TAG = "WaitDeviceRecovery";    /** the time in ms to wait before beginning recovery attempts */    protected static final long INITIAL_PAUSE_TIME = 5 * 1000;    /**     * The number of attempts to check if device is in bootloader.     * <p/>     * Exposed for unit testing     */    public static final int BOOTLOADER_POLL_ATTEMPTS = 3;    // TODO: add a separate configurable timeout per operation    @Option(name="device-wait-time",            description="maximum time in ms to wait for a single device recovery command.")    protected long mWaitTime = 4 * 60 * 1000;    @Option(name="bootloader-wait-time",            description="maximum time in ms to wait for device to be in fastboot.")    protected long mBootloaderWaitTime = 30 * 1000;    @Option(name="shell-wait-time",            description="maximum time in ms to wait for device shell to be responsive.")    protected long mShellWaitTime = 30 * 1000;    @Option(name = "disable-unresponsive-reboot",            description = "If this is set, we will not attempt to reboot an unresponsive device" +            "that is in userspace.  Note that this will have no effect if the device is in " +            "fastboot or is expected to be in fastboot.")    protected boolean mDisableUnresponsiveReboot = false;    /**     * Get the {@link RunUtil} instance to use.     * <p/>     * Exposed for unit testing.     */    protected IRunUtil getRunUtil() {        return RunUtil.getDefault();    }    /**     * Sets the maximum time in ms to wait for a single device recovery command.     */    void setWaitTime(long waitTime) {        mWaitTime = waitTime;    }    /**     * {@inheritDoc}     */    @Override    public void recoverDevice(IDeviceStateMonitor monitor, boolean recoverUntilOnline)            throws DeviceNotAvailableException {        // device may have just gone offline        // sleep a small amount to give ddms state a chance to settle        // TODO - see if there is better way to handle this        Log.i(LOG_TAG, String.format("Pausing for %d for %s to recover",                INITIAL_PAUSE_TIME, monitor.getSerialNumber()));        getRunUtil().sleep(INITIAL_PAUSE_TIME);        // ensure bootloader state is updated        monitor.waitForDeviceBootloaderStateUpdate();        if (monitor.getDeviceState().equals(TestDeviceState.FASTBOOT)) {            Log.i(LOG_TAG, String.format(                    "Found device %s in fastboot but expected online. Rebooting...",                    monitor.getSerialNumber()));            // TODO: retry if failed            getRunUtil().runTimedCmd(20*1000, "fastboot", "-s", monitor.getSerialNumber(),                    "reboot");        }        // wait for device online        IDevice device = monitor.waitForDeviceOnline();        if (device == null) {            handleDeviceNotAvailable(monitor, recoverUntilOnline);            return;        }        // occasionally device is erroneously reported as online - double check that we can shell        // into device        if (!monitor.waitForDeviceShell(mShellWaitTime)) {            // treat this as a not available device            handleDeviceNotAvailable(monitor, recoverUntilOnline);            return;        }        if (!recoverUntilOnline) {            if (monitor.waitForDeviceAvailable(mWaitTime) == null) {                // device is online but not responsive                handleDeviceUnresponsive(device, monitor);            }        }    }    /**     * Handle situation where device is online but unresponsive.     * @param monitor     * @throws DeviceNotAvailableException     */    protected void handleDeviceUnresponsive(IDevice device, IDeviceStateMonitor monitor)            throws DeviceNotAvailableException {        if (!mDisableUnresponsiveReboot) {            rebootDevice(device);        }        IDevice newdevice = monitor.waitForDeviceOnline();        if (newdevice == null) {            handleDeviceNotAvailable(monitor, false);            return;        }        if (monitor.waitForDeviceAvailable(mWaitTime) == null) {            throw new DeviceUnresponsiveException(String.format(                    "Device %s is online but unresponsive", monitor.getSerialNumber()));        }    }    /**     * Handle situation where device is not available.     *     * @param monitor the {@link IDeviceStateMonitor}     * @param recoverTillOnline if true this method should return if device is online, and not     * check for responsiveness     * @throws DeviceNotAvailableException     */    protected void handleDeviceNotAvailable(IDeviceStateMonitor monitor, boolean recoverTillOnline)            throws DeviceNotAvailableException {        throw new DeviceNotAvailableException(String.format("Could not find device %s",                monitor.getSerialNumber()));    }    /**     * {@inheritDoc}     */    @Override    public void recoverDeviceBootloader(final IDeviceStateMonitor monitor)            throws DeviceNotAvailableException {        // device may have just gone offline        // wait a small amount to give device state a chance to settle        // TODO - see if there is better way to handle this        Log.i(LOG_TAG, String.format("Pausing for %d for %s to recover",                INITIAL_PAUSE_TIME, monitor.getSerialNumber()));        getRunUtil().sleep(INITIAL_PAUSE_TIME);        // poll and wait for device to return to valid state        long pollTime = mBootloaderWaitTime / BOOTLOADER_POLL_ATTEMPTS;        for (int i=0; i < BOOTLOADER_POLL_ATTEMPTS; i++) {            if (monitor.waitForDeviceBootloader(pollTime)) {                handleDeviceBootloaderUnresponsive(monitor);                // passed above check, abort                return;            } else if (monitor.getDeviceState() == TestDeviceState.ONLINE) {                handleDeviceOnlineExpectedBootloader(monitor);                return;            }        }        handleDeviceBootloaderNotAvailable(monitor);    }    /**     * Handle condition where device is online, but should be in bootloader state.     * <p/>     * If this method     * @param monitor     * @throws DeviceNotAvailableException     */    protected void handleDeviceOnlineExpectedBootloader(final IDeviceStateMonitor monitor)            throws DeviceNotAvailableException {        Log.i(LOG_TAG, String.format("Found device %s online but expected fastboot.",            monitor.getSerialNumber()));        // call waitForDeviceOnline to get handle to IDevice        IDevice device = monitor.waitForDeviceOnline();        if (device == null) {            handleDeviceBootloaderNotAvailable(monitor);            return;        }        rebootDeviceIntoBootloader(device);        if (!monitor.waitForDeviceBootloader(mBootloaderWaitTime)) {            throw new DeviceNotAvailableException(String.format(                    "Device %s not in bootloader after reboot", monitor.getSerialNumber()));        }    }    /**     * @param monitor     * @throws DeviceNotAvailableException     */    protected void handleDeviceBootloaderUnresponsive(IDeviceStateMonitor monitor)            throws DeviceNotAvailableException {        CLog.i("Found device %s in fastboot but potentially unresponsive.",                monitor.getSerialNumber());        // TODO: retry reboot        getRunUtil().runTimedCmd(20*1000, "fastboot", "-s", monitor.getSerialNumber(),                "reboot-bootloader");        // wait for device to reboot        monitor.waitForDeviceNotAvailable(20*1000);        if (!monitor.waitForDeviceBootloader(mBootloaderWaitTime)) {            throw new DeviceNotAvailableException(String.format(                    "Device %s not in bootloader after reboot", monitor.getSerialNumber()));        }    }    /**     * Reboot device into bootloader.     *     * @param device the {@link IDevice} to reboot.     */    protected void rebootDeviceIntoBootloader(IDevice device) {        try {            device.reboot("bootloader");        } catch (IOException e) {            Log.w(LOG_TAG, String.format("failed to reboot %s: %s", device.getSerialNumber(),                    e.getMessage()));        } catch (TimeoutException e) {            Log.w(LOG_TAG, String.format("failed to reboot %s: timeout", device.getSerialNumber()));        } catch (AdbCommandRejectedException e) {            Log.w(LOG_TAG, String.format("failed to reboot %s: %s", device.getSerialNumber(),                    e.getMessage()));        }    }    /**     * Reboot device into bootloader.     *     * @param device the {@link IDevice} to reboot.     */    protected void rebootDevice(IDevice device) {        try {            device.reboot(null);        } catch (IOException e) {            Log.w(LOG_TAG, String.format("failed to reboot %s: %s", device.getSerialNumber(),                    e.getMessage()));        } catch (TimeoutException e) {            Log.w(LOG_TAG, String.format("failed to reboot %s: timeout", device.getSerialNumber()));        } catch (AdbCommandRejectedException e) {            Log.w(LOG_TAG, String.format("failed to reboot %s: %s", device.getSerialNumber(),                    e.getMessage()));        }    }    /**     * Handle situation where device is not available when expected to be in bootloader.     *     * @param monitor the {@link IDeviceStateMonitor}     * @throws DeviceNotAvailableException     */    protected void handleDeviceBootloaderNotAvailable(final IDeviceStateMonitor monitor)            throws DeviceNotAvailableException {        throw new DeviceNotAvailableException(String.format(                "Could not find device %s in bootloader", monitor.getSerialNumber()));    }    /**     * {@inheritDoc}     */    @Override    public void recoverDeviceRecovery(IDeviceStateMonitor monitor)            throws DeviceNotAvailableException {        throw new DeviceNotAvailableException("device recovery not implemented");    }}

这个类的方法中具体讲了如何实现重连机制,有兴趣的可以详细了解。我不太感兴趣,就一笔带过了。


0 0