change OTA tools to handle variable dev keys

The signing and OTA-building tools now understand the
default_sys_dev_certificate value which may be present in the
META/misc_info.txt file of the target-files packages.

Change-Id: I64f09ec0b77a5184b6ddb74019255518776ee773
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index 4264efa..0a27a19 100755
--- a/tools/releasetools/ota_from_target_files
+++ b/tools/releasetools/ota_from_target_files
@@ -24,9 +24,14 @@
   -b  (--board_config)  <file>
       Deprecated.
 
-  -k  (--package_key)  <key>
-      Key to use to sign the package (default is
-      "build/target/product/security/testkey").
+  -k (--package_key) <key> Key to use to sign the package (default is
+      the value of default_system_dev_certificate from the input
+      target-files's META/misc_info.txt, or
+      "build/target/product/security/testkey" if that value is not
+      specified).
+
+      For incremental OTAs, the default value is based on the source
+      target-file, not the target build.
 
   -i  (--incremental_from)  <file>
       Generate an incremental OTA using the given target-files zip as
@@ -72,7 +77,7 @@
 import edify_generator
 
 OPTIONS = common.OPTIONS
-OPTIONS.package_key = "build/target/product/security/testkey"
+OPTIONS.package_key = None
 OPTIONS.incremental_source = None
 OPTIONS.require_verbatim = set()
 OPTIONS.prohibit_verbatim = set(("system/build.prop",))
@@ -794,30 +799,34 @@
     OPTIONS.device_specific = os.path.normpath(OPTIONS.device_specific)
     print "using device-specific extensions in", OPTIONS.device_specific
 
-  if OPTIONS.package_key:
-    temp_zip_file = tempfile.NamedTemporaryFile()
-    output_zip = zipfile.ZipFile(temp_zip_file, "w",
-                                 compression=zipfile.ZIP_DEFLATED)
-  else:
-    output_zip = zipfile.ZipFile(args[1], "w",
-                                 compression=zipfile.ZIP_DEFLATED)
+  temp_zip_file = tempfile.NamedTemporaryFile()
+  output_zip = zipfile.ZipFile(temp_zip_file, "w",
+                               compression=zipfile.ZIP_DEFLATED)
 
   if OPTIONS.incremental_source is None:
     WriteFullOTAPackage(input_zip, output_zip)
+    if OPTIONS.package_key is None:
+      OPTIONS.package_key = OPTIONS.info_dict.get(
+          "default_system_dev_certificate",
+          "build/target/product/security/testkey")
   else:
     print "unzipping source target-files..."
     OPTIONS.source_tmp, source_zip = common.UnzipTemp(OPTIONS.incremental_source)
     OPTIONS.target_info_dict = OPTIONS.info_dict
     OPTIONS.source_info_dict = common.LoadInfoDict(source_zip)
+    if OPTIONS.package_key is None:
+      OPTIONS.package_key = OPTIONS.source_info_dict.get(
+          "default_system_dev_certificate",
+          "build/target/product/security/testkey")
     if OPTIONS.verbose:
       print "--- source info ---"
       common.DumpInfoDict(OPTIONS.source_info_dict)
     WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
 
   output_zip.close()
-  if OPTIONS.package_key:
-    SignOutput(temp_zip_file.name, args[1])
-    temp_zip_file.close()
+
+  SignOutput(temp_zip_file.name, args[1])
+  temp_zip_file.close()
 
   common.Cleanup()
 
diff --git a/tools/releasetools/sign_target_files_apks b/tools/releasetools/sign_target_files_apks
index 5353063..bc88ef8 100755
--- a/tools/releasetools/sign_target_files_apks
+++ b/tools/releasetools/sign_target_files_apks
@@ -36,10 +36,16 @@
   -d  (--default_key_mappings)  <dir>
       Set up the following key mappings:
 
-        build/target/product/security/testkey   ==>  $dir/releasekey
-        build/target/product/security/media     ==>  $dir/media
-        build/target/product/security/shared    ==>  $dir/shared
-        build/target/product/security/platform  ==>  $dir/platform
+        $devkey/devkey    ==>  $dir/releasekey
+        $devkey/testkey   ==>  $dir/releasekey
+        $devkey/media     ==>  $dir/media
+        $devkey/shared    ==>  $dir/shared
+        $devkey/platform  ==>  $dir/platform
+
+      where $devkey is the directory part of the value of
+      default_system_dev_certificate from the input target-files's
+      META/misc_info.txt.  (Defaulting to "build/target/product/security"
+      if the value is not present in misc_info.
 
       -d and -k options are added to the set of mappings in the order
       in which they appear on the command line.
@@ -55,7 +61,7 @@
       the last component of the build fingerprint).  Prefix each with
       '+' or '-' to indicate whether that tag should be added or
       removed.  Changes are processed in the order they appear.
