Merge "Don't build all installed files by default in soong-only builds" into main
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index 6ad54da..3262493 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -65,15 +65,16 @@
 		})
 
 		var numOffendingPkg = 0
+		offendingPkgsMessage := ""
 		for pkg, cnt := range packages {
 			if cnt > 1 {
-				fmt.Printf("%d aconfig_declarations found for package %s\n", cnt, pkg)
+				offendingPkgsMessage += fmt.Sprintf("%d aconfig_declarations found for package %s\n", cnt, pkg)
 				numOffendingPkg++
 			}
 		}
 
 		if numOffendingPkg > 0 {
-			panic(fmt.Errorf("Only one aconfig_declarations allowed for each package."))
+			panic("Only one aconfig_declarations allowed for each package.\n" + offendingPkgsMessage)
 		}
 
 		// Generate build action for aconfig (binary proto output)
diff --git a/android/neverallow.go b/android/neverallow.go
index fdcbe1c..d211784 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -322,9 +322,6 @@
 
 func createKotlinPluginRule() []Rule {
 	kotlinPluginProjectsAllowedList := []string{
-		// TODO: Migrate compose plugin to the bundled compiler plugin
-		// Actual path prebuilts/sdk/current/androidx/m2repository/androidx/compose/compiler/compiler-hosted
-		"prebuilts/sdk/current/androidx",
 		"external/kotlinc",
 	}
 
diff --git a/android/util.go b/android/util.go
index 3fc4608..30d8ec6 100644
--- a/android/util.go
+++ b/android/util.go
@@ -308,6 +308,20 @@
 	return
 }
 
+// FilterListByPrefixes performs the same splitting as FilterList does, but treats the passed
+// filters as prefixes
+func FilterListByPrefix(list []string, filter []string) (remainder []string, filtered []string) {
+	for _, l := range list {
+		if HasAnyPrefix(l, filter) {
+			filtered = append(filtered, l)
+		} else {
+			remainder = append(remainder, l)
+		}
+	}
+
+	return
+}
+
 // FilterListPred returns the elements of the given list for which the predicate
 // returns true. Order is kept.
 func FilterListPred(list []string, pred func(s string) bool) (filtered []string) {
diff --git a/android/variable.go b/android/variable.go
index ec84274..6e46e9d 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -162,6 +162,7 @@
 			Optimize struct {
 				Enabled *bool
 			}
+			Aaptflags []string
 		}
 
 		Uml struct {
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 19e93ae..0a7b701 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -44,6 +44,12 @@
 	Vbmeta_partitions []string
 	// Name of the userdata partition filesystem module
 	Userdata_partition_name *string
+	// Name of the system_dlkm partition filesystem module
+	System_dlkm_partition_name *string
+	// Name of the vendor_dlkm partition filesystem module
+	Vendor_dlkm_partition_name *string
+	// Name of the odm_dlkm partition filesystem module
+	Odm_dlkm_partition_name *string
 }
 
 type androidDevice struct {
@@ -79,6 +85,9 @@
 	addDependencyIfDefined(a.partitionProps.Vendor_partition_name)
 	addDependencyIfDefined(a.partitionProps.Odm_partition_name)
 	addDependencyIfDefined(a.partitionProps.Userdata_partition_name)
+	addDependencyIfDefined(a.partitionProps.System_dlkm_partition_name)
+	addDependencyIfDefined(a.partitionProps.Vendor_dlkm_partition_name)
+	addDependencyIfDefined(a.partitionProps.Odm_dlkm_partition_name)
 	for _, vbmetaPartition := range a.partitionProps.Vbmeta_partitions {
 		ctx.AddDependency(ctx.Module(), filesystemDepTag, vbmetaPartition)
 	}
@@ -95,12 +104,25 @@
 	builder := android.NewRuleBuilder(pctx, ctx)
 	builder.Command().Textf("rm -rf %s", targetFilesDir.String())
 	builder.Command().Textf("mkdir -p %s", targetFilesDir.String())
-	if a.partitionProps.Vendor_partition_name != nil {
-		fsInfo := a.getFilesystemInfo(ctx, *a.partitionProps.Vendor_partition_name)
-		builder.Command().Textf("mkdir -p %s/VENDOR", targetFilesDir.String())
+	partitionToSubdir := map[*string]string{
+		a.partitionProps.System_partition_name:      "SYSTEM",
+		a.partitionProps.System_ext_partition_name:  "SYSTEM_EXT",
+		a.partitionProps.Product_partition_name:     "PRODUCT",
+		a.partitionProps.Vendor_partition_name:      "VENDOR",
+		a.partitionProps.Odm_partition_name:         "ODM",
+		a.partitionProps.System_dlkm_partition_name: "SYSTEM_DLKM",
+		a.partitionProps.Vendor_dlkm_partition_name: "VENDOR_DLKM",
+		a.partitionProps.Odm_dlkm_partition_name:    "ODM_DLKM",
+	}
+	for partition, subdir := range partitionToSubdir {
+		if partition == nil {
+			continue
+		}
+		fsInfo := a.getFilesystemInfo(ctx, *partition)
+		builder.Command().Textf("mkdir -p %s/%s", targetFilesDir.String(), subdir)
 		builder.Command().
 			BuiltTool("acp").
-			Textf("-rd %s/. %s/VENDOR", fsInfo.RootDir, targetFilesDir).
+			Textf("-rd %s/. %s/%s", fsInfo.RootDir, targetFilesDir, subdir).
 			Implicit(fsInfo.Output) // so that the staging dir is built
 	}
 	builder.Command().
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 0160159..de9e5c2 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -214,6 +214,15 @@
 	if android.InList("recovery", f.properties.Generated_partition_types) {
 		partitionProps.Recovery_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "recovery"))
 	}
