Merge "Include TARGET_RELEASE in soong metrics" into main
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e1a9582..c123d03 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -7090,6 +7090,34 @@
 	`)
 }
 
+func TestApexValidation_UsesProperPartitionTag(t *testing.T) {
+	t.Parallel()
+	ctx := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			updatable: false,
+			vendor: true,
+		}
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+	`, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+		// vendor path should not affect "partition tag"
+		variables.VendorPath = proptools.StringPtr("system/vendor")
+	}))
+
+	module := ctx.ModuleForTests("myapex", "android_common_myapex")
+	android.AssertStringEquals(t, "partition tag for host_apex_verifier",
+		"vendor",
+		module.Output("host_apex_verifier.timestamp").Args["partition_tag"])
+	android.AssertStringEquals(t, "partition tag for apex_sepolicy_tests",
+		"vendor",
+		module.Output("apex_sepolicy_tests.timestamp").Args["partition_tag"])
+}
+
 func TestApexValidation_TestApexCanSkipInitRcCheck(t *testing.T) {
 	t.Parallel()
 	ctx := testApex(t, `
diff --git a/apex/builder.go b/apex/builder.go
index d9348c5..daba6f1 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -1202,6 +1202,22 @@
 	return timestamp
 }
 
+// Can't use PartitionTag() because PartitionTag() returns the partition this module is actually
+// installed (e.g. PartitionTag() may return "system" for vendor apex when vendor is linked to /system/vendor)
+func (a *apexBundle) partition() string {
+	if a.SocSpecific() {
+		return "vendor"
+	} else if a.DeviceSpecific() {
+		return "odm"
+	} else if a.ProductSpecific() {
+		return "product"
+	} else if a.SystemExtSpecific() {
+		return "system_ext"
+	} else {
+		return "system"
+	}
+}
+
 // Runs apex_sepolicy_tests
 //
 // $ apex-ls -Z {apex_file} > {file_contexts}
@@ -1213,7 +1229,7 @@
 		Input:  apexFile,
 		Output: timestamp,
 		Args: map[string]string{
-			"partition_tag": a.PartitionTag(ctx.DeviceConfig()),
+			"partition_tag": a.partition(),
 		},
 	})
 	return timestamp
@@ -1240,7 +1256,7 @@
 		Input:  apexFile,
 		Output: timestamp,
 		Args: map[string]string{
-			"partition_tag": a.PartitionTag(ctx.DeviceConfig()),
+			"partition_tag": a.partition(),
 		},
 	})
 	return timestamp
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 98a56d7..83cac74 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -225,11 +225,17 @@
 	}
 }
 
+// Helper structs for target_files.zip creation
 type targetFilesZipCopy struct {
 	srcModule  *string
 	destSubdir string
 }
 
+type targetFilesystemZipCopy struct {
+	fsInfo     FilesystemInfo
+	destSubdir string
+}
+
 func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) {
 	targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir")
 	targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip")
@@ -256,25 +262,45 @@
 		toCopy = append(toCopy, targetFilesZipCopy{a.partitionProps.Recovery_partition_name, "VENDOR_BOOT/RAMDISK"})
 	}
 
+	filesystemsToCopy := []targetFilesystemZipCopy{}
 	for _, zipCopy := range toCopy {
 		if zipCopy.srcModule == nil {
 			continue
 		}
-		fsInfo := a.getFilesystemInfo(ctx, *zipCopy.srcModule)
-		subdir := zipCopy.destSubdir
-		rootDirString := fsInfo.RootDir.String()
-		if subdir == "SYSTEM" {
+		filesystemsToCopy = append(
+			filesystemsToCopy,
+			targetFilesystemZipCopy{a.getFilesystemInfo(ctx, *zipCopy.srcModule), zipCopy.destSubdir},
+		)
+	}
+	// Get additional filesystems from super_partition dependency
+	if a.partitionProps.Super_partition_name != nil {
+		superPartition := ctx.GetDirectDepWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag)
+		if info, ok := android.OtherModuleProvider(ctx, superPartition, SuperImageProvider); ok {
+			for _, partition := range android.SortedStringKeys(info.SubImageInfo) {
+				filesystemsToCopy = append(
+					filesystemsToCopy,
+					targetFilesystemZipCopy{info.SubImageInfo[partition], strings.ToUpper(partition)},
+				)
+			}
+		} else {
+			ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name())
+		}
+	}
+
+	for _, toCopy := range filesystemsToCopy {
+		rootDirString := toCopy.fsInfo.RootDir.String()
+		if toCopy.destSubdir == "SYSTEM" {
 			rootDirString = rootDirString + "/system"
 		}
-		builder.Command().Textf("mkdir -p %s/%s", targetFilesDir.String(), subdir)
+		builder.Command().Textf("mkdir -p %s/%s", targetFilesDir.String(), toCopy.destSubdir)
 		builder.Command().
 			BuiltTool("acp").
-			Textf("-rd %s/. %s/%s", rootDirString, targetFilesDir, subdir).
-			Implicit(fsInfo.Output) // so that the staging dir is built
+			Textf("-rd %s/. %s/%s", rootDirString, targetFilesDir, toCopy.destSubdir).
+			Implicit(toCopy.fsInfo.Output) // so that the staging dir is built
 
-		if subdir == "SYSTEM" {
+		if toCopy.destSubdir == "SYSTEM" {
 			// Create the ROOT partition in target_files.zip
-			builder.Command().Textf("rsync --links --exclude=system/* %s/ -r %s/ROOT", fsInfo.RootDir, targetFilesDir.String())
+			builder.Command().Textf("rsync --links --exclude=system/* %s/ -r %s/ROOT", toCopy.fsInfo.RootDir, targetFilesDir.String())
 		}
 	}
 	// Copy cmdline, kernel etc. files of boot images
@@ -332,9 +358,13 @@
 	}
 	// Copy the filesystem ,boot and vbmeta img files to IMAGES/
 	ctx.VisitDirectDepsProxyWithTag(filesystemDepTag, func(child android.ModuleProxy) {
-		if info, ok := android.OtherModuleProvider(ctx, child, FilesystemProvider); ok {
+		if strings.Contains(child.Name(), "recovery") {
+			return // skip recovery.img to match the make packaging behavior
+		}
+		if info, ok := android.OtherModuleProvider(ctx, child, BootimgInfoProvider); ok {
+			// Check Boot img first so that the boot.img is copied and not its dep ramdisk.img
 			builder.Command().Textf("cp ").Input(info.Output).Textf(" %s/IMAGES/", targetFilesDir.String())
-		} else if info, ok := android.OtherModuleProvider(ctx, child, BootimgInfoProvider); ok {
+		} else if info, ok := android.OtherModuleProvider(ctx, child, FilesystemProvider); ok {
 			builder.Command().Textf("cp ").Input(info.Output).Textf(" %s/IMAGES/", targetFilesDir.String())
 		} else if info, ok := android.OtherModuleProvider(ctx, child, vbmetaPartitionProvider); ok {
 			builder.Command().Textf("cp ").Input(info.Output).Textf(" %s/IMAGES/", targetFilesDir.String())
@@ -342,6 +372,17 @@
 			ctx.ModuleErrorf("Module %s does not provide an .img file output for target_files.zip", child.Name())
 		}
 	})
+
+	if a.partitionProps.Super_partition_name != nil {
+		superPartition := ctx.GetDirectDepWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag)
+		if info, ok := android.OtherModuleProvider(ctx, superPartition, SuperImageProvider); ok {
+			for _, partition := range android.SortedStringKeys(info.SubImageInfo) {
+				builder.Command().Textf("cp ").Input(info.SubImageInfo[partition].Output).Textf(" %s/IMAGES/", targetFilesDir.String())
+			}
+		} else {
+			ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name())
+		}
+	}
 }
 
 func (a *androidDevice) getFilesystemInfo(ctx android.ModuleContext, depName string) FilesystemInfo {
diff --git a/rust/config/global.go b/rust/config/global.go
index 0a4b314..2623a5c 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -25,7 +25,7 @@
 var (
 	pctx = android.NewPackageContext("android/soong/rust/config")
 
-	RustDefaultVersion = "1.81.0"
+	RustDefaultVersion = "1.82.0"
 	RustDefaultBase    = "prebuilts/rust/"
 	DefaultEdition     = "2021"
 	Stdlibs            = []string{