Merge "Remove unused shared libs from otatools."
diff --git a/core/Makefile b/core/Makefile
index 3d54cb7..2782737 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -4518,13 +4518,20 @@
 
 ifeq ($(BUILD_QEMU_IMAGES),true)
 MK_QEMU_IMAGE_SH := device/generic/goldfish/tools/mk_qemu_image.sh
+MK_COMBINE_QEMU_IMAGE_SH := device/generic/goldfish/tools/mk_combined_img.py
 SGDISK_HOST := $(HOST_OUT_EXECUTABLES)/sgdisk
 
 ifdef INSTALLED_SYSTEMIMAGE_TARGET
 INSTALLED_QEMU_SYSTEMIMAGE := $(PRODUCT_OUT)/system-qemu.img
-$(INSTALLED_QEMU_SYSTEMIMAGE): $(INSTALLED_SYSTEMIMAGE_TARGET) $(MK_QEMU_IMAGE_SH) $(SGDISK_HOST) $(SIMG2IMG)
-	@echo Create system-qemu.img
-	(export SGDISK=$(SGDISK_HOST) SIMG2IMG=$(SIMG2IMG); $(MK_QEMU_IMAGE_SH) $(INSTALLED_SYSTEMIMAGE_TARGET))
+INSTALLED_SYSTEM_QEMU_CONFIG := $(PRODUCT_OUT)/system-qemu-config.txt
+$(INSTALLED_SYSTEM_QEMU_CONFIG): $(INSTALLED_SUPERIMAGE_TARGET) $(INSTALLED_VBMETAIMAGE_TARGET)
+	@echo "$(PRODUCT_OUT)/vbmeta.img vbmeta 1" > $@
+	@echo "$(INSTALLED_SUPERIMAGE_TARGET) super 2" >> $@
+$(INSTALLED_QEMU_SYSTEMIMAGE): $(INSTALLED_VBMETAIMAGE_TARGET) $(MK_COMBINE_QEMU_IMAGE_SH) $(SGDISK_HOST) $(SIMG2IMG) \
+    $(INSTALLED_SUPERIMAGE_TARGET) $(INSTALLED_SYSTEM_QEMU_CONFIG)
+	@echo Create system-qemu.img now
+	(export SGDISK=$(SGDISK_HOST) SIMG2IMG=$(SIMG2IMG); \
+     $(MK_COMBINE_QEMU_IMAGE_SH) -i $(INSTALLED_SYSTEM_QEMU_CONFIG) -o $@)
 
 systemimage: $(INSTALLED_QEMU_SYSTEMIMAGE)
 droidcore: $(INSTALLED_QEMU_SYSTEMIMAGE)
@@ -4566,17 +4573,17 @@
 droidcore: $(INSTALLED_QEMU_ODMIMAGE)
 endif
 
-ifeq ($(BOARD_AVB_ENABLE),true)
 QEMU_VERIFIED_BOOT_PARAMS := $(PRODUCT_OUT)/VerifiedBootParams.textproto
-MK_VERIFIED_BOOT_KERNEL_CMDLINE_SH := device/generic/goldfish/tools/mk_verified_boot_params.sh
-$(QEMU_VERIFIED_BOOT_PARAMS): $(INSTALLED_QEMU_SYSTEMIMAGE) $(MK_VERIFIED_BOOT_KERNEL_CMDLINE_SH) $(INSTALLED_VBMETAIMAGE_TARGET) $(SGDISK_HOST) $(AVBTOOL)
+MK_VBMETA_BOOT_KERNEL_CMDLINE_SH := device/generic/goldfish/tools/mk_vbmeta_boot_params.sh
+$(QEMU_VERIFIED_BOOT_PARAMS): $(INSTALLED_VBMETAIMAGE_TARGET) $(INSTALLED_SYSTEMIMAGE_TARGET) \
+    $(MK_VBMETA_BOOT_KERNEL_CMDLINE_SH) $(AVBTOOL)
 	@echo Creating $@
