1*33f37583SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*33f37583SAndroid Build Coastguard Worker# 3*33f37583SAndroid Build Coastguard Worker# Copyright (C) 2019 The Android Open Source Project 4*33f37583SAndroid Build Coastguard Worker# 5*33f37583SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*33f37583SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*33f37583SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*33f37583SAndroid Build Coastguard Worker# 9*33f37583SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*33f37583SAndroid Build Coastguard Worker# 11*33f37583SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*33f37583SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*33f37583SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*33f37583SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*33f37583SAndroid Build Coastguard Worker# limitations under the License. 16*33f37583SAndroid Build Coastguard Worker"""conv_apex_manifest converts apex_manifest.json in two ways 17*33f37583SAndroid Build Coastguard Worker 18*33f37583SAndroid Build Coastguard WorkerTo remove keys which are unknown to Q 19*33f37583SAndroid Build Coastguard Worker conv_apex_manifest strip apex_manifest.json (-o apex_manifest_stripped.json) 20*33f37583SAndroid Build Coastguard Worker 21*33f37583SAndroid Build Coastguard WorkerTo convert into .pb 22*33f37583SAndroid Build Coastguard Worker conv_apex_manifest proto apex_manifest.json -o apex_manifest.pb 23*33f37583SAndroid Build Coastguard Worker 24*33f37583SAndroid Build Coastguard WorkerTo change property value 25*33f37583SAndroid Build Coastguard Worker conv_apex_manifest setprop version 137 apex_manifest.pb 26*33f37583SAndroid Build Coastguard Worker""" 27*33f37583SAndroid Build Coastguard Worker 28*33f37583SAndroid Build Coastguard Workerimport argparse 29*33f37583SAndroid Build Coastguard Workerimport collections 30*33f37583SAndroid Build Coastguard Workerimport json 31*33f37583SAndroid Build Coastguard Worker 32*33f37583SAndroid Build Coastguard Workerimport apex_manifest_pb2 33*33f37583SAndroid Build Coastguard Workerfrom google.protobuf.descriptor import FieldDescriptor 34*33f37583SAndroid Build Coastguard Workerfrom google.protobuf.json_format import ParseDict 35*33f37583SAndroid Build Coastguard Workerfrom google.protobuf.json_format import ParseError 36*33f37583SAndroid Build Coastguard Workerfrom google.protobuf.text_format import MessageToString 37*33f37583SAndroid Build Coastguard Worker 38*33f37583SAndroid Build Coastguard WorkerQ_compat_keys = ["name", "version", "preInstallHook", "postInstallHook", "versionName"] 39*33f37583SAndroid Build Coastguard Worker 40*33f37583SAndroid Build Coastguard Workerdef Strip(args): 41*33f37583SAndroid Build Coastguard Worker with open(args.input) as f: 42*33f37583SAndroid Build Coastguard Worker obj = json.load(f, object_pairs_hook=collections.OrderedDict) 43*33f37583SAndroid Build Coastguard Worker 44*33f37583SAndroid Build Coastguard Worker # remove unknown keys 45*33f37583SAndroid Build Coastguard Worker for key in list(obj): 46*33f37583SAndroid Build Coastguard Worker if key not in Q_compat_keys: 47*33f37583SAndroid Build Coastguard Worker del obj[key] 48*33f37583SAndroid Build Coastguard Worker 49*33f37583SAndroid Build Coastguard Worker if args.out: 50*33f37583SAndroid Build Coastguard Worker with open(args.out, "w") as f: 51*33f37583SAndroid Build Coastguard Worker json.dump(obj, f, indent=2) 52*33f37583SAndroid Build Coastguard Worker else: 53*33f37583SAndroid Build Coastguard Worker print(json.dumps(obj, indent=2)) 54*33f37583SAndroid Build Coastguard Worker 55*33f37583SAndroid Build Coastguard Workerdef Proto(args): 56*33f37583SAndroid Build Coastguard Worker with open(args.input) as f: 57*33f37583SAndroid Build Coastguard Worker obj = json.load(f, object_pairs_hook=collections.OrderedDict) 58*33f37583SAndroid Build Coastguard Worker pb = ParseDict(obj, apex_manifest_pb2.ApexManifest()) 59*33f37583SAndroid Build Coastguard Worker with open(args.out, "wb") as f: 60*33f37583SAndroid Build Coastguard Worker f.write(pb.SerializeToString()) 61*33f37583SAndroid Build Coastguard Worker 62*33f37583SAndroid Build Coastguard Workerdef SetProp(args): 63*33f37583SAndroid Build Coastguard Worker with open(args.input, "rb") as f: 64*33f37583SAndroid Build Coastguard Worker pb = apex_manifest_pb2.ApexManifest() 65*33f37583SAndroid Build Coastguard Worker pb.ParseFromString(f.read()) 66*33f37583SAndroid Build Coastguard Worker 67*33f37583SAndroid Build Coastguard Worker if getattr(type(pb), args.property).DESCRIPTOR.label == FieldDescriptor.LABEL_REPEATED: 68*33f37583SAndroid Build Coastguard Worker getattr(pb, args.property)[:] = args.value.split(",") 69*33f37583SAndroid Build Coastguard Worker else: 70*33f37583SAndroid Build Coastguard Worker setattr(pb, args.property, type(getattr(pb, args.property))(args.value)) 71*33f37583SAndroid Build Coastguard Worker with open(args.input, "wb") as f: 72*33f37583SAndroid Build Coastguard Worker f.write(pb.SerializeToString()) 73*33f37583SAndroid Build Coastguard Worker 74*33f37583SAndroid Build Coastguard Workerdef Print(args): 75*33f37583SAndroid Build Coastguard Worker with open(args.input, "rb") as f: 76*33f37583SAndroid Build Coastguard Worker pb = apex_manifest_pb2.ApexManifest() 77*33f37583SAndroid Build Coastguard Worker pb.ParseFromString(f.read()) 78*33f37583SAndroid Build Coastguard Worker print(MessageToString(pb)) 79*33f37583SAndroid Build Coastguard Worker 80*33f37583SAndroid Build Coastguard Workerdef main(): 81*33f37583SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 82*33f37583SAndroid Build Coastguard Worker subparsers = parser.add_subparsers(required=True) 83*33f37583SAndroid Build Coastguard Worker 84*33f37583SAndroid Build Coastguard Worker parser_strip = subparsers.add_parser('strip', help='remove unknown keys from APEX manifest (JSON)') 85*33f37583SAndroid Build Coastguard Worker parser_strip.add_argument('input', type=str, help='APEX manifest file (JSON)') 86*33f37583SAndroid Build Coastguard Worker parser_strip.add_argument('-o', '--out', type=str, help='Output filename. If omitted, prints to stdout') 87*33f37583SAndroid Build Coastguard Worker parser_strip.set_defaults(func=Strip) 88*33f37583SAndroid Build Coastguard Worker 89*33f37583SAndroid Build Coastguard Worker parser_proto = subparsers.add_parser('proto', help='write protobuf binary format') 90*33f37583SAndroid Build Coastguard Worker parser_proto.add_argument('input', type=str, help='APEX manifest file (JSON)') 91*33f37583SAndroid Build Coastguard Worker parser_proto.add_argument('-o', '--out', required=True, type=str, help='APEX manifest file (PB)') 92*33f37583SAndroid Build Coastguard Worker parser_proto.set_defaults(func=Proto) 93*33f37583SAndroid Build Coastguard Worker 94*33f37583SAndroid Build Coastguard Worker parser_setprop = subparsers.add_parser('setprop', help='change property value') 95*33f37583SAndroid Build Coastguard Worker parser_setprop.add_argument('property', type=str, help='name of property') 96*33f37583SAndroid Build Coastguard Worker parser_setprop.add_argument('value', type=str, help='new value of property') 97*33f37583SAndroid Build Coastguard Worker parser_setprop.add_argument('input', type=str, help='APEX manifest file (PB)') 98*33f37583SAndroid Build Coastguard Worker parser_setprop.set_defaults(func=SetProp) 99*33f37583SAndroid Build Coastguard Worker 100*33f37583SAndroid Build Coastguard Worker parser_print = subparsers.add_parser('print', help='print APEX manifest') 101*33f37583SAndroid Build Coastguard Worker parser_print.add_argument('input', type=str, help='APEX manifest file (PB)') 102*33f37583SAndroid Build Coastguard Worker parser_print.set_defaults(func=Print) 103*33f37583SAndroid Build Coastguard Worker 104*33f37583SAndroid Build Coastguard Worker args = parser.parse_args() 105*33f37583SAndroid Build Coastguard Worker args.func(args) 106*33f37583SAndroid Build Coastguard Worker 107*33f37583SAndroid Build Coastguard Workerif __name__ == '__main__': 108*33f37583SAndroid Build Coastguard Worker main() 109