1#!/usr/bin/env python 2# 3# Copyright (C) 2015 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 os 19import re 20import sys 21import threading 22import subprocess 23import time 24 25# class for running android device from python 26# it will fork the device processor 27class androidDevice(object): 28 def __init__(self, adbDevice): 29 self._adbDevice = adbDevice 30 31 def runAdbCommand(self, cmd): 32 self.waitForAdbDevice() 33 adbCmd = "adb -s %s %s" %(self._adbDevice, cmd) 34 print adbCmd 35 adbProcess = subprocess.Popen(adbCmd.split(" "), bufsize = -1, stdout = subprocess.PIPE, stderr = subprocess.PIPE) 36 return adbProcess.communicate() 37 38 def runShellCommand(self, cmd): 39 return self.runAdbCommand("shell " + cmd) 40 41 def waitForAdbDevice(self): 42 print "waitForAdbDevice" 43 os.system("adb -s %s wait-for-device" %self._adbDevice) 44 45 def waitForBootComplete(self, timeout = 240): 46 boot_complete = False 47 attempts = 0 48 wait_period = 5 49 while not boot_complete and (attempts*wait_period) < timeout: 50 (output, err) = self.runShellCommand("getprop dev.bootcomplete") 51 output = output.strip() 52 if output == "1": 53 boot_complete = True 54 else: 55 time.sleep(wait_period) 56 attempts += 1 57 if not boot_complete: 58 print "***boot not complete within timeout. will proceed to the next step" 59 return boot_complete 60 61 def installApk(self, apkPath): 62 (out, err) = self.runAdbCommand("install -r -d -g " + apkPath) 63 result = err.split() 64 return (out, err, "Success" in result) 65 66 def uninstallApk(self, package): 67 (out, err) = self.runAdbCommand("uninstall " + package) 68 result = err.split() 69 return "Success" in result 70 71 def runInstrumentationTest(self, option): 72 return self.runShellCommand("am instrument -w --no-window-animation " + option) 73 74 def isProcessAlive(self, processName): 75 (out, err) = self.runShellCommand("ps") 76 names = out.split() 77 # very lazy implementation as it does not filter out things like uid 78 # should work mostly unless processName is too simple to overlap with 79 # uid. So only use name like com.android.xyz 80 return processName in names 81 82 def getVersionSdkInt(self): 83 return int(self.runShellCommand("getprop ro.build.version.sdk")[0]) 84 85 def getVersionCodename(self): 86 return self.runShellCommand("getprop ro.build.version.codename")[0].strip() 87 88 def getDensity(self): 89 if "emulator" in self._adbDevice: 90 return int(self.runShellCommand("getprop qemu.sf.lcd_density")[0]) 91 else: 92 return int(self.runShellCommand("getprop ro.sf.lcd_density")[0]) 93 94 def getSdkLevel(self): 95 return int(self.runShellCommand("getprop ro.build.version.sdk")[0]) 96 97 def getOrientation(self): 98 return int(self.runShellCommand("dumpsys | grep SurfaceOrientation")[0].split()[1]) 99 100 # Running dumpsys on the emulator currently yields a SIGSEGV, so don't do it. 101 # 102 #def getHWType(self): 103 # (output, err) = self.runShellCommand("dumpsys | grep android.hardware.type") 104 # output = output.strip() 105 # return output 106 107def runAdbDevices(): 108 devices = subprocess.check_output(["adb", "devices"]) 109 devices = devices.split('\n')[1:] 110 111 deviceSerial = [] 112 113 for device in devices: 114 if device is not "": 115 info = device.split('\t') 116 if info[1] == "device": 117 deviceSerial.append(info[0]) 118 119 return deviceSerial 120 121if __name__ == '__main__': 122 main(sys.argv) 123