blob: 4fa15bcd618b9c083abca65aa7d54596863e1179 [file] [log] [blame]
Jiyong Parkae556382020-05-20 18:33:43 +09001#!/usr/bin/env python3
Joe Onorato9197a482011-06-08 16:04:14 -07002#
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
17import sys
18
Jeff Sharkey26d22f72014-03-18 17:20:10 -070019# Usage: post_process_props.py file.prop [blacklist_key, ...]
20# Blacklisted keys are removed from the property file, if present
21
Elliott Hughes05c1a2a2017-02-28 10:04:23 -080022# See PROP_VALUE_MAX in system_properties.h.
23# The constant in system_properties.h includes the terminating NUL,
24# so we decrease the value by 1 here.
Ying Wang35123212014-02-11 20:44:09 -080025PROP_VALUE_MAX = 91
26
Jiyong Parkae556382020-05-20 18:33:43 +090027# Put the modifications that you need to make into the */build.prop into this
28# function.
29def mangle_build_prop(prop_list):
Jerry Zhang16956532016-10-18 00:01:27 +000030 # If ro.debuggable is 1, then enable adb on USB by default
31 # (this is for userdebug builds)
Jiyong Parkae556382020-05-20 18:33:43 +090032 if prop_list.get("ro.debuggable") == "1":
33 val = prop_list.get("persist.sys.usb.config")
Jerry Zhang16956532016-10-18 00:01:27 +000034 if "adb" not in val:
35 if val == "":
36 val = "adb"
37 else:
38 val = val + ",adb"
Jiyong Parkae556382020-05-20 18:33:43 +090039 prop_list.put("persist.sys.usb.config", val)
Joe Onorato8ad4bb12012-05-02 14:36:57 -070040 # UsbDeviceManager expects a value here. If it doesn't get it, it will
41 # default to "adb". That might not the right policy there, but it's better
42 # to be explicit.
Jiyong Parkae556382020-05-20 18:33:43 +090043 if not prop_list.get("persist.sys.usb.config"):
44 prop_list.put("persist.sys.usb.config", "none");
Joe Onorato9197a482011-06-08 16:04:14 -070045
Jiyong Parkae556382020-05-20 18:33:43 +090046def validate(prop_list):
Ying Wang35123212014-02-11 20:44:09 -080047 """Validate the properties.
48
49 Returns:
50 True if nothing is wrong.
51 """
52 check_pass = True
Jiyong Parkae556382020-05-20 18:33:43 +090053 for p in prop_list.get_all():
54 if len(p.value) > PROP_VALUE_MAX and not p.name.startswith("ro."):
Ying Wang38df1012015-02-04 15:10:59 -080055 check_pass = False
56 sys.stderr.write("error: %s cannot exceed %d bytes: " %
Jiyong Parkae556382020-05-20 18:33:43 +090057 (p.name, PROP_VALUE_MAX))
58 sys.stderr.write("%s (%d)\n" % (p.value, len(p.value)))
Ying Wang35123212014-02-11 20:44:09 -080059 return check_pass
60
Jiyong Parkae556382020-05-20 18:33:43 +090061class Prop:
Yu Liu115c66b2014-02-10 19:20:36 -080062
Jiyong Parkae556382020-05-20 18:33:43 +090063 def __init__(self, name, value, comment=None):
64 self.name = name.strip()
65 self.value = value.strip()
66 self.comment = comment
Ying Wang35123212014-02-11 20:44:09 -080067
Jiyong Parkae556382020-05-20 18:33:43 +090068 @staticmethod
69 def from_line(line):
70 line = line.rstrip('\n')
71 if line.startswith("#"):
72 return Prop("", "", line)
73 elif "=" in line:
74 name, value = line.split("=", 1)
75 return Prop(name, value)
76 else:
77 # don't fail on invalid line
78 # TODO(jiyong) make this a hard error
79 return Prop("", "", line)
80
81 def is_comment(self):
82 return self.comment != None
83
84 def __str__(self):
85 if self.is_comment():
86 return self.comment
87 else:
88 return self.name + "=" + self.value
89
90class PropList:
91
92 def __init__(self, filename):
93 with open(filename) as f:
94 self.props = [Prop.from_line(l)
95 for l in f.readlines() if l.strip() != ""]
96
97 def get_all(self):
98 return [p for p in self.props if not p.is_comment()]
Joe Onorato9197a482011-06-08 16:04:14 -070099
100 def get(self, name):
Jiyong Parkae556382020-05-20 18:33:43 +0900101 return next((p.value for p in self.props if p.name == name), "")
Joe Onorato9197a482011-06-08 16:04:14 -0700102
103 def put(self, name, value):
Jiyong Parkae556382020-05-20 18:33:43 +0900104 index = next((i for i,p in enumerate(self.props) if p.name == name), -1)
105 if index == -1:
106 self.props.append(Prop(name, value))
107 else:
108 self.props[index].value = value
Joe Onorato9197a482011-06-08 16:04:14 -0700109
Jeff Sharkey26d22f72014-03-18 17:20:10 -0700110 def delete(self, name):
Jiyong Parkcc49c6b2020-05-26 03:30:02 +0900111 index = next((i for i,p in enumerate(self.props) if p.name == name), -1)
112 if index != -1:
113 new_comment = "# removed by post_process_props.py\n#" + str(self.props[index])
114 self.props[index] = Prop.from_line(new_comment)
Jeff Sharkey26d22f72014-03-18 17:20:10 -0700115
Jiyong Parkae556382020-05-20 18:33:43 +0900116 def write(self, filename):
117 with open(filename, 'w+') as f:
118 for p in self.props:
119 f.write(str(p) + "\n")
Joe Onorato9197a482011-06-08 16:04:14 -0700120
121def main(argv):
122 filename = argv[1]
Joe Onorato9197a482011-06-08 16:04:14 -0700123
Jiyong Parkae556382020-05-20 18:33:43 +0900124 if not filename.endswith("/build.prop"):
Joe Onorato9197a482011-06-08 16:04:14 -0700125 sys.stderr.write("bad command line: " + str(argv) + "\n")
126 sys.exit(1)
127
Jiyong Parkae556382020-05-20 18:33:43 +0900128 props = PropList(filename)
129 mangle_build_prop(props)
130 if not validate(props):
Ying Wang35123212014-02-11 20:44:09 -0800131 sys.exit(1)
132
Jeff Sharkey26d22f72014-03-18 17:20:10 -0700133 # Drop any blacklisted keys
134 for key in argv[2:]:
Jiyong Parkae556382020-05-20 18:33:43 +0900135 props.delete(key)
Jeff Sharkey26d22f72014-03-18 17:20:10 -0700136
Jiyong Parkae556382020-05-20 18:33:43 +0900137 props.write(filename)
Joe Onorato9197a482011-06-08 16:04:14 -0700138
139if __name__ == "__main__":
140 main(sys.argv)