Merge changes from topic "productmanifest" into qt-dev

* changes:
  ota_from_target_files: include metadata when odm / product is changed.
  Add product manifest.
diff --git a/core/Makefile b/core/Makefile
index 2aee70b..6acd6e9 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -2035,14 +2035,19 @@
 
 $(INSTALLED_DEBUG_RAMDISK_TARGET): DEBUG_RAMDISK_SYNC_DIR := $(my_debug_ramdisk_sync_dir)
 $(INSTALLED_DEBUG_RAMDISK_TARGET): DEBUG_RAMDISK_ROOT_DIR := $(my_debug_ramdisk_root_dir)
-# We should have just depended on ramdisk.img or ramdisk-recovery.img.
-# But ramdisk-recovery.img is not a make target, so let's depend on the boot.img directly.
+
+ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+# ramdisk-recovery.img isn't a make target, need to depend on boot.img if it's for recovery.
 $(INSTALLED_DEBUG_RAMDISK_TARGET): $(INSTALLED_BOOTIMAGE_TARGET)
+else
+# Depends on ramdisk.img, note that some target has ramdisk.img but no boot.img, e.g., emulator.
+$(INSTALLED_DEBUG_RAMDISK_TARGET): $(INSTALLED_RAMDISK_TARGET)
+endif # BOARD_USES_RECOVERY_AS_BOOT
 $(INSTALLED_DEBUG_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_DEBUG_RAMDISK_FILES) | $(MINIGZIP)
 	$(call pretty,"Target debug ram disk: $@")
 	mkdir -p $(TARGET_DEBUG_RAMDISK_OUT)
 	touch $(TARGET_DEBUG_RAMDISK_OUT)/force_debuggable
-	rsync -a $(DEBUG_RAMDISK_SYNC_DIR)/* $(DEBUG_RAMDISK_ROOT_DIR)
+	rsync -a $(DEBUG_RAMDISK_SYNC_DIR)/ $(DEBUG_RAMDISK_ROOT_DIR)
 	$(MKBOOTFS) -d $(TARGET_OUT) $(DEBUG_RAMDISK_ROOT_DIR) | $(MINIGZIP) > $@
 
 .PHONY: ramdisk_debug-nodeps
@@ -2052,7 +2057,7 @@
 	echo "make $@: ignoring dependencies"
 	mkdir -p $(TARGET_DEBUG_RAMDISK_OUT)
 	touch $(TARGET_DEBUG_RAMDISK_OUT)/force_debuggable
-	rsync -a $(DEBUG_RAMDISK_SYNC_DIR)/* $(DEBUG_RAMDISK_ROOT_DIR)
+	rsync -a $(DEBUG_RAMDISK_SYNC_DIR)/ $(DEBUG_RAMDISK_ROOT_DIR)
 	$(MKBOOTFS) -d $(TARGET_OUT) $(DEBUG_RAMDISK_ROOT_DIR) | $(MINIGZIP) > $(INSTALLED_DEBUG_RAMDISK_TARGET)
 
 my_debug_ramdisk_sync_dir :=
diff --git a/target/board/gsi_system.prop b/target/board/gsi_system.prop
index d768c83..780aadc 100644
--- a/target/board/gsi_system.prop
+++ b/target/board/gsi_system.prop
@@ -4,6 +4,9 @@
 # GSI always disables adb authentication
 ro.adb.secure=0
 
+# GSI disables non-AOSP nnapi extensions on product partition
+ro.nnapi.extensions.deny_on_product=true
+
 # TODO(b/120679683): disable RescueParty before all problem apps solved
 persist.sys.disable_rescue=true
 
diff --git a/target/board/gsi_system_user.prop b/target/board/gsi_system_user.prop
index becb783..217bd01 100644
--- a/target/board/gsi_system_user.prop
+++ b/target/board/gsi_system_user.prop
@@ -1,6 +1,9 @@
 # GSI always generate dex pre-opt in system image
 ro.cp_system_other_odex=0
 
+# GSI disables non-AOSP nnapi extensions on product partition
+ro.nnapi.extensions.deny_on_product=true
+
 # TODO(b/120679683): disable RescueParty before all problem apps solved
 persist.sys.disable_rescue=true
 
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index f05a27d..c2acd8e 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -1074,13 +1074,16 @@
     # full names only.
     container_cert = matches.group("CONTAINER_CERT")
     container_private_key = matches.group("CONTAINER_PRIVATE_KEY")
-    if not CompareKeys(
+    if container_cert == 'PRESIGNED' and container_private_key == 'PRESIGNED':
+      container_key = 'PRESIGNED'
+    elif CompareKeys(
         container_cert, OPTIONS.public_key_suffix,
         container_private_key, OPTIONS.private_key_suffix):
+      container_key = container_cert[:-len(OPTIONS.public_key_suffix)]
+    else:
       raise ValueError("Failed to parse container keys: \n{}".format(line))
 
-    keys[name] = (payload_private_key,
-                  container_cert[:-len(OPTIONS.public_key_suffix)])
+    keys[name] = (payload_private_key, container_key)
 
   return keys
 
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 6a4df1a..a4d51cf 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -461,3 +461,26 @@
             'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
             'build/target/product/security/testkey'),
         }, keys_info)
+
+  def test_ReadApexKeysInfo_presignedKeys(self):
+    apex_keys = self.APEX_KEYS_TXT + (
+        'name="apex.apexd_test_different_app2.apex" '
+        'private_key="PRESIGNED" '
+        'public_key="PRESIGNED" '
+        'container_certificate="PRESIGNED" '
+        'container_private_key="PRESIGNED"')
+    target_files = common.MakeTempFile(suffix='.zip')
+    with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+      target_files_zip.writestr('META/apexkeys.txt', apex_keys)
+
+    with zipfile.ZipFile(target_files) as target_files_zip:
+      keys_info = ReadApexKeysInfo(target_files_zip)
+
+    self.assertEqual({
+        'apex.apexd_test.apex': (
+            'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
+            'build/make/target/product/security/testkey'),
+        'apex.apexd_test_different_app.apex': (
+            'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
+            'build/make/target/product/security/testkey'),
+        }, keys_info)