summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'analyze_matrix/dump_hals_for_release.py')
-rwxr-xr-xanalyze_matrix/dump_hals_for_release.py110
1 files changed, 110 insertions, 0 deletions
diff --git a/analyze_matrix/dump_hals_for_release.py b/analyze_matrix/dump_hals_for_release.py
new file mode 100755
index 0000000..47519c6
--- /dev/null
+++ b/analyze_matrix/dump_hals_for_release.py
@@ -0,0 +1,110 @@
1#!/usr/bin/env python
2#
3# Copyright (C) 2018 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"""
19Dump new HIDL types that are introduced in each FCM version.
20"""
21
22from __future__ import print_function
23
24import argparse
25import collections
26import json
27import os
28import subprocess
29import sys
30
31class Globals:
32 pass
33
34def call(args):
35 if Globals.verbose:
36 print(' '.join(args), file=sys.stderr)
37 sp = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
38 out, err = sp.communicate()
39 return sp.returncode, out.decode(), err.decode()
40
41def check_call(args):
42 r, o, e = call(args)
43 assert not r, '`{}` returns {}'.format(' '.join(args), r)
44 return o, e
45
46def lines(o):
47 return filter(lambda line: line, (line.strip() for line in o.split()))
48
49def to_level(s):
50 if s == 'legacy': return 0
51 if s == '': return float('inf')
52 return int(s)
53
54def main():
55 parser = argparse.ArgumentParser(description=__doc__)
56 parser.add_argument('--verbose', help='Verbose mode', action='store_true')
57 parser.add_argument('--pretty', help='Print pretty JSON', action='store_true')
58 parser.add_argument('--hidl-gen', help='Location of hidl-gen', required=True)
59 parser.add_argument('--analyze-matrix', help='Location of analyze_matrix', required=True)
60 parser.add_argument('--compatibility-matrix', metavar='FILE',
61 help='Location of framework compatibility matrices', nargs='+', required=True)
62 parser.add_argument('--package-root', metavar='PACKAGE:PATH',
63 help='package roots provided to hidl-gen, e.g. android.hardware:hardware/interfaces',
64 nargs='+')
65 parser.parse_args(namespace=Globals)
66
67 interfaces_for_level = dict()
68 for matrix_path in Globals.compatibility_matrix:
69 r, o, _ = call([Globals.analyze_matrix, '--input', matrix_path, '--level'])
70 if r:
71 # Not a compatibility matrix, ignore
72 continue
73 # stderr may contain warning message if level is empty
74 level = o.strip()
75
76 o, _ = check_call([Globals.analyze_matrix, '--input', matrix_path, '--interfaces'])
77 # stderr may contain warning message if no interfaces
78
79 interfaces = list(lines(o))
80 if not interfaces: continue
81
82 if level not in interfaces_for_level:
83 interfaces_for_level[level] = set()
84
85 # Put top level interfaces
86 interfaces_for_level[level].update(interfaces)
87
88 # Put interfaces referenced by top level interfaces
89 args = [Globals.hidl_gen, '-Ldependencies']
90 if Globals.package_root:
91 args.append('-R')
92 for package_root in Globals.package_root:
93 args.extend(['-r', package_root])
94 args.extend(interfaces)
95 o, e = check_call(args)
96 assert not e, '`{}` has written to stderr:\n{}'.format(' '.join(args), e)
97 interfaces_for_level[level].update(lines(o))
98
99 seen_interfaces = set()
100 new_interfaces_for_level = collections.OrderedDict()
101 for level, interfaces in sorted(interfaces_for_level.items(), key=lambda tup: to_level(tup[0])):
102 new_interfaces_for_level[level] = sorted(interfaces - seen_interfaces)
103 seen_interfaces.update(interfaces)
104
105 print(json.dumps(new_interfaces_for_level,
106 separators=None if Globals.pretty else (',',':'),
107 indent=4 if Globals.pretty else None))
108
109if __name__ == '__main__':
110 main()