• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#
3# Copyright (C) 2019 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"""conv_apex_manifest converts apex_manifest.json in two ways
17
18To remove keys which are unknown to Q
19  conv_apex_manifest strip apex_manifest.json (-o apex_manifest_stripped.json)
20
21To convert into .pb
22  conv_apex_manifest proto apex_manifest.json -o apex_manifest.pb
23
24To change property value
25  conv_apex_manifest setprop version 137 apex_manifest.pb
26"""
27
28import argparse
29import collections
30import json
31
32import apex_manifest_pb2
33from google.protobuf.descriptor import FieldDescriptor
34from google.protobuf.json_format import ParseDict
35from google.protobuf.json_format import ParseError
36from google.protobuf.text_format import MessageToString
37
38Q_compat_keys = ["name", "version", "preInstallHook", "postInstallHook", "versionName"]
39
40def Strip(args):
41  with open(args.input) as f:
42      obj = json.load(f, object_pairs_hook=collections.OrderedDict)
43
44  # remove unknown keys
45  for key in list(obj):
46    if key not in Q_compat_keys:
47      del obj[key]
48
49  if args.out:
50    with open(args.out, "w") as f:
51      json.dump(obj, f, indent=2)
52  else:
53    print(json.dumps(obj, indent=2))
54
55def Proto(args):
56  with open(args.input) as f:
57    obj = json.load(f, object_pairs_hook=collections.OrderedDict)
58  pb = ParseDict(obj, apex_manifest_pb2.ApexManifest())
59  with open(args.out, "wb") as f:
60    f.write(pb.SerializeToString())
61
62def SetProp(args):
63  with open(args.input, "rb") as f:
64    pb = apex_manifest_pb2.ApexManifest()
65    pb.ParseFromString(f.read())
66
67  if getattr(type(pb), args.property).DESCRIPTOR.label == FieldDescriptor.LABEL_REPEATED:
68    getattr(pb, args.property)[:] = args.value.split(",")
69  else:
70    setattr(pb, args.property, type(getattr(pb, args.property))(args.value))
71  with open(args.input, "wb") as f:
72    f.write(pb.SerializeToString())
73
74def Print(args):
75  with open(args.input, "rb") as f:
76    pb = apex_manifest_pb2.ApexManifest()
77    pb.ParseFromString(f.read())
78  print(MessageToString(pb))
79
80def main():
81  parser = argparse.ArgumentParser()
82  subparsers = parser.add_subparsers()
83
84  parser_strip = subparsers.add_parser('strip', help='remove unknown keys from APEX manifest (JSON)')
85  parser_strip.add_argument('input', type=str, help='APEX manifest file (JSON)')
86  parser_strip.add_argument('-o', '--out', type=str, help='Output filename. If omitted, prints to stdout')
87  parser_strip.set_defaults(func=Strip)
88
89  parser_proto = subparsers.add_parser('proto', help='write protobuf binary format')
90  parser_proto.add_argument('input', type=str, help='APEX manifest file (JSON)')
91  parser_proto.add_argument('-o', '--out', required=True, type=str, help='Directory to extract content of APEX to')
92  parser_proto.set_defaults(func=Proto)
93
94  parser_proto = subparsers.add_parser('setprop', help='change proprety value')
95  parser_proto.add_argument('property', type=str, help='name of property')
96  parser_proto.add_argument('value', type=str, help='new value of property')
97  parser_proto.add_argument('input', type=str, help='APEX manifest file (PB)')
98  parser_proto.set_defaults(func=SetProp)
99
100  parser_proto = subparsers.add_parser('print', help='print APEX manifest')
101  parser_proto.add_argument('input', type=str, help='APEX manifest file (PB)')
102  parser_proto.set_defaults(func=Print)
103
104  args = parser.parse_args()
105  args.func(args)
106
107if __name__ == '__main__':
108  main()
109