1#!/usr/bin/env python 2# 3# Copyright (C) 2020 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import logging 19import subprocess 20import time 21 22from threading import Timer 23 24class AdbError(Exception): 25 """Raised when there is an error in adb operations.""" 26 27 def __init__(self, cmd, stdout, stderr, ret_code): 28 self.cmd = cmd 29 self.stdout = stdout 30 self.stderr = stderr 31 self.ret_code = ret_code 32 33 def __str__(self): 34 return ("Error executing adb cmd '%s'. ret: %d, stdout: %s, stderr: %s" 35 ) % (self.cmd, self.ret_code, self.stdout, self.stderr) 36 37 38class ADB(object): 39 """This class to wrap adb command.""" 40 41 # Default adb timeout 5 minutes 42 DEFAULT_ADB_TIMEOUT = 300 43 44 def __init__(self, serial_number): 45 self._serial_number = serial_number 46 47 def Execute(self, cmd_list, timeout=DEFAULT_ADB_TIMEOUT): 48 """Executes a command. 49 50 Args: 51 args: Strings, the arguments. 52 53 Returns: 54 Stdout as a string, stderr as a string, and return code as an 55 integer. 56 """ 57 cmd = ["adb", "-s", self._serial_number] 58 cmd.extend(cmd_list) 59 return RunCommand(cmd, timeout) 60 61 62def RunCommand(cmd, timeout=None): 63 kill = lambda process:process.kill() 64 proc = subprocess.Popen(args=cmd, 65 stderr=subprocess.PIPE, 66 stdout=subprocess.PIPE) 67 _timer = Timer(timeout, kill, [proc]) 68 try: 69 _timer.start() 70 (out, err) = proc.communicate() 71 finally: 72 _timer.cancel() 73 74 out = out.decode("utf-8") 75 err = err.decode("utf-8") 76 77 if proc.returncode != 0: 78 raise AdbError(cmd, out, err, proc.returncode) 79 return out, err, proc.returncode 80 81