+	if android.InList("system_dlkm", f.properties.Generated_partition_types) {
+		partitionProps.System_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_dlkm"))
+	}
+	if android.InList("vendor_dlkm", f.properties.Generated_partition_types) {
+		partitionProps.Vendor_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_dlkm"))
+	}
+	if android.InList("odm_dlkm", f.properties.Generated_partition_types) {
+		partitionProps.Odm_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm_dlkm"))
+	}
 	if f.properties.Boot_image != "" {
 		partitionProps.Boot_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "boot"))
 	}
diff --git a/java/aar.go b/java/aar.go
index 3c62441..ed2fb7a 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -391,8 +391,9 @@
 		versionName = proptools.NinjaEscape(versionName)
 		linkFlags = append(linkFlags, "--version-name ", versionName)
 	}
-
-	linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
+	// Split the flags by prefix, as --png-compression-level has the "=value" suffix.
+	linkFlags, compileFlags = android.FilterListByPrefix(linkFlags,
+		[]string{"--legacy", "--png-compression-level"})
 
 	// Always set --pseudo-localize, it will be stripped out later for release
 	// builds that don't want it.
diff --git a/java/app.go b/java/app.go
index d56ea5f..a4e84e0 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1738,6 +1738,8 @@
 
 	// TODO(b/192032291): Disable by default after auditing downstream usage.
 	module.Module.dexProperties.Optimize.EnabledByDefault = true
+	module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
+	module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
 
 	module.Module.properties.Installable = proptools.BoolPtr(true)
 	module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
diff --git a/java/dex.go b/java/dex.go
index 168a231..7b99549 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -42,11 +42,15 @@
 		// True if the module containing this has it set by default.
 		EnabledByDefault bool `blueprint:"mutated"`
 
+		// Whether to allow that library classes inherit from program classes.
+		// Defaults to false.
+		Ignore_library_extends_program *bool
+
 		// Whether to continue building even if warnings are emitted.  Defaults to true.
 		Ignore_warnings *bool
 
 		// If true, runs R8 in Proguard compatibility mode, otherwise runs R8 in full mode.
-		// Defaults to false for apps, true for libraries and tests.
+		// Defaults to false for apps and tests, true for libraries.
 		Proguard_compatibility *bool
 
 		// If true, optimize for size by removing unused code.  Defaults to true for apps,
@@ -356,6 +360,10 @@
 
 	r8Flags = append(r8Flags, opt.Proguard_flags...)
 