-	(export SGDISK=$(SGDISK_HOST) AVBTOOL=$(AVBTOOL); $(MK_VERIFIED_BOOT_KERNEL_CMDLINE_SH) $(INSTALLED_VBMETAIMAGE_TARGET) $(INSTALLED_QEMU_SYSTEMIMAGE) $(QEMU_VERIFIED_BOOT_PARAMS))
-
+	(export AVBTOOL=$(AVBTOOL); $(MK_VBMETA_BOOT_KERNEL_CMDLINE_SH) $(INSTALLED_VBMETAIMAGE_TARGET) \
+    $(INSTALLED_SYSTEMIMAGE_TARGET) $(QEMU_VERIFIED_BOOT_PARAMS))
 
 systemimage: $(QEMU_VERIFIED_BOOT_PARAMS)
 droidcore: $(QEMU_VERIFIED_BOOT_PARAMS)
-endif
+
 endif
 # -----------------------------------------------------------------
 # The emulator package
diff --git a/core/definitions.mk b/core/definitions.mk
index aa2a2a9..af6248d 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2094,9 +2094,9 @@
     $(addprefix --bootclasspath ,$(strip $(PRIVATE_BOOTCLASSPATH))) \
     $(addprefix --classpath ,$(strip $(PRIVATE_ALL_JAVA_HEADER_LIBRARIES))) \
     || ( rm -rf $(dir $@)/classes-turbine ; exit 41 ) && \
-    $(MERGE_ZIPS) -j --ignore-duplicates -stripDir META-INF $@.tmp $@.premerged $(call reverse-list,$(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES)) ; \
+    $(MERGE_ZIPS) -j --ignore-duplicates -stripDir META-INF $@.tmp $@.premerged $(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES) ; \
 else \
-    $(MERGE_ZIPS) -j --ignore-duplicates -stripDir META-INF $@.tmp $(call reverse-list,$(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES)) ; \
+    $(MERGE_ZIPS) -j --ignore-duplicates -stripDir META-INF $@.tmp $(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES) ; \
 fi
 $(hide) $(ZIPTIME) $@.tmp
 $(hide) $(call commit-change-for-toc,$@)
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index 1545f63..423575c 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -141,7 +141,7 @@
             $(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf)
 	$(MERGE_ZIPS) -j --ignore-duplicates $(if $(PRIVATE_JAR_MANIFEST),-m $(dir $@)/manifest.mf) \
             $(if $(PRIVATE_DONT_DELETE_JAR_META_INF),,-stripDir META-INF -zipToNotStrip $<) \
-            $@ $< $(call reverse-list,$(PRIVATE_STATIC_JAVA_LIBRARIES))
+            $@ $< $(PRIVATE_STATIC_JAVA_LIBRARIES)
 
 # Run jarjar if necessary, otherwise just copy the file.
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index f7bf337..1225fa9 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -103,7 +103,7 @@
             $(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf)
 	$(MERGE_ZIPS) -j --ignore-duplicates $(if $(PRIVATE_JAR_MANIFEST),-m $(dir $@)/manifest.mf) \
             $(if $(PRIVATE_DONT_DELETE_JAR_META_INF),,-stripDir META-INF -zipToNotStrip $<) \
-            $@ $< $(call reverse-list,$(PRIVATE_STATIC_JAVA_LIBRARIES))
+            $@ $< $(PRIVATE_STATIC_JAVA_LIBRARIES)
 
 # Run jarjar if necessary, otherwise just copy the file.
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
diff --git a/core/java.mk b/core/java.mk
index afc77d6..b951f14 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -309,7 +309,7 @@
             $(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf)
 	$(MERGE_ZIPS) -j --ignore-duplicates $(if $(PRIVATE_JAR_MANIFEST),-m $(dir $@)/manifest.mf) \
             $(if $(PRIVATE_DONT_DELETE_JAR_META_INF),,-stripDir META-INF -zipToNotStrip $<) \
-            $@ $< $(call reverse-list,$(PRIVATE_STATIC_JAVA_LIBRARIES))
+            $@ $< $(PRIVATE_STATIC_JAVA_LIBRARIES)
 
 ifdef LOCAL_JAR_PROCESSOR
 # LOCAL_JAR_PROCESSOR_ARGS must be evaluated here to set up the rule-local
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index 8153d78..d873cc4 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -129,7 +129,15 @@
 my_2nd_arch_prefix :=
 
 PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
