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