+	if BoolDefault(opt.Ignore_library_extends_program, false) {
+		r8Flags = append(r8Flags, "--ignore-library-extends-program")
+	}
+
 	if BoolDefault(opt.Proguard_compatibility, true) {
 		r8Flags = append(r8Flags, "--force-proguard-compatibility")
 	}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index e955949..fa1fb86 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -629,8 +629,8 @@
 					cmd.Implicit(dep)
 				} else if filename != "android.jar" && depBase == "android.jar" {
 					// Metalava implicitly searches these patterns:
-					//  prebuilts/tools/common/api-versions/android-%/android.jar
-					//  prebuilts/sdk/%/public/android.jar
+					//  prebuilts/tools/common/api-versions/android-{version:level}/android.jar
+					//  prebuilts/sdk/{version:level}/public/android.jar
 					// Add android.jar files from the api_levels_annotations_dirs directories to try
 					// to satisfy these patterns.  If Metalava can't find a match for an API level
 					// between 1 and 28 in at least one pattern it will fail.
@@ -646,11 +646,11 @@
 	})
 
 	// Generate the list of --android-jar-pattern options. The order matters so the first one which
-	// matches will be the one that is used for a specific api level..
+	// matches will be the one that is used for a specific api level.
 	for _, sdkDir := range sdkDirs {
 		for _, dir := range dirs {
 			addPattern := func(jarFilename string) {
-				cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, jarFilename))
+				cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:level}/%s/%s", dir, sdkDir, jarFilename))
 			}
 
 			if sdkDir == "module-lib" || sdkDir == "system-server" {
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 1e8362c..37740ae 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -88,7 +88,7 @@
 		cmdline := String(sboxProto.Commands[0].Command)
 		android.AssertStringContainsEquals(t, "api-versions generation flag", cmdline, "--generate-api-levels", c.generate_xml)
 		if c.expectedJarFilename != "" {
-			expected := "--android-jar-pattern ./%/public/" + c.expectedJarFilename
+			expected := "--android-jar-pattern ./{version:level}/public/" + c.expectedJarFilename
 			if !strings.Contains(cmdline, expected) {
 				t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, cmdline)
 			}
@@ -142,8 +142,8 @@
 	patterns := getAndroidJarPatternsForDroidstubs(t, "public")
 
 	android.AssertArrayString(t, "order of patterns", []string{
-		"--android-jar-pattern somedir/%/public/android.jar",
-		"--android-jar-pattern someotherdir/%/public/android.jar",
+		"--android-jar-pattern somedir/{version:level}/public/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/public/android.jar",
 	}, patterns)
 }
 
@@ -151,10 +151,10 @@
 	patterns := getAndroidJarPatternsForDroidstubs(t, "system")
 
 	android.AssertArrayString(t, "order of patterns", []string{
-		"--android-jar-pattern somedir/%/system/android.jar",
-		"--android-jar-pattern someotherdir/%/system/android.jar",
-		"--android-jar-pattern somedir/%/public/android.jar",
-		"--android-jar-pattern someotherdir/%/public/android.jar",
+		"--android-jar-pattern somedir/{version:level}/system/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/system/android.jar",
+		"--android-jar-pattern somedir/{version:level}/public/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/public/android.jar",
 	}, patterns)
 }
 
@@ -162,12 +162,12 @@
 	patterns := getAndroidJarPatternsForDroidstubs(t, "module-lib")
 
 	android.AssertArrayString(t, "order of patterns", []string{
-		"--android-jar-pattern somedir/%/module-lib/android.jar",
-		"--android-jar-pattern someotherdir/%/module-lib/android.jar",
-		"--android-jar-pattern somedir/%/system/android.jar",
-		"--android-jar-pattern someotherdir/%/system/android.jar",
-		"--android-jar-pattern somedir/%/public/android.jar",
-		"--android-jar-pattern someotherdir/%/public/android.jar",
+		"--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
+		"--android-jar-pattern somedir/{version:level}/system/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/system/android.jar",
+		"--android-jar-pattern somedir/{version:level}/public/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/public/android.jar",
 	}, patterns)
 }
 