-ifdef LOCAL_CERTIFICATE
+ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
+  # The magic string "PRESIGNED" means this package is already checked
+  # signed with its release key.
+  #
+  # By setting .CERTIFICATE but not .PRIVATE_KEY, this package will be
+  # mentioned in apkcerts.txt (with certificate set to "PRESIGNED")
+  # but the dexpreopt process will not try to re-sign the app.
+  PACKAGES.$(LOCAL_MODULE).CERTIFICATE := PRESIGNED
+else ifneq ($(LOCAL_CERTIFICATE),)
   PACKAGES.$(LOCAL_MODULE).CERTIFICATE := $(LOCAL_CERTIFICATE)
   PACKAGES.$(LOCAL_MODULE).PRIVATE_KEY := $(patsubst %.x509.pem,%.pk8,$(LOCAL_CERTIFICATE))
 endif
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 19326dd..48db6b1 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -58,6 +58,16 @@
 $(call add_json_str,  DeviceSecondaryCpuVariant,         $(TARGET_2ND_CPU_VARIANT))
 $(call add_json_list, DeviceSecondaryAbi,                $(TARGET_2ND_CPU_ABI) $(TARGET_2ND_CPU_ABI2))
 
+$(call add_json_str,  NativeBridgeArch,                  $(TARGET_NATIVE_BRIDGE_ARCH))
+$(call add_json_str,  NativeBridgeArchVariant,           $(TARGET_NATIVE_BRIDGE_ARCH_VARIANT))
+$(call add_json_str,  NativeBridgeCpuVariant,            $(TARGET_NATIVE_BRIDGE_CPU_VARIANT))
+$(call add_json_list, NativeBridgeAbi,                   $(TARGET_NATIVE_BRIDGE_ABI))
+
+$(call add_json_str,  NativeBridgeSecondaryArch,         $(TARGET_NATIVE_BRIDGE_2ND_ARCH))
+$(call add_json_str,  NativeBridgeSecondaryArchVariant,  $(TARGET_NATIVE_BRIDGE_2ND_ARCH_VARIANT))
+$(call add_json_str,  NativeBridgeSecondaryCpuVariant,   $(TARGET_NATIVE_BRIDGE_2ND_CPU_VARIANT))
+$(call add_json_list, NativeBridgeSecondaryAbi,          $(TARGET_NATIVE_BRIDGE_2ND_ABI))
+
 $(call add_json_str,  HostArch,                          $(HOST_ARCH))
 $(call add_json_str,  HostSecondaryArch,                 $(HOST_2ND_ARCH))
 $(call add_json_bool, HostStaticBinaries,                $(BUILD_HOST_static))
