From a7054eede1089e22274502ff51e0915ba80e887c Mon Sep 17 00:00:00 2001
From: Tao Bao <tbao@google.com>
Date: Fri, 8 Dec 2017 14:42:16 -0800
Subject: [PATCH] releasetools: Fix the tag replacement for
 ro.build.vendor.fingerprint.

For devices using derived fingerprint (i.e. /system/build.prop doesn't
contain ro.build.fingerprint, but has ro.build.thumbprint instead), the
current code (in android.os.Build) doesn't have a matching logic to do
the same for ro.vendor.build.fingerprint. This means we will see
ro.build.thumbprint in /system/build.prop, while there's no matching
ro.vendor.build.thumbprint in /vendor/build.prop.

From signing script point of view, it should just apply the tag
replacement (e.g. test-keys -> release-keys) for whatever it sees when
signing a target_files.zip.

This CL also adds unit tests for EditTags() and RewriteProps().

Fixes: 27950003
Test: Use 'sign_target_files_apks.py' to sign a target that uses derived
      fingerprint and vendor partition. Check VENDOR/build.prop.
Test: python -m unittest test_sign_target_files_apks
Change-Id: I09019da970840cd82f54b68a32b4e94984bc1d8d
---
 tools/releasetools/sign_target_files_apks.py  | 35 +++++++---
 .../test_sign_target_files_apks.py            | 67 +++++++++++++++++++
 2 files changed, 91 insertions(+), 11 deletions(-)
 create mode 100644 tools/releasetools/test_sign_target_files_apks.py

diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index f559b2912..7bfc04bfe 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -278,7 +278,7 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
       if stat.S_ISLNK(info.external_attr >> 16):
         new_data = data
       else:
-        new_data = RewriteProps(data, misc_info)
+        new_data = RewriteProps(data)
       common.ZipWriteStr(output_tf_zip, out_info, new_data)
 
     elif info.filename.endswith("mac_permissions.xml"):
@@ -385,8 +385,14 @@ def ReplaceCerts(data):
 
 
 def EditTags(tags):
-  """Given a string containing comma-separated tags, apply the edits
-  specified in OPTIONS.tag_changes and return the updated string."""
+  """Applies the edits to the tag string as specified in OPTIONS.tag_changes.
+
+  Args:
+    tags: The input string that contains comma-separated tags.
+
+  Returns:
+    The updated tags (comma-separated and sorted).
+  """
   tags = set(tags.split(","))
   for ch in OPTIONS.tag_changes:
     if ch[0] == "-":
@@ -396,20 +402,27 @@ def EditTags(tags):
   return ",".join(sorted(tags))
 
 
-def RewriteProps(data, misc_info):
+def RewriteProps(data):
+  """Rewrites the system properties in the given string.
+
+  Each property is expected in 'key=value' format. The properties that contain
+  build tags (i.e. test-keys, dev-keys) will be updated accordingly by calling
+  EditTags().
+
+  Args:
+    data: Input string, separated by newlines.
+
+  Returns:
+    The string with modified properties.
+  """
   output = []
   for line in data.split("\n"):
     line = line.strip()
     original_line = line
     if line and line[0] != '#' and "=" in line:
       key, value = line.split("=", 1)
-      if (key in ("ro.build.fingerprint", "ro.vendor.build.fingerprint")
-          and misc_info.get("oem_fingerprint_properties") is None):
-        pieces = value.split("/")
-        pieces[-1] = EditTags(pieces[-1])
-        value = "/".join(pieces)
-      elif (key in ("ro.build.thumbprint", "ro.vendor.build.thumbprint")
-            and misc_info.get("oem_fingerprint_properties") is not None):
+      if key in ("ro.build.fingerprint", "ro.build.thumbprint",
+                 "ro.vendor.build.fingerprint", "ro.vendor.build.thumbprint"):
         pieces = value.split("/")
         pieces[-1] = EditTags(pieces[-1])
         value = "/".join(pieces)
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
new file mode 100644
index 000000000..90afdc7d1
--- /dev/null
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from __future__ import print_function
+
+import unittest
+
+from sign_target_files_apks import EditTags, RewriteProps
+
+
+class SignTargetFilesApksTest(unittest.TestCase):
+
+  def test_EditTags(self):
+    self.assertEqual(EditTags('dev-keys'), ('release-keys'))
+    self.assertEqual(EditTags('test-keys'), ('release-keys'))
+
+    # Multiple tags.
+    self.assertEqual(EditTags('abc,dev-keys,xyz'), ('abc,release-keys,xyz'))
+
+    # Tags are sorted.
+    self.assertEqual(EditTags('xyz,abc,dev-keys,xyz'), ('abc,release-keys,xyz'))
+
+  def test_RewriteProps(self):
+    props = (
+        ('', '\n'),
+        ('ro.build.fingerprint=foo/bar/dev-keys',
+         'ro.build.fingerprint=foo/bar/release-keys\n'),
+        ('ro.build.thumbprint=foo/bar/dev-keys',
+         'ro.build.thumbprint=foo/bar/release-keys\n'),
+        ('ro.vendor.build.fingerprint=foo/bar/dev-keys',
+         'ro.vendor.build.fingerprint=foo/bar/release-keys\n'),
+        ('ro.vendor.build.thumbprint=foo/bar/dev-keys',
+         'ro.vendor.build.thumbprint=foo/bar/release-keys\n'),
+        ('# comment line 1', '# comment line 1\n'),
+        ('ro.bootimage.build.fingerprint=foo/bar/dev-keys',
+         'ro.bootimage.build.fingerprint=foo/bar/release-keys\n'),
+        ('ro.build.description='
+         'sailfish-user 8.0.0 OPR6.170623.012 4283428 dev-keys',
+         'ro.build.description='
+         'sailfish-user 8.0.0 OPR6.170623.012 4283428 release-keys\n'),
+        ('ro.build.tags=dev-keys', 'ro.build.tags=release-keys\n'),
+        ('# comment line 2', '# comment line 2\n'),
+        ('ro.build.display.id=OPR6.170623.012 dev-keys',
+         'ro.build.display.id=OPR6.170623.012\n'),
+        ('# comment line 3', '# comment line 3\n'),
+    )
+
+    # Assert the case for each individual line.
+    for input, output in props:
+      self.assertEqual(RewriteProps(input), output)
+
+    # Concatenate all the input lines.
+    self.assertEqual(RewriteProps('\n'.join([prop[0] for prop in props])),
+                     ''.join([prop[1] for prop in props]))