Add support for SBOM generation in soong-only builds

Add an alternative way of collecting metadata in soong-only build, which
is initially done in make.

Bug: 398039178
Test: presubmits
Test: lunch aosp_cf_x86_64_phone-trunk_staging-eng && m && m sbom
Change-Id: I94476db21cf9eac8be7693043f2cd7a2b1bcd8a6
diff --git a/android/Android.bp b/android/Android.bp
index 1cc7ffe..00dc50a 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -97,6 +97,7 @@
         "product_packages_file.go",
         "proto.go",
         "provider.go",
+        "provider_keys.go",
         "raw_files.go",
         "recovery_build_prop.go",
         "register.go",
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index a6dbb8d..7c0ab85 100644
--- a/android/compliance_metadata.go
+++ b/android/compliance_metadata.go
@@ -127,27 +127,32 @@
 // dependencies, built/installed files, etc. It is a wrapper on a map[string]string with some utility
 // methods to get/set properties' values.
 type ComplianceMetadataInfo struct {
-	properties map[string]string
+	properties     map[string]string
+	filesContained []string
 }
 
 type complianceMetadataInfoGob struct {
-	Properties map[string]string
+	Properties     map[string]string
+	FilesContained []string
 }
 
 func NewComplianceMetadataInfo() *ComplianceMetadataInfo {
 	return &ComplianceMetadataInfo{
-		properties: map[string]string{},
+		properties:     map[string]string{},
+		filesContained: make([]string, 0),
 	}
 }
 
 func (m *ComplianceMetadataInfo) ToGob() *complianceMetadataInfoGob {
 	return &complianceMetadataInfoGob{
-		Properties: m.properties,
+		Properties:     m.properties,
+		FilesContained: m.filesContained,
 	}
 }
 
 func (m *ComplianceMetadataInfo) FromGob(data *complianceMetadataInfoGob) {
 	m.properties = data.Properties
+	m.filesContained = data.FilesContained
 }
 
 func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) {
@@ -169,6 +174,14 @@
 	c.SetStringValue(propertyName, strings.TrimSpace(strings.Join(value, " ")))
 }
 
+func (c *ComplianceMetadataInfo) SetFilesContained(files []string) {
+	c.filesContained = files
+}
+
+func (c *ComplianceMetadataInfo) GetFilesContained() []string {
+	return c.filesContained
+}
+
 func (c *ComplianceMetadataInfo) getStringValue(propertyName string) string {
 	if !slices.Contains(COMPLIANCE_METADATA_PROPS, propertyName) {
 		panic(fmt.Errorf("Unknown metadata property: %s.", propertyName))
@@ -317,8 +330,25 @@
 	makeModulesCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-modules.csv")
 
 	if !ctx.Config().KatiEnabled() {
-		WriteFileRule(ctx, makeMetadataCsv, "installed_file,module_path,is_soong_module,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,static_libs,whole_static_libs,license_text")
-		WriteFileRule(ctx, makeModulesCsv, "name,module_path,module_class,module_type,static_libs,whole_static_libs,built_files,installed_files")
+		// In soong-only build the installed file list is from android_device module
+		ctx.VisitAllModuleProxies(func(module ModuleProxy) {
+			if androidDeviceInfo, ok := OtherModuleProvider(ctx, module, AndroidDeviceInfoProvider); !ok || !androidDeviceInfo.Main_device {
+				return
+			}
+			if metadataInfo, ok := OtherModuleProvider(ctx, module, ComplianceMetadataProvider); ok {
+				if len(metadataInfo.filesContained) > 0 {
+					csvHeaders := "installed_file,module_path,is_soong_module,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,static_libs,whole_static_libs,license_text"
+					csvContent := make([]string, 0, len(metadataInfo.filesContained)+1)
+					csvContent = append(csvContent, csvHeaders)
+					for _, file := range metadataInfo.filesContained {
+						csvContent = append(csvContent, file+",,Y,,,,,,,")
+					}
+					WriteFileRuleVerbatim(ctx, makeMetadataCsv, strings.Join(csvContent, "\n"))
+					WriteFileRuleVerbatim(ctx, makeModulesCsv, "name,module_path,module_class,module_type,static_libs,whole_static_libs,built_files,installed_files")
+				}
+				return
+			}
+		})
 	}
 
 	// Import metadata from Make and Soong to sqlite3 database
diff --git a/android/provider_keys.go b/android/provider_keys.go
new file mode 100644
index 0000000..60b383f
--- /dev/null
+++ b/android/provider_keys.go
@@ -0,0 +1,24 @@
+// Copyright 2025 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import "github.com/google/blueprint"
+
+// Providers of package filesystem
+type AndroidDeviceInfo struct {
+	Main_device bool
+}
+
+var AndroidDeviceInfoProvider = blueprint.NewProvider[AndroidDeviceInfo]()