Prepare release tools for python 3

- Sort dictionaries before looping over them
- Don't call sorted() on lists with Nones
- Open file in binary format when serializing protobufs

Change-Id: If5dbc908f7125f6184014b3c1c7891f833d1d8bf
Bug: 203436762
Test: Presubmits
diff --git a/tools/releasetools/check_target_files_vintf.py b/tools/releasetools/check_target_files_vintf.py
index a2ddfe7..213ae21 100755
--- a/tools/releasetools/check_target_files_vintf.py
+++ b/tools/releasetools/check_target_files_vintf.py
@@ -132,7 +132,7 @@
       'checkvintf',
       '--check-compat',
   ]
-  for device_path, real_path in dirmap.items():
+  for device_path, real_path in sorted(dirmap.items()):
     common_command += ['--dirmap', '{}:{}'.format(device_path, real_path)]
   common_command += kernel_args
   common_command += shipping_api_level_args
@@ -165,7 +165,15 @@
   def PathToPatterns(path):
     if path[-1] == '/':
       path += '*'
-    for device_path, target_files_rel_paths in DIR_SEARCH_PATHS.items():
+
+    # Loop over all the entries in DIR_SEARCH_PATHS and find one where the key
+    # is a prefix of path. In order to get find the correct prefix, sort the
+    # entries by decreasing length of their keys, so that we check if longer
+    # strings are prefixes before shorter strings. This is so that keys that
+    # are substrings of other keys (like /system vs /system_ext) are checked
+    # later, and we don't mistakenly mark a path that starts with /system_ext
+    # as starting with only /system.
+    for device_path, target_files_rel_paths in sorted(DIR_SEARCH_PATHS.items(), key=lambda i: len(i[0]), reverse=True):
       if path.startswith(device_path):
         suffix = path[len(device_path):]
         return [rel_path + suffix for rel_path in target_files_rel_paths]
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 1937f29..1533030 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -2105,7 +2105,9 @@
   need_passwords = []
   key_passwords = {}
   devnull = open("/dev/null", "w+b")
-  for k in sorted(keylist):
+
+  # sorted() can't compare strings to None, so convert Nones to strings
+  for k in sorted(keylist, key=lambda x: x if x is not None else ""):
     # We don't need a password for things that aren't really keys.
     if k in SPECIAL_CERT_STRINGS or k is None:
       no_passwords.append(k)
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index 5737009..6c5fc05 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -154,7 +154,7 @@
                 compress_type=zipfile.ZIP_STORED)
     return
 
-  with open('{}.pb'.format(output), 'w') as f:
+  with open('{}.pb'.format(output), 'wb') as f:
     f.write(metadata_proto.SerializeToString())
   with open(output, 'w') as f:
     f.write(legacy_metadata)