Merge "aconfig: add flag type in flag table and remove info byte from value array" into main
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 098ed27..6a101da9 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -70,7 +70,7 @@
     com.android.scheduling \
     com.android.sdkext \
     com.android.tethering \
-    com.android.tzdata \
+    $(RELEASE_PACKAGE_TZDATA_MODULE) \
     com.android.uwb \
     com.android.virt \
     com.android.wifi \
diff --git a/tools/aconfig/src/storage/flag_table.rs b/tools/aconfig/src/storage/flag_table.rs
index 5cfe3a5..595217e 100644
--- a/tools/aconfig/src/storage/flag_table.rs
+++ b/tools/aconfig/src/storage/flag_table.rs
@@ -106,8 +106,6 @@
 
 impl FlagTable {
     fn create_nodes(package: &FlagPackage, num_buckets: u32) -> Result<Vec<FlagTableNode>> {
-        let flag_names = package.boolean_flags.iter().map(|pf| pf.name()).collect::<Vec<_>>();
-        println!("{:?}", flag_names);
         let flag_ids =
             assign_flag_ids(package.package_name, package.boolean_flags.iter().copied())?;
         package
diff --git a/tools/metadata/generator.go b/tools/metadata/generator.go
index d328876..b7668be 100644
--- a/tools/metadata/generator.go
+++ b/tools/metadata/generator.go
@@ -77,9 +77,18 @@
 	return string(data)
 }
 
-func writeNewlineToOutputFile(outputFile string) {
+func writeEmptyOutputProto(outputFile string, metadataRule string) {
 	file, err := os.Create(outputFile)
-	data := "\n"
+	if err != nil {
+		log.Fatal(err)
+	}
+	var message proto.Message
+	if metadataRule == "test_spec" {
+		message = &test_spec_proto.TestSpec{}
+	} else if metadataRule == "code_metadata" {
+		message = &code_metadata_proto.CodeMetadata{}
+	}
+	data, err := proto.Marshal(message)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -92,8 +101,8 @@
 }
 
 func processTestSpecProtobuf(
-		filePath string, ownershipMetadataMap *sync.Map, keyLocks *keyToLocksMap,
-		errCh chan error, wg *sync.WaitGroup,
+	filePath string, ownershipMetadataMap *sync.Map, keyLocks *keyToLocksMap,
+	errCh chan error, wg *sync.WaitGroup,
 ) {
 	defer wg.Done()
 
@@ -121,7 +130,7 @@
 				if metadata.GetTrendyTeamId() != existing.GetTrendyTeamId() {
 					errCh <- fmt.Errorf(
 						"Conflicting trendy team IDs found for %s at:\n%s with teamId"+
-								": %s,\n%s with teamId: %s",
+							": %s,\n%s with teamId: %s",
 						key,
 						metadata.GetPath(), metadata.GetTrendyTeamId(), existing.GetPath(),
 						existing.GetTrendyTeamId(),
@@ -147,8 +156,8 @@
 
 // processCodeMetadataProtobuf processes CodeMetadata protobuf files
 func processCodeMetadataProtobuf(
-		filePath string, ownershipMetadataMap *sync.Map, sourceFileMetadataMap *sync.Map, keyLocks *keyToLocksMap,
-		errCh chan error, wg *sync.WaitGroup,
+	filePath string, ownershipMetadataMap *sync.Map, sourceFileMetadataMap *sync.Map, keyLocks *keyToLocksMap,
+	errCh chan error, wg *sync.WaitGroup,
 ) {
 	defer wg.Done()
 
@@ -182,8 +191,8 @@
 				if attributes.TeamID != existing.TeamID && (!attributes.MultiOwnership || !existing.MultiOwnership) {
 					errCh <- fmt.Errorf(
 						"Conflict found for source file %s covered at %s with team ID: %s. Existing team ID: %s and path: %s."+
-								" If multi-ownership is required, multiOwnership should be set to true in all test_spec modules using this target. "+
-								"Multiple-ownership in general is discouraged though as it make infrastructure around android relying on this information pick up a random value when it needs only one.",
+							" If multi-ownership is required, multiOwnership should be set to true in all test_spec modules using this target. "+
+							"Multiple-ownership in general is discouraged though as it make infrastructure around android relying on this information pick up a random value when it needs only one.",
 						srcFile, internalMetadata.GetPath(), attributes.TeamID, existing.TeamID, existing.Path,
 					)
 					srcFileLock.Unlock()
@@ -235,7 +244,7 @@
 	inputFileData := strings.TrimRight(readFileToString(*inputFile), "\n")
 	filePaths := strings.Split(inputFileData, " ")
 	if len(filePaths) == 1 && filePaths[0] == "" {
-		writeNewlineToOutputFile(*outputFile)
+		writeEmptyOutputProto(*outputFile, *rule)
 		return
 	}
 	ownershipMetadataMap := &sync.Map{}
diff --git a/tools/metadata/testdata/generatedEmptyOutputFile.txt b/tools/metadata/testdata/generatedEmptyOutputFile.txt
index 8b13789..e69de29 100644
--- a/tools/metadata/testdata/generatedEmptyOutputFile.txt
+++ b/tools/metadata/testdata/generatedEmptyOutputFile.txt
@@ -1 +0,0 @@
-
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index b65764b..29042a5 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -259,6 +259,9 @@
 
   --vabc_cow_version
       Specify the VABC cow version to be used
+
+  --compression_factor
+      Specify the maximum block size to be compressed at once during OTA. supported options: 4k, 8k, 16k, 32k, 64k, 128k
 """
 
 from __future__ import print_function
@@ -331,6 +334,7 @@
 OPTIONS.security_patch_level = None
 OPTIONS.max_threads = None
 OPTIONS.vabc_cow_version = None
+OPTIONS.compression_factor = None
 
 
 POSTINSTALL_CONFIG = 'META/postinstall_config.txt'
@@ -393,17 +397,6 @@
   """
   return ModifyKeyvalueList(content, "virtual_ab_compression_method", algo)
 
-def SetVABCCowVersion(content, cow_version):
-  """ Update virtual_ab_cow_version in dynamic_partitions_info.txt
-  Args:
-    content: The string content of dynamic_partitions_info.txt
-    algo: The cow version be used for VABC. See
-          https://cs.android.com/android/platform/superproject/main/+/main:system/core/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h;l=36
-  Returns:
-    Updated content of dynamic_partitions_info.txt , updated cow version
-  """
-  return ModifyKeyvalueList(content, "virtual_ab_cow_version", cow_version)
-
 
 def UpdatesInfoForSpecialUpdates(content, partitions_filter,
                                  delete_keys=None):
@@ -1020,6 +1013,8 @@
         target_file, vabc_compression_param)
   if OPTIONS.vabc_cow_version:
     target_file = ModifyTargetFilesDynamicPartitionInfo(target_file, "virtual_ab_cow_version", OPTIONS.vabc_cow_version)
+  if OPTIONS.compression_factor:
+    target_file = ModifyTargetFilesDynamicPartitionInfo(target_file, "virtual_ab_compression_factor", OPTIONS.compression_factor)
   if OPTIONS.skip_postinstall:
     target_file = GetTargetFilesZipWithoutPostinstallConfig(target_file)
   # Target_file may have been modified, reparse ab_partitions
@@ -1280,6 +1275,13 @@
       else:
         raise ValueError("Cannot parse value %r for option %r - only "
                          "integers are allowed." % (a, o))
+    elif o in ("--compression_factor"):
+        values = ["4k", "8k", "16k", "32k", "64k", "128k"]
+        if a[:-1].isdigit() and a in values and a.endswith("k"):
+            OPTIONS.compression_factor = str(int(a[:-1]) * 1024)
+        else:
+            raise ValueError("Please specify value from following options: 4k, 8k, 16k, 32k, 64k, 128k")
+
     elif o == "--vabc_cow_version":
       if a.isdigit():
         OPTIONS.vabc_cow_version = a
@@ -1335,6 +1337,7 @@
                                  "security_patch_level=",
                                  "max_threads=",
                                  "vabc_cow_version=",
+                                 "compression_factor=",
                              ], extra_option_handler=[option_handler, payload_signer.signer_options])
   common.InitLogging()