1 #!/usr/bin/env python 2 # 3 # Copyright (C) 2009 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 import sys 18 19 # Usage: post_process_props.py file.prop [blacklist_key, ...] 20 # Blacklisted keys are removed from the property file, if present 21 22 # See PROP_NAME_MAX and PROP_VALUE_MAX system_properties.h. 23 # The constants in system_properties.h includes the termination NUL, 24 # so we decrease the values by 1 here. 25 PROP_NAME_MAX = 31 26 PROP_VALUE_MAX = 91 27 28 # Put the modifications that you need to make into the /system/build.prop into this 29 # function. The prop object has get(name) and put(name,value) methods. 30 def mangle_build_prop(prop): 31 pass 32 33 # Put the modifications that you need to make into the /default.prop into this 34 # function. The prop object has get(name) and put(name,value) methods. 35 def mangle_default_prop(prop): 36 # If ro.debuggable is 1, then enable adb on USB by default 37 # (this is for userdebug builds) 38 if prop.get("ro.debuggable") == "1": 39 val = prop.get("persist.sys.usb.config") 40 if val == "": 41 val = "adb" 42 else: 43 val = val + ",adb" 44 prop.put("persist.sys.usb.config", val) 45 # UsbDeviceManager expects a value here. If it doesn't get it, it will 46 # default to "adb". That might not the right policy there, but it's better 47 # to be explicit. 48 if not prop.get("persist.sys.usb.config"): 49 prop.put("persist.sys.usb.config", "none"); 50 51 def validate(prop): 52 """Validate the properties. 53 54 Returns: 55 True if nothing is wrong. 56 """ 57 check_pass = True 58 buildprops = prop.to_dict() 59 dev_build = buildprops.get("ro.build.version.incremental", 60 "").startswith("eng") 61 for key, value in buildprops.iteritems(): 62 # Check build properties' length. 63 if len(key) > PROP_NAME_MAX: 64 check_pass = False 65 sys.stderr.write("error: %s cannot exceed %d bytes: " % 66 (key, PROP_NAME_MAX)) 67 sys.stderr.write("%s (%d)\n" % (key, len(key))) 68 if len(value) > PROP_VALUE_MAX: 69 # If dev build, show a warning message, otherwise fail the 70 # build with error message 71 if dev_build: 72 sys.stderr.write("warning: %s exceeds %d bytes: " % 73 (key, PROP_VALUE_MAX)) 74 sys.stderr.write("%s (%d)\n" % (value, len(value))) 75 sys.stderr.write("warning: This will cause the %s " % key) 76 sys.stderr.write("property return as empty at runtime\n") 77 else: 78 check_pass = False 79 sys.stderr.write("error: %s cannot exceed %d bytes: " % 80 (key, PROP_VALUE_MAX)) 81 sys.stderr.write("%s (%d)\n" % (value, len(value))) 82 return check_pass 83 84 class PropFile: 85 86 def __init__(self, lines): 87 self.lines = [s.strip() for s in lines] 88 89 def to_dict(self): 90 props = {} 91 for line in self.lines: 92 if not line or line.startswith("#"): 93 continue 94 if "=" in line: 95 key, value = line.split("=", 1) 96 props[key] = value 97 return props 98 99 def get(self, name): 100 key = name + "=" 101 for line in self.lines: 102 if line.startswith(key): 103 return line[len(key):] 104 return "" 105 106 def put(self, name, value): 107 key = name + "=" 108 for i in range(0,len(self.lines)): 109 if self.lines[i].startswith(key): 110 self.lines[i] = key + value 111 return 112 self.lines.append(key + value) 113 114 def delete(self, name): 115 key = name + "=" 116 self.lines = [ line for line in self.lines if not line.startswith(key) ] 117 118 def write(self, f): 119 f.write("\n".join(self.lines)) 120 f.write("\n") 121 122 def main(argv): 123 filename = argv[1] 124 f = open(filename) 125 lines = f.readlines() 126 f.close() 127 128 properties = PropFile(lines) 129 130 if filename.endswith("/build.prop"): 131 mangle_build_prop(properties) 132 elif filename.endswith("/default.prop"): 133 mangle_default_prop(properties) 134 else: 135 sys.stderr.write("bad command line: " + str(argv) + "\n") 136 sys.exit(1) 137 138 if not validate(properties): 139 sys.exit(1) 140 141 # Drop any blacklisted keys 142 for key in argv[2:]: 143 properties.delete(key) 144 145 f = open(filename, 'w+') 146 properties.write(f) 147 f.close() 148 149 if __name__ == "__main__": 150 main(sys.argv) 151