-      Default value is "-test-keys,+release-keys".
+      Default value is "-test-keys,-dev-keys,+release-keys".
 
 """
 
@@ -80,7 +86,7 @@
 OPTIONS.extra_apks = {}
 OPTIONS.key_map = {}
 OPTIONS.replace_ota_keys = False
-OPTIONS.tag_changes = ("-test-keys", "+release-keys")
+OPTIONS.tag_changes = ("-test-keys", "-dev-keys", "+release-keys")
 
 def GetApkCerts(tf_zip):
   certmap = common.ReadApkCerts(tf_zip)
@@ -198,14 +204,12 @@
   return "\n".join(output) + "\n"
 
 
-def ReplaceOtaKeys(input_tf_zip, output_tf_zip):
+def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info):
   try:
     keylist = input_tf_zip.read("META/otakeys.txt").split()
   except KeyError:
     raise ExternalError("can't read META/otakeys.txt from input")
 
-  misc_info = common.LoadInfoDict(input_tf_zip)
-
   extra_recovery_keys = misc_info.get("extra_recovery_keys", None)
   if extra_recovery_keys:
     extra_recovery_keys = [OPTIONS.key_map.get(k, k) + ".x509.pem"
@@ -227,10 +231,10 @@
     print "using:\n   ", "\n   ".join(mapped_keys)
     print "for OTA package verification"
   else:
+    devkey = misc_info.get("default_system_dev_certificate",
+                           "build/target/product/security/testkey")
     mapped_keys.append(
-        OPTIONS.key_map.get("build/target/product/security/testkey",
-                            "build/target/product/security/testkey")
-        + ".x509.pem")
+        OPTIONS.key_map.get(devkey, devkey) + ".x509.pem")
     print "META/otakeys.txt has no keys; using", mapped_keys[0]
 
   # recovery uses a version of the key that has been slightly
@@ -259,8 +263,28 @@
                      tempfile.getvalue())
 
 
+def BuildKeyMap(misc_info, key_mapping_options):
+  for s, d in key_mapping_options:
+    if s is None:   # -d option
+      devkey = misc_info.get("default_system_dev_certificate",
+                             "build/target/product/security/testkey")
+      devkeydir = os.path.dirname(devkey)
+
+      OPTIONS.key_map.update({
+          devkeydir + "/testkey":  d + "/releasekey",
+          devkeydir + "/devkey":   d + "/releasekey",
+          devkeydir + "/media":    d + "/media",
+          devkeydir + "/shared":   d + "/shared",
+          devkeydir + "/platform": d + "/platform",
+          })
+    else:
+      OPTIONS.key_map[s] = d
+
+
 def main(argv):
 
+  key_mapping_options = []
+
   def option_handler(o, a):
     if o in ("-e", "--extra_apks"):
       names, key = a.split("=")
@@ -268,15 +292,9 @@
       for n in names:
         OPTIONS.extra_apks[n] = key
     elif o in ("-d", "--default_key_mappings"):
-      OPTIONS.key_map.update({
-          "build/target/product/security/testkey": "%s/releasekey" % (a,),
-          "build/target/product/security/media": "%s/media" % (a,),
-          "build/target/product/security/shared": "%s/shared" % (a,),
-          "build/target/product/security/platform": "%s/platform" % (a,),
-          })
+      key_mapping_options.append((None, a))
     elif o in ("-k", "--key_mapping"):
-      s, d = a.split("=")
-      OPTIONS.key_map[s] = d
+      key_mapping_options.append(a.split("=", 1))
     elif o in ("-o", "--replace_ota_keys"):
       OPTIONS.replace_ota_keys = True
     elif o in ("-t", "--tag_changes"):
@@ -307,6 +325,10 @@
   input_zip = zipfile.ZipFile(args[0], "r")
   output_zip = zipfile.ZipFile(args[1], "w")
 
+  misc_info = common.LoadInfoDict(input_zip)
+
+  BuildKeyMap(misc_info, key_mapping_options)
+
   apk_key_map = GetApkCerts(input_zip)
   CheckAllApksSigned(input_zip, apk_key_map)