CTS framework analysis (9)-idevicerecovery

Source: Internet
Author: User

When the device is offline, the CTS Framework calls the idevicerecovery interface class to recover the device.


Interface


/* * 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;}


This interface requires three methods:

Recoverdevice: a device that no longer communicates with each other.

Recoverdevicerecovery: When the mobile phone is in the recovery engineering mode and the message has been sent but does not respond, you need to call this method to reconnect again.
Recoverdevicebootloader: Restores devices without feedback. Different from the above, the current device is in the bootloader mode.


Implementation class


The CTS mode implementation class is 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");    }}

The method of this class details how to implement the reconnection mechanism. If you are interested, you can learn more. I'm not very interested.


CTS framework analysis (9)-idevicerecovery

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.