blob: d5098e713a00d8be900089661bdc436531274831 [file] [log] [blame]
/*
* Copyright (C) 2014 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.Log.LogLevel;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.IRunUtil;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A helper class for fastboot operations.
*/
public class FastbootHelper {
/** max wait time in ms for fastboot devices command to complete */
private static final long FASTBOOT_CMD_TIMEOUT = 1 * 60 * 1000;
private IRunUtil mRunUtil;
/**
* Constructor.
*
* @param runUtil a {@link IRunUtil}.
*/
public FastbootHelper(final IRunUtil runUtil) {
if (runUtil == null) {
throw new IllegalArgumentException("runUtil cannot be null");
}
mRunUtil = runUtil;
}
/**
* Determine if fastboot is available for use.
*/
public boolean isFastbootAvailable() {
// Run "fastboot help" to check the existence and the version of fastboot
// (Old versions do not support "help" command).
CommandResult fastbootResult = mRunUtil.runTimedCmdSilently(5000, "fastboot", "help");
if (fastbootResult.getStatus() == CommandStatus.SUCCESS) {
return true;
}
if (fastbootResult.getStderr() != null &&
fastbootResult.getStderr().indexOf("usage: fastboot") >= 0) {
CLog.logAndDisplay(LogLevel.WARN,
"You are running an older version of fastboot, please update it.");
return true;
}
CLog.d("fastboot not available. stdout: %s, stderr: %s",
fastbootResult.getStdout(), fastbootResult.getStderr());
return false;
}
/**
* Returns a set of device serials in fastboot mode.
*
* @return a set of device serials.
*/
public Set<String> getDevices() {
CommandResult fastbootResult = mRunUtil.runTimedCmd(FASTBOOT_CMD_TIMEOUT,
"fastboot", "devices");
if (fastbootResult.getStatus().equals(CommandStatus.SUCCESS)) {
CLog.v("fastboot devices returned\n %s",
fastbootResult.getStdout());
return parseDevices(fastbootResult.getStdout());
} else {
CLog.w("'fastboot devices' failed. Result: %s, stderr: %s", fastbootResult.getStatus(),
fastbootResult.getStderr());
}
return null;
}
/**
* Parses the output of "fastboot devices" command.
* Exposed for unit testing.
*
* @param fastbootOutput the output of fastboot command.
* @return a set of device serials.
*/
Set<String> parseDevices(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;
}
/**
* Executes a fastboot command on a device and return the output.
*
* @param serial a device serial.
* @param command a fastboot command to run.
* @return the output of the fastboot command. null if the command failed.
*/
public String executeCommand(String serial, String command) {
final CommandResult fastbootResult = mRunUtil.runTimedCmd(FASTBOOT_CMD_TIMEOUT,
"fastboot", "-s", serial, command);
if (fastbootResult.getStatus() != CommandStatus.SUCCESS) {
CLog.w("'fastboot -s %s %s' failed. Result: %s, stderr: %s", serial, command,
fastbootResult.getStatus(), fastbootResult.getStderr());
return null;
}
return fastbootResult.getStdout();
}
}