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        adbProcess = subprocess.Popen(adbCmd.split(" "), bufsize = -1, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
35        return adbProcess.communicate()
36
37    def runShellCommand(self, cmd):
38        return self.runAdbCommand("shell " + cmd)
39
40    def waitForAdbDevice(self):
41        os.system("adb -s %s wait-for-device" %self._adbDevice)
42
43    def waitForBootComplete(self, timeout = 240):
44        boot_complete = False
45        attempts = 0
46        wait_period = 5
47        while not boot_complete and (attempts*wait_period) < timeout:
48            (output, err) = self.runShellCommand("getprop dev.bootcomplete")
49            output = output.strip()
50            if output == "1":
51                boot_complete = True
52            else:
53                time.sleep(wait_period)
54                attempts += 1
55        if not boot_complete:
56            print "***boot not complete within timeout. will proceed to the next step"
57        return boot_complete
58
59    def installApk(self, apkPath):
60        (out, err) = self.runAdbCommand("install -r -d -g " + apkPath)
61        result = err.split()
62        return (out, err, "Success" in result)
63
64    def uninstallApk(self, package):
65        (out, err) = self.runAdbCommand("uninstall " + package)
66        result = err.split()
67        return "Success" in result
68
69    def runInstrumentationTest(self, option):
70        return self.runShellCommand("am instrument -w " + option)
71
72    def isProcessAlive(self, processName):
73        (out, err) = self.runShellCommand("ps")
74        names = out.split()
75        # very lazy implementation as it does not filter out things like uid
76        # should work mostly unless processName is too simple to overlap with
77        # uid. So only use name like com.android.xyz
78        return processName in names
79
80    def getDensity(self):
81        if "emulator" in self._adbDevice:
82          return int(self.runShellCommand("getprop qemu.sf.lcd_density")[0])
83        else:
84          return int(self.runShellCommand("getprop ro.sf.lcd_density")[0])
85
86    def getSdkLevel(self):
87        return int(self.runShellCommand("getprop ro.build.version.sdk")[0])
88
89    def getOrientation(self):
90        return int(self.runShellCommand("dumpsys | grep SurfaceOrientation")[0].split()[1])
91
92def runAdbDevices():
93    devices = subprocess.check_output(["adb", "devices"])
94    devices = devices.split('\n')[1:]
95
96    deviceSerial = []
97
98    for device in devices:
99        if device is not "":
100            info = device.split('\t')
101            if info[1] == "device":
102                deviceSerial.append(info[0])
103
104    return deviceSerial
105
106if __name__ == '__main__':
107    main(sys.argv)
108