diff --git a/envsetup.sh b/envsetup.sh
index 9e381a2..5292d38 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -22,7 +22,7 @@
 - jgrep:      Greps on all local Java files.
 - resgrep:    Greps on all local res/*.xml files.
 - mangrep:    Greps on all local AndroidManifest.xml files.
-- mgrep:      Greps on all local Makefiles files.
+- mgrep:      Greps on all local Makefiles and *.bp files.
 - sepgrep:    Greps on all local sepolicy files.
 - sgrep:      Greps on all local source files.
 - godir:      Go to the directory containing a file.
diff --git a/target/board/BoardConfigEmuCommon.mk b/target/board/BoardConfigEmuCommon.mk
index 9ec71d0..3ab5f12 100644
--- a/target/board/BoardConfigEmuCommon.mk
+++ b/target/board/BoardConfigEmuCommon.mk
@@ -23,15 +23,35 @@
 # Emulator doesn't support sparse image format.
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
 
-# ~140 MB vendor image. Please adjust system image / vendor image sizes
-# when finalizing them. The partition size needs to be a multiple of image
-# block size: 4096.
-BOARD_VENDORIMAGE_PARTITION_SIZE := 146800640
+ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
+  # emulator is Non-A/B device
+  AB_OTA_UPDATER := false
+
+  # emulator needs super.img
+  BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
+
+  BOARD_EXT4_SHARE_DUP_BLOCKS := true
+
+  # 3G + header
+  BOARD_SUPER_PARTITION_SIZE := 3229614080
+  BOARD_SUPER_PARTITION_GROUPS := emulator_dynamic_partitions
+  BOARD_EMULATOR_DYNAMIC_PARTITIONS_PARTITION_LIST := \
+      system \
+      vendor
+
+  # 3G
+  BOARD_EMULATOR_DYNAMIC_PARTITIONS_SIZE := 3221225472
+else ifeq ($(PRODUCT_USE_DYNAMIC_PARTITION_SIZE),true)
+  # Enable dynamic system image size and reserved 64MB in it.
+  BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE := 67108864
+  BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE := 67108864
+else
+  BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3221225472
+  BOARD_VENDORIMAGE_PARTITION_SIZE := 146800640
+endif
+
 BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
 
 BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/common
-
-# TODO(b/125540538): Remove when emulator uses dynamic partitions
-BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index b61a7fd..8624ed7 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -29,8 +29,8 @@
 TARGET_CPU_ABI := armeabi-v7a
 TARGET_CPU_ABI2 := armeabi
 
-include build/make/target/board/BoardConfigEmuCommon.mk
 include build/make/target/board/BoardConfigGsiCommon.mk
+include build/make/target/board/BoardConfigEmuCommon.mk
 
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
 
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 7d92b7d..ecc547f 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -52,8 +52,8 @@
 TARGET_2ND_CPU_VARIANT := generic
 endif
 
-include build/make/target/board/BoardConfigEmuCommon.mk
 include build/make/target/board/BoardConfigGsiCommon.mk
+include build/make/target/board/BoardConfigEmuCommon.mk
 
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
 
diff --git a/target/board/generic_x86/BoardConfig.mk b/target/board/generic_x86/BoardConfig.mk
index 650073e..83d7ecc 100644
--- a/target/board/generic_x86/BoardConfig.mk
+++ b/target/board/generic_x86/BoardConfig.mk
@@ -20,8 +20,8 @@
 
 TARGET_PRELINK_MODULE := false
 
-include build/make/target/board/BoardConfigEmuCommon.mk
 include build/make/target/board/BoardConfigGsiCommon.mk
+include build/make/target/board/BoardConfigEmuCommon.mk
 
 # Resize to 4G to accomodate ASAN and CTS
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 4294967296
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index 1426630..07bbc07 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -23,9 +23,8 @@
 TARGET_2ND_ARCH_VARIANT := x86_64
 
 TARGET_PRELINK_MODULE := false
-
-include build/make/target/board/BoardConfigEmuCommon.mk
 include build/make/target/board/BoardConfigGsiCommon.mk
+include build/make/target/board/BoardConfigEmuCommon.mk
 
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
 
diff --git a/target/board/generic_x86_arm/BoardConfig.mk b/target/board/generic_x86_arm/BoardConfig.mk
index ab2089d..6fae411 100644
--- a/target/board/generic_x86_arm/BoardConfig.mk
+++ b/target/board/generic_x86_arm/BoardConfig.mk
@@ -30,8 +30,8 @@
 BUILD_BROKEN_DUP_RULES := true
 
 
-include build/make/target/board/BoardConfigEmuCommon.mk
 include build/make/target/board/BoardConfigGsiCommon.mk
+include build/make/target/board/BoardConfigEmuCommon.mk
 
 # Resize to 4G to accomodate ASAN and CTS
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 4294967296
diff --git a/target/product/aosp_arm.mk b/target/product/aosp_arm.mk
index 400fa6a..0fdd313 100644
--- a/target/product/aosp_arm.mk
+++ b/target/product/aosp_arm.mk
@@ -14,6 +14,8 @@
 # limitations under the License.
 #
 
+PRODUCT_USE_DYNAMIC_PARTITIONS := true
+
 # The system image of aosp_arm-userdebug is a GSI for the devices with:
 # - ARM 32 bits user space
 # - 64 bits binder interface
diff --git a/target/product/aosp_arm64.mk b/target/product/aosp_arm64.mk
index aa6ec4d..8ef2023 100644
--- a/target/product/aosp_arm64.mk
+++ b/target/product/aosp_arm64.mk
@@ -14,6 +14,8 @@
 # limitations under the License.
 #
 
+PRODUCT_USE_DYNAMIC_PARTITIONS := true
+
 # The system image of aosp_arm64-userdebug is a GSI for the devices with:
 # - ARM 64 bits user space
 # - 64 bits binder interface
diff --git a/target/product/aosp_x86.mk b/target/product/aosp_x86.mk
index b16b5ed..1c71948 100644
--- a/target/product/aosp_x86.mk
+++ b/target/product/aosp_x86.mk
@@ -14,6 +14,8 @@
 # limitations under the License.
 #
 
+PRODUCT_USE_DYNAMIC_PARTITIONS := true
+
 # The system image of aosp_x86-userdebug is a GSI for the devices with:
 # - x86 32 bits user space
 # - 64 bits binder interface
diff --git a/target/product/aosp_x86_64.mk b/target/product/aosp_x86_64.mk
index f7e2056..9dfa2f4 100644
--- a/target/product/aosp_x86_64.mk
+++ b/target/product/aosp_x86_64.mk
@@ -14,6 +14,8 @@
 # limitations under the License.
 #
 
+PRODUCT_USE_DYNAMIC_PARTITIONS := true
+
 # The system image of aosp_x86_64-userdebug is a GSI for the devices with:
 # - x86 64 bits user space
 # - 64 bits binder interface
diff --git a/target/product/aosp_x86_arm.mk b/target/product/aosp_x86_arm.mk
index b921c97..70aa64e 100644
--- a/target/product/aosp_x86_arm.mk
+++ b/target/product/aosp_x86_arm.mk
@@ -14,6 +14,7 @@
 # limitations under the License.
 #
 
+PRODUCT_USE_DYNAMIC_PARTITIONS := true
 
 # aosp_x86 with arm libraries needed by binary translation.
 
@@ -31,13 +32,6 @@
 # Enable dynamic partition size
 PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
 
-# Enable A/B update
-AB_OTA_UPDATER := true
-AB_OTA_PARTITIONS := system
-PRODUCT_PACKAGES += \
-    update_engine \
-    update_verifier
-
 # Needed by Pi newly launched device to pass VtsTrebleSysProp on GSI
 PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true
 
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 7b5f000..d25ae0c 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -558,6 +558,13 @@
     # System properties.
     elif filename in ("SYSTEM/build.prop",
                       "VENDOR/build.prop",
+                      "SYSTEM/vendor/build.prop",
+                      "ODM/build.prop",
+                      "VENDOR/odm/build.prop",
+                      "PRODUCT/build.prop",
+                      "SYSTEM/product/build.prop",
+                      "PRODUCT_SERVICES/build.prop",
+                      "SYSTEM/product_services/build.prop",
                       "SYSTEM/etc/prop.default",
                       "BOOT/RAMDISK/prop.default",
                       "BOOT/RAMDISK/default.prop",  # legacy
@@ -752,8 +759,8 @@
     original_line = line
     if line and line[0] != '#' and "=" in line:
       key, value = line.split("=", 1)
-      if key in ("ro.build.fingerprint", "ro.build.thumbprint",
-                 "ro.vendor.build.fingerprint", "ro.vendor.build.thumbprint"):
+      if (key.startswith("ro.") and
+          key.endswith((".build.fingerprint", ".build.thumbprint"))):
         pieces = value.split("/")
         pieces[-1] = EditTags(pieces[-1])
         value = "/".join(pieces)
@@ -766,7 +773,7 @@
         assert len(pieces) == 5
         pieces[-1] = EditTags(pieces[-1])
         value = " ".join(pieces)
-      elif key == "ro.build.tags":
+      elif key.startswith("ro.") and key.endswith(".build.tags"):
         value = EditTags(value)
       elif key == "ro.build.display.id":
         # change, eg, "JWR66N dev-keys" to "JWR66N"
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index a7bf977..e142ebb 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -53,36 +53,60 @@
 
   def test_RewriteProps(self):
     props = (
-        ('', '\n'),
+        ('', ''),
         ('ro.build.fingerprint=foo/bar/dev-keys',
-         'ro.build.fingerprint=foo/bar/release-keys\n'),
+         'ro.build.fingerprint=foo/bar/release-keys'),
         ('ro.build.thumbprint=foo/bar/dev-keys',
-         'ro.build.thumbprint=foo/bar/release-keys\n'),
+         'ro.build.thumbprint=foo/bar/release-keys'),
         ('ro.vendor.build.fingerprint=foo/bar/dev-keys',
-         'ro.vendor.build.fingerprint=foo/bar/release-keys\n'),
+         'ro.vendor.build.fingerprint=foo/bar/release-keys'),
         ('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.vendor.build.thumbprint=foo/bar/release-keys'),
+        ('ro.odm.build.fingerprint=foo/bar/test-keys',
+         'ro.odm.build.fingerprint=foo/bar/release-keys'),
+        ('ro.odm.build.thumbprint=foo/bar/test-keys',
+         'ro.odm.build.thumbprint=foo/bar/release-keys'),
+        ('ro.product.build.fingerprint=foo/bar/dev-keys',
+         'ro.product.build.fingerprint=foo/bar/release-keys'),
+        ('ro.product.build.thumbprint=foo/bar/dev-keys',
+         'ro.product.build.thumbprint=foo/bar/release-keys'),
+        ('ro.product_services.build.fingerprint=foo/bar/test-keys',
+         'ro.product_services.build.fingerprint=foo/bar/release-keys'),
+        ('ro.product_services.build.thumbprint=foo/bar/test-keys',
+         'ro.product_services.build.thumbprint=foo/bar/release-keys'),
+        ('# comment line 1', '# comment line 1'),
         ('ro.bootimage.build.fingerprint=foo/bar/dev-keys',
-         'ro.bootimage.build.fingerprint=foo/bar/release-keys\n'),
+         'ro.bootimage.build.fingerprint=foo/bar/release-keys'),
         ('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'),
+         'sailfish-user 8.0.0 OPR6.170623.012 4283428 release-keys'),
+        ('ro.build.tags=dev-keys', 'ro.build.tags=release-keys'),
+        ('ro.build.tags=test-keys', 'ro.build.tags=release-keys'),
+        ('ro.system.build.tags=dev-keys',
+         'ro.system.build.tags=release-keys'),
+        ('ro.vendor.build.tags=dev-keys',
+         'ro.vendor.build.tags=release-keys'),
+        ('ro.odm.build.tags=dev-keys',
+         'ro.odm.build.tags=release-keys'),
+        ('ro.product.build.tags=dev-keys',
+         'ro.product.build.tags=release-keys'),
+        ('ro.product_services.build.tags=dev-keys',
+         'ro.product_services.build.tags=release-keys'),
+        ('# comment line 2', '# comment line 2'),
         ('ro.build.display.id=OPR6.170623.012 dev-keys',
-         'ro.build.display.id=OPR6.170623.012\n'),
-        ('# comment line 3', '# comment line 3\n'),
+         'ro.build.display.id=OPR6.170623.012'),
+        ('# comment line 3', '# comment line 3'),
     )
 
     # Assert the case for each individual line.
-    for prop, output in props:
-      self.assertEqual(RewriteProps(prop), output)
+    for prop, expected in props:
+      self.assertEqual(expected + '\n', RewriteProps(prop))
 
     # Concatenate all the input lines.
-    self.assertEqual(RewriteProps('\n'.join([prop[0] for prop in props])),
-                     ''.join([prop[1] for prop in props]))
+    self.assertEqual(
+        '\n'.join([prop[1] for prop in props]) + '\n',
+        RewriteProps('\n'.join([prop[0] for prop in props])))
 
   def test_ReplaceVerityKeyId(self):
     BOOT_CMDLINE1 = (