1ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad#!/usr/bin/python
2ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadimport hashlib
3ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadimport optparse
4ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadimport os
5ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadimport re
6ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadimport shlex
7ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadimport subprocess
8ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadimport sys
9ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadimport threading
10ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadimport time
11ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
12ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_COMPILATION = 'compile'
13ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_DISABLE_OVERLAYS = 'disable overlays'
14ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_ENABLE_MULTIPLE_OVERLAYS = 'enable multiple overlays'
15ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_ENABLE_SINGLE_OVERLAY = 'enable single overlay'
16d5566c6c47faa6b9dda282741e25ac78c9487d58Todd LeeTASK_ENABLE_FILTERED_OVERLAYS = 'enable filtered overlays'
17ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_FILE_EXISTS_TEST = 'test (file exists)'
18ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_GREP_IDMAP_TEST = 'test (grep idmap)'
19ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_MD5_TEST = 'test (md5)'
20ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_IDMAP_PATH = 'idmap --path'
21ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_IDMAP_SCAN = 'idmap --scan'
22ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_INSTRUMENTATION = 'instrumentation'
23ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_INSTRUMENTATION_TEST = 'test (instrumentation)'
24ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_MKDIR = 'mkdir'
25ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_PUSH = 'push'
26ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_ROOT = 'root'
27ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_REMOUNT = 'remount'
28ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_RM = 'rm'
29d5566c6c47faa6b9dda282741e25ac78c9487d58Todd LeeTASK_SETPROP = 'setprop'
30ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_SETUP_IDMAP_PATH = 'setup idmap --path'
31ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_SETUP_IDMAP_SCAN = 'setup idmap --scan'
32ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_START = 'start'
33ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten KongstadTASK_STOP = 'stop'
34ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
35ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadadb = 'adb'
36ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
37ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstaddef _adb_shell(cmd):
38ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    argv = shlex.split(adb + " shell '" + cmd + "; echo $?'")
39ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    proc = subprocess.Popen(argv, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
40ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    (stdout, stderr) = proc.communicate()
41ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    (stdout, stderr) = (stdout.replace('\r', ''), stderr.replace('\r', ''))
42ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    tmp = stdout.rsplit('\n', 2)
43ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if len(tmp) == 2:
44ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        stdout == ''
45ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        returncode = int(tmp[0])
46ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    else:
47ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        stdout = tmp[0] + '\n'
48ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        returncode = int(tmp[1])
49ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    return returncode, stdout, stderr
50ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
51ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass VerbosePrinter:
52ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    class Ticker(threading.Thread):
53ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        def _print(self):
54ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            s = '\r' + self.text + '[' + '.' * self.i + ' ' * (4 - self.i) + ']'
55ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            sys.stdout.write(s)
56ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            sys.stdout.flush()
57ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.i = (self.i + 1) % 5
58ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
59ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        def __init__(self, cond_var, text):
60ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            threading.Thread.__init__(self)
61ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.text = text
62ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.setDaemon(True)
63ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.cond_var = cond_var
64ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.running = False
65ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.i = 0
66ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self._print()
67ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.running = True
68ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
69ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        def run(self):
70ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.cond_var.acquire()
71ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            while True:
72ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                self.cond_var.wait(0.25)
73ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                running = self.running
74ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                if not running:
75ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                    break
76ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                self._print()
77ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.cond_var.release()
78ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
79ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        def stop(self):
80ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.cond_var.acquire()
81ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.running = False
82ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.cond_var.notify_all()
83ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.cond_var.release()
84ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
85ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def _start_ticker(self):
86ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.ticker = VerbosePrinter.Ticker(self.cond_var, self.text)
87ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.ticker.start()
88ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
89ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def _stop_ticker(self):
90ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.ticker.stop()
91ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.ticker.join()
92ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.ticker = None
93ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
94ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def _format_begin(self, type, name):
95ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        N = self.width - len(type) - len(' [    ] ')
96ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        fmt = '%%s %%-%ds ' % N
97ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return fmt % (type, name)
98ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
99ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, use_color):
100ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.cond_var = threading.Condition()
101ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.ticker = None
102ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if use_color:
103ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.color_RED = '\033[1;31m'
104ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.color_red = '\033[0;31m'
105ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.color_reset = '\033[0;37m'
106ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        else:
107ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.color_RED = ''
108ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.color_red = ''
109ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.color_reset = ''
110ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
111ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        argv = shlex.split('stty size') # get terminal width
112ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
113ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        (stdout, stderr) = proc.communicate()
114ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if proc.returncode == 0:
115ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            (h, w) = stdout.split()
116ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.width = int(w)
117ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        else:
118ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            self.width = 72 # conservative guesstimate
119ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
120ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def begin(self, type, name):
121ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.text = self._format_begin(type, name)
122ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.write(self.text + '[    ]')
123ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.flush()
124ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self._start_ticker()
125ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
126ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def end_pass(self, type, name):
127ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self._stop_ticker()
128ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.write('\r' + self.text + '[ OK ]\n')
129ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.flush()
130ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
131ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def end_fail(self, type, name, msg):
132ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self._stop_ticker()
133ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.write('\r' + self.color_RED + self.text + '[FAIL]\n')
134ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.write(self.color_red)
135ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.write(msg)
136ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.write(self.color_reset)
137ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.flush()
138ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
139ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass QuietPrinter:
140ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def begin(self, type, name):
141ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        pass
142ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
143ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def end_pass(self, type, name):
144ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.write('PASS ' + type + ' ' + name + '\n')
145ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.flush()
146ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
147ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def end_fail(self, type, name, msg):
148ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.write('FAIL ' + type + ' ' + name + '\n')
149ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        sys.stdout.flush()
150ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
151ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass CompilationTask:
152ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, makefile):
153ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.makefile = makefile
154ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
155ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
156ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_COMPILATION
157ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
158ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
159ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.makefile
160ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
161ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
162ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        os.putenv('ONE_SHOT_MAKEFILE', os.getcwd() + "/" + self.makefile)
163ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        argv = shlex.split('make -C "../../../../../" files')
164ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
165ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        (stdout, stderr) = proc.communicate()
166ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return proc.returncode, stdout, stderr
167ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
168ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass InstrumentationTask:
169ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, instrumentation_class):
170ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.instrumentation_class = instrumentation_class
171ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
172ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
173ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_INSTRUMENTATION
174ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
175ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
176ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.instrumentation_class
177ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
178ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
179ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return _adb_shell('am instrument -r -w -e class %s com.android.overlaytest/android.test.InstrumentationTestRunner' % self.instrumentation_class)
180ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
181ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass PushTask:
182ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, src, dest):
183ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.src = src
184ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.dest = dest
185ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
186ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
187ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_PUSH
188ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
189ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
190ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return "%s -> %s" % (self.src, self.dest)
191ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
192ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
193d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        src = os.getenv('OUT')
194d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        if (src is None):
195d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee          return 1, "", "Unable to proceed - $OUT environment var not set\n"
196d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        src += "/" + self.src
197ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        argv = shlex.split(adb + ' push %s %s' % (src, self.dest))
198ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
199ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        (stdout, stderr) = proc.communicate()
200ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return proc.returncode, stdout, stderr
201ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
202ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass MkdirTask:
203ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, path):
204ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.path = path
205ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
206ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
207ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_MKDIR
208ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
209ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
210ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.path
211ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
212ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
213ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return _adb_shell('mkdir -p %s' % self.path)
214ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
215ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass RmTask:
216ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, path):
217ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.path = path
218ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
219ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
220ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_RM
221ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
222ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
223ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.path
224ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
225ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
226ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        returncode, stdout, stderr = _adb_shell('ls %s' % self.path)
227d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        if returncode != 0 and stderr.endswith(': No such file or directory\n'):
228ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return 0, "", ""
229ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return _adb_shell('rm -r %s' % self.path)
230ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
231d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Leeclass SetPropTask:
232d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    def __init__(self, prop, value):
233d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        self.prop = prop
234d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        self.value = value
235d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee
236d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    def get_type(self):
237d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        return TASK_SETPROP
238d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee
239d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    def get_name(self):
240d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        return self.prop
241d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee
242d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    def execute(self):
243d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee      return _adb_shell('setprop %s %s' % (self.prop, self.value))
244d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee
245ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass IdmapPathTask:
246ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, path_target_apk, path_overlay_apk, path_idmap):
247ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.path_target_apk = path_target_apk
248ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.path_overlay_apk = path_overlay_apk
249ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.path_idmap = path_idmap
250ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
251ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
252ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_IDMAP_PATH
253ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
254ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
255ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.path_idmap
256ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
257ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
258d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        return _adb_shell('su system idmap --scan "%s" "%s" "%s" "%s"' % (self.target_pkg_name, self.target_pkg, self.idmap_dir, self.overlay_dir))
259ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
260ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass IdmapScanTask:
261ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, overlay_dir, target_pkg_name, target_pkg, idmap_dir, symlink_dir):
262ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.overlay_dir = overlay_dir
263ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.target_pkg_name = target_pkg_name
264ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.target_pkg = target_pkg
265ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.idmap_dir = idmap_dir
266ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.symlink_dir = symlink_dir
267ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
268ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
269ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_IDMAP_SCAN
270ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
271ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
272ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.target_pkg_name
273ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
274ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
275ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return _adb_shell('su system idmap --scan "%s" "%s" "%s" "%s"' % (self.overlay_dir, self.target_pkg_name, self.target_pkg, self.idmap_dir))
276ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
277ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass FileExistsTest:
278ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, path):
279ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.path = path
280ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
281ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
282ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_FILE_EXISTS_TEST
283ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
284ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
285ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.path
286ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
287ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
288ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return _adb_shell('ls %s' % self.path)
289ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
290ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass GrepIdmapTest:
291ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, path_idmap, pattern, expected_n):
292ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.path_idmap = path_idmap
293ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.pattern = pattern
294ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.expected_n = expected_n
295ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
296ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
297ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_GREP_IDMAP_TEST
298ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
299ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
300ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.pattern
301ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
302ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
303ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        returncode, stdout, stderr = _adb_shell('idmap --inspect %s' % self.path_idmap)
304ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if returncode != 0:
305ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return returncode, stdout, stderr
306ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        all_matches = re.findall('\s' + self.pattern + '$', stdout, flags=re.MULTILINE)
307ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if len(all_matches) != self.expected_n:
308ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return 1, 'pattern=%s idmap=%s expected=%d found=%d\n' % (self.pattern, self.path_idmap, self.expected_n, len(all_matches)), ''
309ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return 0, "", ""
310ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
311ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass Md5Test:
312ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, path, expected_content):
313ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.path = path
314ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.expected_md5 = hashlib.md5(expected_content).hexdigest()
315ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
316ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
317ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_MD5_TEST
318ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
319ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
320ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.path
321ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
322ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
323415fa1f5c0eab260211eb192629f61097ed059f3Stephen Smalley        returncode, stdout, stderr = _adb_shell('md5sum %s' % self.path)
324ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if returncode != 0:
325ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return returncode, stdout, stderr
326ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        actual_md5 = stdout.split()[0]
327ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if actual_md5 != self.expected_md5:
328ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return 1, 'expected %s, got %s\n' % (self.expected_md5, actual_md5), ''
329ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return 0, "", ""
330ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
331ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass StartTask:
332ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
333ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_START
334ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
335ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
336ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return ""
337ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
338ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
339ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        (returncode, stdout, stderr) = _adb_shell('start')
340ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if returncode != 0:
341ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return returncode, stdout, stderr
342ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
343ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        while True:
344ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            (returncode, stdout, stderr) = _adb_shell('getprop dev.bootcomplete')
345ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            if returncode != 0:
346ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                return returncode, stdout, stderr
347ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            if stdout.strip() == "1":
348ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                break
349ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            time.sleep(0.5)
350ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
351ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return 0, "", ""
352ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
353ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass StopTask:
354ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
355ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_STOP
356ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
357ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
358ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return ""
359ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
360ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
361ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        (returncode, stdout, stderr) = _adb_shell('stop')
362ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if returncode != 0:
363ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return returncode, stdout, stderr
364ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return _adb_shell('setprop dev.bootcomplete 0')
365ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
366ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass RootTask:
367ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
368ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_ROOT
369ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
370ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
371ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return ""
372ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
373ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
374ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        (returncode, stdout, stderr) = _adb_shell('getprop service.adb.root 0')
375ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if returncode != 0:
376ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return returncode, stdout, stderr
377ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if stdout.strip() == '1': # already root
378ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return 0, "", ""
379ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
380ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        argv = shlex.split(adb + ' root')
381ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
382ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        (stdout, stderr) = proc.communicate()
383ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if proc.returncode != 0:
384ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return proc.returncode, stdout, stderr
385ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
386ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        argv = shlex.split(adb + ' wait-for-device')
387ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
388ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        (stdout, stderr) = proc.communicate()
389ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return proc.returncode, stdout, stderr
390ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
391ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass RemountTask:
392ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
393ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return TASK_REMOUNT
394ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
395ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
396ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return ""
397ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
398ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
399ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        argv = shlex.split(adb + ' remount')
400ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
401ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        (stdout, stderr) = proc.communicate()
402ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        # adb remount returns 0 even if the operation failed, so check stdout
403ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if stdout.startswith('remount failed:'):
404ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            return 1, stdout, stderr
405ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return proc.returncode, stdout, stderr
406ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
407ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadclass CompoundTask:
408ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def __init__(self, type, tasks):
409ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.type = type
410ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        self.tasks = tasks
411ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
412ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_type(self):
413ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return self.type
414ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
415ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def get_name(self):
416ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return ""
417ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
418ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    def execute(self):
419ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        for t in self.tasks:
420ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            (returncode, stdout, stderr) = t.execute()
421ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            if returncode != 0:
422ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                return returncode, stdout, stderr
423ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        return 0, "", ""
424ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
425ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstaddef _create_disable_overlays_task():
426ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    tasks = [
427ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask("/vendor/overlay/framework_a.apk"),
428ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask("/vendor/overlay/framework_b.apk"),
429ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask("/data/resource-cache/vendor@overlay@framework_a.apk@idmap"),
430ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask("/data/resource-cache/vendor@overlay@framework_b.apk@idmap"),
431ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask("/vendor/overlay/app_a.apk"),
432ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask("/vendor/overlay/app_b.apk"),
433d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        RmTask("/vendor/overlay/app_c.apk"),
434ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask("/data/resource-cache/vendor@overlay@app_a.apk@idmap"),
435ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask("/data/resource-cache/vendor@overlay@app_b.apk@idmap"),
436d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        RmTask("/data/resource-cache/vendor@overlay@app_c.apk@idmap"),
437d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        SetPropTask('persist.oem.overlay.test', '""'),
438d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        RmTask("/data/property/persist.oem.overlay.test"),
439ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    ]
440ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    return CompoundTask(TASK_DISABLE_OVERLAYS, tasks)
441ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
442ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstaddef _create_enable_single_overlay_task():
443ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    tasks = [
444ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        _create_disable_overlays_task(),
445ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        MkdirTask('/system/vendor'),
446ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        MkdirTask('/vendor/overlay'),
44797b5df764344c32f8551483385ac4be742427580Mårten Kongstad        PushTask('/data/app/com.android.overlaytest.overlay/com.android.overlaytest.overlay.apk', '/vendor/overlay/framework_a.apk'),
44897b5df764344c32f8551483385ac4be742427580Mårten Kongstad        PushTask('/data/app/com.android.overlaytest.first_app_overlay/com.android.overlaytest.first_app_overlay.apk', '/vendor/overlay/app_a.apk'),
449ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    ]
450ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    return CompoundTask(TASK_ENABLE_SINGLE_OVERLAY, tasks)
451ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
452ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstaddef _create_enable_multiple_overlays_task():
453ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    tasks = [
454ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        _create_disable_overlays_task(),
455ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        MkdirTask('/system/vendor'),
456ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        MkdirTask('/vendor/overlay'),
457ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
45897b5df764344c32f8551483385ac4be742427580Mårten Kongstad        PushTask('/data/app/com.android.overlaytest.overlay/com.android.overlaytest.overlay.apk', '/vendor/overlay/framework_b.apk'),
45997b5df764344c32f8551483385ac4be742427580Mårten Kongstad        PushTask('/data/app/com.android.overlaytest.first_app_overlay/com.android.overlaytest.first_app_overlay.apk', '/vendor/overlay/app_a.apk'),
46097b5df764344c32f8551483385ac4be742427580Mårten Kongstad        PushTask('/data/app/com.android.overlaytest.second_app_overlay/com.android.overlaytest.second_app_overlay.apk', '/vendor/overlay/app_b.apk'),
461d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        PushTask('/data/app/com.android.overlaytest.filtered_app_overlay/com.android.overlaytest.filtered_app_overlay.apk', '/vendor/overlay/app_c.apk'),
462ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    ]
463ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    return CompoundTask(TASK_ENABLE_MULTIPLE_OVERLAYS, tasks)
464ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
465d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Leedef _create_enable_filtered_overlays_task():
466d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee      tasks = [
467d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        _create_disable_overlays_task(),
468d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        SetPropTask('persist.oem.overlay.test', 'foo'),
469d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        MkdirTask('/system/vendor'),
470d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        MkdirTask('/vendor/overlay'),
471d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        PushTask('/data/app/com.android.overlaytest.overlay/com.android.overlaytest.overlay.apk', '/vendor/overlay/framework_b.apk'),
472d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        PushTask('/data/app/com.android.overlaytest.first_app_overlay/com.android.overlaytest.first_app_overlay.apk', '/vendor/overlay/app_a.apk'),
473d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        PushTask('/data/app/com.android.overlaytest.second_app_overlay/com.android.overlaytest.second_app_overlay.apk', '/vendor/overlay/app_b.apk'),
474d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        PushTask('/data/app/com.android.overlaytest.filtered_app_overlay/com.android.overlaytest.filtered_app_overlay.apk', '/vendor/overlay/app_c.apk'),
475d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee      ]
476d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee      return CompoundTask(TASK_ENABLE_FILTERED_OVERLAYS, tasks)
477d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee
478ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstaddef _create_setup_idmap_path_task(idmaps, symlinks):
479ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    tasks = [
480ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        _create_enable_single_overlay_task(),
481ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask(symlinks),
482ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask(idmaps),
483ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        MkdirTask(idmaps),
484ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        MkdirTask(symlinks),
485ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    ]
486ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    return CompoundTask(TASK_SETUP_IDMAP_PATH, tasks)
487ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
488ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstaddef _create_setup_idmap_scan_task(idmaps, symlinks):
489ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    tasks = [
490d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        _create_enable_filtered_overlays_task(),
491ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask(symlinks),
492ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        RmTask(idmaps),
493ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        MkdirTask(idmaps),
494ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        MkdirTask(symlinks),
495ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    ]
496ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    return CompoundTask(TASK_SETUP_IDMAP_SCAN, tasks)
497ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
498ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstaddef _handle_instrumentation_task_output(stdout, printer):
499ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    regex_status_code = re.compile(r'^INSTRUMENTATION_STATUS_CODE: -?(\d+)')
500ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    regex_name = re.compile(r'^INSTRUMENTATION_STATUS: test=(.*)')
501ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    regex_begin_stack = re.compile(r'^INSTRUMENTATION_STATUS: stack=(.*)')
502ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    regex_end_stack = re.compile(r'^$')
503ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
504ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    failed_tests = 0
505ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    current_test = None
506ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    current_stack = []
507ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    mode_stack = False
508ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    for line in stdout.split("\n"):
509ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        line = line.rstrip() # strip \r from adb output
510ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        m = regex_status_code.match(line)
511ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if m:
512ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            c = int(m.group(1))
513ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            if c == 1:
514ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                printer.begin(TASK_INSTRUMENTATION_TEST, current_test)
515ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            elif c == 0:
516ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                printer.end_pass(TASK_INSTRUMENTATION_TEST, current_test)
517ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            else:
518ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                failed_tests += 1
519ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                current_stack.append("\n")
520ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                msg = "\n".join(current_stack)
521ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                printer.end_fail(TASK_INSTRUMENTATION_TEST, current_test, msg.rstrip() + '\n')
522ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            continue
523ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
524ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        m = regex_name.match(line)
525ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if m:
526ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            current_test = m.group(1)
527ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            continue
528ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
529ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        m = regex_begin_stack.match(line)
530ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if m:
531ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            mode_stack = True
532ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            current_stack = []
533ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            current_stack.append("  " + m.group(1))
534ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            continue
535ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
536ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        m = regex_end_stack.match(line)
537ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if m:
538ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            mode_stack = False
539ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            continue
540ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
541ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if mode_stack:
542ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            current_stack.append("    " + line.strip())
543ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
544ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    return failed_tests
545ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
546ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstaddef _set_adb_device(option, opt, value, parser):
547ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    global adb
548ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if opt == '-d' or opt == '--device':
549ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        adb = 'adb -d'
550ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if opt == '-e' or opt == '--emulator':
551ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        adb = 'adb -e'
552ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if opt == '-s' or opt == '--serial':
553ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        adb = 'adb -s ' + value
554ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
555ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstaddef _create_opt_parser():
556ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser = optparse.OptionParser()
557ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-d', '--device', action='callback', callback=_set_adb_device,
558ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='pass -d to adb')
559ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-e', '--emulator', action='callback', callback=_set_adb_device,
560ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='pass -e to adb')
561ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-s', '--serial', type="str", action='callback', callback=_set_adb_device,
562ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='pass -s <serical> to adb')
563ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-C', '--no-color', action='store_false',
564ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            dest='use_color', default=True,
565ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='disable color escape sequences in output')
566ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-q', '--quiet', action='store_true',
567ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            dest='quiet_mode', default=False,
568ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='quiet mode, output only results')
569ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-b', '--no-build', action='store_false',
570ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            dest='do_build', default=True,
571ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='do not rebuild test projects')
572ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-k', '--continue', action='store_true',
573ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            dest='do_continue', default=False,
574ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='do not rebuild test projects')
575ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-i', '--test-idmap', action='store_true',
576ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            dest='test_idmap', default=False,
577d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee            help='run tests for idmap')
578ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-0', '--test-no-overlay', action='store_true',
579ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            dest='test_no_overlay', default=False,
580ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='run tests without any overlay')
581ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-1', '--test-single-overlay', action='store_true',
582ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            dest='test_single_overlay', default=False,
583ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='run tests for single overlay')
584ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    parser.add_option('-2', '--test-multiple-overlays', action='store_true',
585ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            dest='test_multiple_overlays', default=False,
586ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            help='run tests for multiple overlays')
587d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    parser.add_option('-3', '--test-filtered-overlays', action='store_true',
588d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee            dest='test_filtered_overlays', default=False,
589d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee            help='run tests for filtered (sys prop) overlays')
590ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    return parser
591ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
592ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstadif __name__ == '__main__':
593ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    opt_parser = _create_opt_parser()
594ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    opts, args = opt_parser.parse_args(sys.argv[1:])
595d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    if not opts.test_idmap and not opts.test_no_overlay and not opts.test_single_overlay and not opts.test_multiple_overlays and not opts.test_filtered_overlays:
596ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        opts.test_idmap = True
597ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        opts.test_no_overlay = True
598ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        opts.test_single_overlay = True
599ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        opts.test_multiple_overlays = True
600d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        opts.test_filtered_overlays = True
601d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee
602ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if len(args) > 0:
603ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        opt_parser.error("unexpected arguments: %s" % " ".join(args))
604ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        # will never reach this: opt_parser.error will call sys.exit
605ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
606ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if opts.quiet_mode:
607ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        printer = QuietPrinter()
608ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    else:
609ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        printer = VerbosePrinter(opts.use_color)
610ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    tasks = []
611ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
612ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    # must be in the same directory as this script for compilation tasks to work
613ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    script = sys.argv[0]
614ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    dirname = os.path.dirname(script)
615ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    wd = os.path.realpath(dirname)
616ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    os.chdir(wd)
617ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
618ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    # build test cases
619ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if opts.do_build:
620ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(CompilationTask('OverlayTest/Android.mk'))
621ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(CompilationTask('OverlayTestOverlay/Android.mk'))
622ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(CompilationTask('OverlayAppFirst/Android.mk'))
623ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(CompilationTask('OverlayAppSecond/Android.mk'))
624d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        tasks.append(CompilationTask('OverlayAppFiltered/Android.mk'))
625ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
626ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    # remount filesystem, install test project
627ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    tasks.append(RootTask())
628ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    tasks.append(RemountTask())
62997b5df764344c32f8551483385ac4be742427580Mårten Kongstad    tasks.append(PushTask('/system/app/OverlayTest/OverlayTest.apk', '/system/app/OverlayTest.apk'))
630ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
631ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    # test idmap
632ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if opts.test_idmap:
633ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        idmaps='/data/local/tmp/idmaps'
634ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        symlinks='/data/local/tmp/symlinks'
635ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
636ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        # idmap --path
637ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StopTask())
638ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(_create_setup_idmap_path_task(idmaps, symlinks))
639ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StartTask())
640ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(IdmapPathTask('/vendor/overlay/framework_a.apk', '/system/framework/framework-res.apk', idmaps + '/a.idmap'))
641ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(FileExistsTest(idmaps + '/a.idmap'))
642ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(GrepIdmapTest(idmaps + '/a.idmap', 'bool/config_annoy_dianne', 1))
643ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
644ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        # idmap --scan
645ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StopTask())
646ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(_create_setup_idmap_scan_task(idmaps, symlinks))
647ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StartTask())
648ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(IdmapScanTask('/vendor/overlay', 'android', '/system/framework/framework-res.apk', idmaps, symlinks))
649d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        tasks.append(FileExistsTest(idmaps + '/vendor@overlay@framework_b.apk@idmap'))
650d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        tasks.append(GrepIdmapTest(idmaps + '/vendor@overlay@framework_b.apk@idmap', 'bool/config_annoy_dianne', 1))
651d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee
652ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
653ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        # overlays.list
65497b5df764344c32f8551483385ac4be742427580Mårten Kongstad        overlays_list_path = idmaps + '/overlays.list'
655ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        expected_content = '''\
65697b5df764344c32f8551483385ac4be742427580Mårten Kongstad/vendor/overlay/framework_b.apk /data/local/tmp/idmaps/vendor@overlay@framework_b.apk@idmap
657ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad'''
658ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(FileExistsTest(overlays_list_path))
659ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(Md5Test(overlays_list_path, expected_content))
660ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
661ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        # idmap cleanup
662ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(RmTask(symlinks))
663ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(RmTask(idmaps))
664ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
665d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    # test no overlay: all overlays cleared
666ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if opts.test_no_overlay:
667ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StopTask())
668ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(_create_disable_overlays_task())
669ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StartTask())
670ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(InstrumentationTask('com.android.overlaytest.WithoutOverlayTest'))
671ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
672d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    # test single overlay: one overlay (a)
673ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if opts.test_single_overlay:
674ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StopTask())
675ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(_create_enable_single_overlay_task())
676ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StartTask())
677ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(InstrumentationTask('com.android.overlaytest.WithOverlayTest'))
678ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
679d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    # test multiple overlays: all overlays - including 'disabled' filtered
680d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    # overlay (system property unset) so expect 'b[p=2]' overrides 'a[p=1]' but
681d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    # 'c[p=3]' should be ignored
682ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    if opts.test_multiple_overlays:
683ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StopTask())
684ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(_create_enable_multiple_overlays_task())
685ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(StartTask())
686ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        tasks.append(InstrumentationTask('com.android.overlaytest.WithMultipleOverlaysTest'))
687ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad
688d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    # test filtered overlays: all overlays - including 'enabled' filtered
689d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    # overlay (system property set/matched) so expect c[p=3] to override both a
690d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    # & b where applicable
691d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee    if opts.test_filtered_overlays:
692d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        tasks.append(StopTask())
693d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        tasks.append(_create_enable_filtered_overlays_task())
694d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        tasks.append(StartTask())
695d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee        tasks.append(InstrumentationTask('com.android.overlaytest.WithFilteredOverlaysTest'))
696d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee
697ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    ignored_errors = 0
698ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    for t in tasks:
699ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        type = t.get_type()
700ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        name = t.get_name()
701ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        if type == TASK_INSTRUMENTATION:
702ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            # InstrumentationTask will run several tests, but we want it
703ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            # to appear as if each test was run individually. Calling
704ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            # "am instrument" with a single test method is prohibitively
705ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            # expensive, so let's instead post-process the output to
706ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            # emulate individual calls.
707ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            retcode, stdout, stderr = t.execute()
708ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            if retcode != 0:
709ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                printer.begin(TASK_INSTRUMENTATION, name)
710ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                printer.end_fail(TASK_INSTRUMENTATION, name, stderr)
711ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                sys.exit(retcode)
712ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            retcode = _handle_instrumentation_task_output(stdout, printer)
713ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            if retcode != 0:
714ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                if not opts.do_continue:
715ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                    sys.exit(retcode)
716ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                else:
717ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                    ignored_errors += retcode
718ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad        else:
719ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            printer.begin(type, name)
720ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            retcode, stdout, stderr = t.execute()
721ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            if retcode == 0:
722ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                printer.end_pass(type, name)
723ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad            if retcode != 0:
724ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                if len(stderr) == 0:
725ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                    # hope for output from stdout instead (true for eg adb shell rm)
726ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                    stderr = stdout
727ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                printer.end_fail(type, name, stderr)
728ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                if not opts.do_continue:
729ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                    sys.exit(retcode)
730ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                else:
731ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad                    ignored_errors += retcode
732ad6ed950dbfa152c193dd7e49c369d9e831f1591Mårten Kongstad    sys.exit(ignored_errors)
733