19197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato#!/usr/bin/env python
29197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato#
39197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# Copyright (C) 2009 The Android Open Source Project
49197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato#
59197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# Licensed under the Apache License, Version 2.0 (the "License");
69197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# you may not use this file except in compliance with the License.
79197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# You may obtain a copy of the License at
89197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato#
99197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato#      http://www.apache.org/licenses/LICENSE-2.0
109197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato#
119197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# Unless required by applicable law or agreed to in writing, software
129197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# distributed under the License is distributed on an "AS IS" BASIS,
139197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# See the License for the specific language governing permissions and
159197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# limitations under the License.
169197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
179197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onoratoimport sys
189197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
1926d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey# Usage: post_process_props.py file.prop [blacklist_key, ...]
2026d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey# Blacklisted keys are removed from the property file, if present
2126d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey
22dad2ab4df403125873940d50c80f2db8217b4916Brian Carlstrom# See PROP_NAME_MAX and PROP_VALUE_MAX system_properties.h.
23dad2ab4df403125873940d50c80f2db8217b4916Brian Carlstrom# The constants in system_properties.h includes the termination NUL,
24dad2ab4df403125873940d50c80f2db8217b4916Brian Carlstrom# so we decrease the values by 1 here.
25dad2ab4df403125873940d50c80f2db8217b4916Brian CarlstromPROP_NAME_MAX = 31
26351232107e9cc94802c9d1a122c21cd69e36e284Ying WangPROP_VALUE_MAX = 91
27351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang
289197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# Put the modifications that you need to make into the /system/build.prop into this
299197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# function. The prop object has get(name) and put(name,value) methods.
309197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onoratodef mangle_build_prop(prop):
31351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  pass
329197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
33351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang# Put the modifications that you need to make into the /default.prop into this
349197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato# function. The prop object has get(name) and put(name,value) methods.
359197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onoratodef mangle_default_prop(prop):
369197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  # If ro.debuggable is 1, then enable adb on USB by default
379197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  # (this is for userdebug builds)
389197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  if prop.get("ro.debuggable") == "1":
399197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    val = prop.get("persist.sys.usb.config")
40420e341a361372e6e7c121da0f667b093fa90d4fOreste Salerno    if "adb" not in val:
41420e341a361372e6e7c121da0f667b093fa90d4fOreste Salerno      if val == "":
42420e341a361372e6e7c121da0f667b093fa90d4fOreste Salerno        val = "adb"
43420e341a361372e6e7c121da0f667b093fa90d4fOreste Salerno      else:
44420e341a361372e6e7c121da0f667b093fa90d4fOreste Salerno        val = val + ",adb"
45420e341a361372e6e7c121da0f667b093fa90d4fOreste Salerno      prop.put("persist.sys.usb.config", val)
468ad4bb16a0d8b8ff9b4d17e860db336111bef34dJoe Onorato  # UsbDeviceManager expects a value here.  If it doesn't get it, it will
478ad4bb16a0d8b8ff9b4d17e860db336111bef34dJoe Onorato  # default to "adb". That might not the right policy there, but it's better
488ad4bb16a0d8b8ff9b4d17e860db336111bef34dJoe Onorato  # to be explicit.
498ad4bb16a0d8b8ff9b4d17e860db336111bef34dJoe Onorato  if not prop.get("persist.sys.usb.config"):
508ad4bb16a0d8b8ff9b4d17e860db336111bef34dJoe Onorato    prop.put("persist.sys.usb.config", "none");
519197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
52351232107e9cc94802c9d1a122c21cd69e36e284Ying Wangdef validate(prop):
53351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  """Validate the properties.
54351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang
55351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  Returns:
56351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang    True if nothing is wrong.
57351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  """
58351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  check_pass = True
59351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  buildprops = prop.to_dict()
60351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  for key, value in buildprops.iteritems():
61351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang    # Check build properties' length.
62dad2ab4df403125873940d50c80f2db8217b4916Brian Carlstrom    if len(key) > PROP_NAME_MAX:
63dad2ab4df403125873940d50c80f2db8217b4916Brian Carlstrom      check_pass = False
64dad2ab4df403125873940d50c80f2db8217b4916Brian Carlstrom      sys.stderr.write("error: %s cannot exceed %d bytes: " %
65dad2ab4df403125873940d50c80f2db8217b4916Brian Carlstrom                       (key, PROP_NAME_MAX))
66dad2ab4df403125873940d50c80f2db8217b4916Brian Carlstrom      sys.stderr.write("%s (%d)\n" % (key, len(key)))
67351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang    if len(value) > PROP_VALUE_MAX:
6838df101343137c3a4c1954803a52a4ea35c7f42fYing Wang      check_pass = False
6938df101343137c3a4c1954803a52a4ea35c7f42fYing Wang      sys.stderr.write("error: %s cannot exceed %d bytes: " %
7038df101343137c3a4c1954803a52a4ea35c7f42fYing Wang                       (key, PROP_VALUE_MAX))
7138df101343137c3a4c1954803a52a4ea35c7f42fYing Wang      sys.stderr.write("%s (%d)\n" % (value, len(value)))
72351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  return check_pass
73115c66bd741c6caa7d3078615b81f5e7a5041c9bYu Liu
74351232107e9cc94802c9d1a122c21cd69e36e284Ying Wangclass PropFile:
75115c66bd741c6caa7d3078615b81f5e7a5041c9bYu Liu
769197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  def __init__(self, lines):
77351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang    self.lines = [s.strip() for s in lines]
78351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang
79351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  def to_dict(self):
80351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang    props = {}
81115c66bd741c6caa7d3078615b81f5e7a5041c9bYu Liu    for line in self.lines:
82351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang      if not line or line.startswith("#"):
83115c66bd741c6caa7d3078615b81f5e7a5041c9bYu Liu        continue
845a7ad0338bf027e6398bff411c826b24f4faf358Ying Wang      if "=" in line:
855a7ad0338bf027e6398bff411c826b24f4faf358Ying Wang        key, value = line.split("=", 1)
865a7ad0338bf027e6398bff411c826b24f4faf358Ying Wang        props[key] = value
87351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang    return props
889197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
899197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  def get(self, name):
909197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    key = name + "="
919197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    for line in self.lines:
929197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato      if line.startswith(key):
939197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato        return line[len(key):]
949197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    return ""
959197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
969197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  def put(self, name, value):
979197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    key = name + "="
989197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    for i in range(0,len(self.lines)):
999197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato      if self.lines[i].startswith(key):
1009197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato        self.lines[i] = key + value
1019197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato        return
1029197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    self.lines.append(key + value)
1039197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
10426d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey  def delete(self, name):
10526d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey    key = name + "="
10626d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey    self.lines = [ line for line in self.lines if not line.startswith(key) ]
10726d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey
1089197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  def write(self, f):
1099197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    f.write("\n".join(self.lines))
1109197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    f.write("\n")
1119197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
1129197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onoratodef main(argv):
1139197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  filename = argv[1]
1149197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  f = open(filename)
1159197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  lines = f.readlines()
1169197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  f.close()
1179197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
1189197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  properties = PropFile(lines)
119351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang
1209197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  if filename.endswith("/build.prop"):
1219197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    mangle_build_prop(properties)
1229197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  elif filename.endswith("/default.prop"):
1239197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    mangle_default_prop(properties)
1249197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  else:
1259197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    sys.stderr.write("bad command line: " + str(argv) + "\n")
1269197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato    sys.exit(1)
1279197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
128351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang  if not validate(properties):
129351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang    sys.exit(1)
130351232107e9cc94802c9d1a122c21cd69e36e284Ying Wang
13126d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey  # Drop any blacklisted keys
13226d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey  for key in argv[2:]:
13326d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey    properties.delete(key)
13426d22f713948dfc5292268b7307de7a3b9e22e4dJeff Sharkey
1355b65ee497492c278ee8bd9a92a846363e81a155bMike Lockwood  f = open(filename, 'w+')
1365b65ee497492c278ee8bd9a92a846363e81a155bMike Lockwood  properties.write(f)
1379197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  f.close()
1389197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato
1399197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onoratoif __name__ == "__main__":
1409197a487b4a30bcbc6ef41471ca5aa03440dca1fJoe Onorato  main(sys.argv)
141