@@ -175,14 +175,14 @@
 	patterns := getAndroidJarPatternsForDroidstubs(t, "system-server")
 
 	android.AssertArrayString(t, "order of patterns", []string{
-		"--android-jar-pattern somedir/%/system-server/android.jar",
-		"--android-jar-pattern someotherdir/%/system-server/android.jar",
-		"--android-jar-pattern somedir/%/module-lib/android.jar",
-		"--android-jar-pattern someotherdir/%/module-lib/android.jar",
-		"--android-jar-pattern somedir/%/system/android.jar",
-		"--android-jar-pattern someotherdir/%/system/android.jar",
-		"--android-jar-pattern somedir/%/public/android.jar",
-		"--android-jar-pattern someotherdir/%/public/android.jar",
+		"--android-jar-pattern somedir/{version:level}/system-server/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/system-server/android.jar",
+		"--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
+		"--android-jar-pattern somedir/{version:level}/system/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/system/android.jar",
+		"--android-jar-pattern somedir/{version:level}/public/android.jar",
+		"--android-jar-pattern someotherdir/{version:level}/public/android.jar",
 	}, patterns)
 }
 
diff --git a/rust/builder.go b/rust/builder.go
index e5434ef..8a869aa 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -264,7 +264,7 @@
 		libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
 	}
 	for _, lib := range deps.DyLibs {
-		libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
+		libFlags = append(libFlags, "--extern force:"+lib.CrateName+"="+lib.Path.String())
 	}
 	for _, proc_macro := range deps.ProcMacros {
 		libFlags = append(libFlags, "--extern "+proc_macro.CrateName+"="+proc_macro.Path.String())
diff --git a/rust/config/global.go b/rust/config/global.go
index 66ffc0b..0a4b314 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -42,6 +42,8 @@
 	}
 
 	GlobalRustFlags = []string{
+		// Allow `--extern force:foo` for dylib support
+		"-Z unstable-options",
 		"-Z stack-protector=strong",
 		"-Z remap-cwd-prefix=.",
 		"-C debuginfo=2",
diff --git a/rust/library.go b/rust/library.go
index 14a2b65..2d62dcf 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -457,13 +457,6 @@
 
 	cfgs := library.baseCompiler.Properties.Cfgs.GetOrDefault(ctx, nil)
 
-	if library.dylib() {
-		// We need to add a dependency on std in order to link crates as dylibs.
-		// The hack to add this dependency is guarded by the following cfg so
-		// that we don't force a dependency when it isn't needed.
-		cfgs = append(cfgs, "android_dylib")
-	}
-
 	cfgFlags := cfgsToFlags(cfgs)
 
 	flags.RustFlags = append(flags.RustFlags, cfgFlags...)
diff --git a/rust/library_test.go b/rust/library_test.go
index 256cb35..e5fd5e0 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -89,22 +89,6 @@
 	}
 }
 
-// Check that we are passing the android_dylib config flag
-func TestAndroidDylib(t *testing.T) {
-	ctx := testRust(t, `
-		rust_library_host_dylib {
-			name: "libfoo",
-			srcs: ["foo.rs"],
-			crate_name: "foo",
-		}`)
-
-	libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
-
-	if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") {
-		t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
-	}
-}
-
 func TestValidateLibraryStem(t *testing.T) {
 	testRustError(t, "crate_name must be defined.", `
 			rust_library_host {
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 90c1f61..9f65dec 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -424,11 +424,11 @@
 		}`)
 
 	fooRustc := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
-	if !strings.Contains(fooRustc.Args["libFlags"], "--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so") {
-		t.Errorf("--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+	if !strings.Contains(fooRustc.Args["libFlags"], "--extern force:bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so") {
+		t.Errorf("--extern force:bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
 	}
-	if !strings.Contains(fooRustc.Args["libFlags"], "--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so") {
-		t.Errorf("--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+	if !strings.Contains(fooRustc.Args["libFlags"], "--extern force:baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so") {
+		t.Errorf("--extern force:baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
 	}
 }
 
diff --git a/ui/metrics/proc/status_linux_test.go b/ui/metrics/proc/status_linux_test.go
index 6709850..0edc400 100644
--- a/ui/metrics/proc/status_linux_test.go
+++ b/ui/metrics/proc/status_linux_test.go
@@ -1,7 +1,6 @@
 package proc
 
 import (
-	"fmt"
 	"path/filepath"
 	"reflect"
 	"strconv"
@@ -29,7 +28,6 @@
 		t.Fatalf("got %v, want nil for error", err)
 	}
 
-	fmt.Printf("%d %d\b", status.VmPeak, expectedStatus.VmPeak)
 	if !reflect.DeepEqual(status, expectedStatus) {
 		t.Errorf("got %v, expecting %v for ProcStatus", status, expectedStatus)
 	}