Home | History | Annotate | Download | only in theme
      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 
     18 import os
     19 import sys
     20 import threading
     21 import time
     22 import traceback
     23 import Queue
     24 sys.path.append(sys.path[0])
     25 from android_device import *
     26 
     27 CTS_THEME_dict = {
     28     120 : "ldpi",
     29     160 : "mdpi",
     30     213 : "tvdpi",
     31     240 : "hdpi",
     32     320 : "xhdpi",
     33     480 : "xxhdpi",
     34     640 : "xxxhdpi",
     35 }
     36 
     37 OUT_FILE = "/sdcard/cts-theme-assets.zip"
     38 
     39 # pass a function with number of instances to be executed in parallel
     40 # each thread continues until config q is empty.
     41 def executeParallel(tasks, setup, q, numberThreads):
     42     class ParallelExecutor(threading.Thread):
     43         def __init__(self, tasks, q):
     44             threading.Thread.__init__(self)
     45             self._q = q
     46             self._tasks = tasks
     47             self._setup = setup
     48             self._result = 0
     49 
     50         def run(self):
     51             try:
     52                 while True:
     53                     config = q.get(block=True, timeout=2)
     54                     for t in self._tasks:
     55                         try:
     56                             if t(self._setup, config):
     57                                 self._result += 1
     58                         except KeyboardInterrupt:
     59                             raise
     60                         except:
     61                             print "Failed to execute thread:", sys.exc_info()[0]
     62                             traceback.print_exc()
     63                     q.task_done()
     64             except KeyboardInterrupt:
     65                 raise
     66             except Queue.Empty:
     67                 pass
     68 
     69         def getResult(self):
     70             return self._result
     71 
     72     result = 0;
     73     threads = []
     74     for i in range(numberThreads):
     75         t = ParallelExecutor(tasks, q)
     76         t.start()
     77         threads.append(t)
     78     for t in threads:
     79         t.join()
     80         result += t.getResult()
     81     return result;
     82 
     83 def printAdbResult(device, out, err):
     84     print "device: " + device
     85     if out is not None:
     86         print "out:\n" + out
     87     if err is not None:
     88         print "err:\n" + err
     89 
     90 def getResDir(outPath, resName):
     91     resDir = outPath + "/" + resName
     92     return resDir
     93 
     94 def doCapturing(setup, deviceSerial):
     95     (themeApkPath, outPath) = setup
     96 
     97     print "Found device: " + deviceSerial
     98     device = androidDevice(deviceSerial)
     99 
    100     density = device.getDensity()
    101     if CTS_THEME_dict.has_key(density):
    102         resName = CTS_THEME_dict[density]
    103     else:
    104         resName = str(density) + "dpi"
    105 
    106     device.uninstallApk("android.theme.app")
    107 
    108     (out, err, success) = device.installApk(themeApkPath)
    109     if not success:
    110         print "Failed to install APK on " + deviceSerial
    111         printAdbResult(deviceSerial, out, err)
    112         return False
    113 
    114     print "Generating images on " + deviceSerial + "..."
    115     try:
    116         (out, err) = device.runInstrumentationTest("android.theme.app/android.support.test.runner.AndroidJUnitRunner")
    117     except KeyboardInterrupt:
    118         raise
    119     except:
    120         (out, err) = device.runInstrumentationTest("android.theme.app/android.test.InstrumentationTestRunner")
    121 
    122     # Detect test failure and abort.
    123     if "FAILURES!!!" in out.split():
    124         printAdbResult(deviceSerial, out, err)
    125         return False
    126 
    127     # Make sure that the run is complete by checking the process itself
    128     print "Waiting for " + deviceSerial + "..."
    129     waitTime = 0
    130     while device.isProcessAlive("android.theme.app"):
    131         time.sleep(1)
    132         waitTime = waitTime + 1
    133         if waitTime > 180:
    134             print "Timed out"
    135             break
    136 
    137     time.sleep(10)
    138     resDir = getResDir(outPath, resName)
    139 
    140     print "Pulling images from " + deviceSerial + " to " + resDir + ".zip"
    141     device.runAdbCommand("pull " + OUT_FILE + " " + resDir + ".zip")
    142     device.runAdbCommand("shell rm -rf " + OUT_FILE)
    143     return True
    144 
    145 def main(argv):
    146     if len(argv) < 3:
    147         print "run_theme_capture_device.py themeApkPath outDir"
    148         sys.exit(1)
    149     themeApkPath = argv[1]
    150     outPath = os.path.abspath(argv[2])
    151     os.system("mkdir -p " + outPath)
    152 
    153     tasks = []
    154     tasks.append(doCapturing)
    155 
    156     devices = runAdbDevices();
    157     numberThreads = len(devices)
    158 
    159     configQ = Queue.Queue()
    160     for device in devices:
    161         configQ.put(device)
    162     setup = (themeApkPath, outPath)
    163     result = executeParallel(tasks, setup, configQ, numberThreads)
    164 
    165     if result > 0:
    166         print 'Generated reference images for %(count)d devices' % {"count": result}
    167     else:
    168         print 'Failed to generate reference images'
    169 
    170 if __name__ == '__main__':
    171     main(sys.argv)
    172