Merge "Add partition compatibility symlinks to installed file list."
diff --git a/core/binary.mk b/core/binary.mk
index 6f1d814..579e6b5 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -168,7 +168,6 @@
 endif
 endif
 
-my_ndk_sysroot :=
 my_ndk_sysroot_include :=
 my_ndk_sysroot_lib :=
 my_api_level := 10000
@@ -183,11 +182,7 @@
   # Make sure we've built the NDK.
   my_additional_dependencies += $(SOONG_OUT_DIR)/ndk_base.timestamp
 
-  ifneq (,$(filter arm64 x86_64,$(my_arch)))
-    my_min_sdk_version := 21
-  else
-    my_min_sdk_version := $(MIN_SUPPORTED_SDK_VERSION)
-  endif
+  my_min_sdk_version := $(MIN_SUPPORTED_SDK_VERSION)
 
   # Historically we've just set up a bunch of symlinks in prebuilts/ndk to map
   # missing API levels to existing ones where necessary, but we're not doing
@@ -200,38 +195,19 @@
 
   my_ndk_crt_version := $(my_ndk_api)
 
-  my_ndk_hist_api := $(my_ndk_api)
-  ifeq ($(my_ndk_api),current)
-    # The last API level supported by the old prebuilt NDKs.
-    my_ndk_hist_api := 24
-  else
+  ifneq ($(my_ndk_api),current)
     my_api_level := $(my_ndk_api)
   endif
 
   my_ndk_source_root := \
       $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/sources
-  my_ndk_sysroot := \
-    $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/platforms/android-$(my_ndk_hist_api)/arch-$(my_arch)
   my_built_ndk := $(SOONG_OUT_DIR)/ndk
   my_ndk_triple := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_TRIPLE)
   my_ndk_sysroot_include := \
       $(my_built_ndk)/sysroot/usr/include \
       $(my_built_ndk)/sysroot/usr/include/$(my_ndk_triple) \
-      $(my_ndk_sysroot)/usr/include \
 
-  # x86_64 is a multilib toolchain, so their libraries are
-  # installed in /usr/lib64. Aarch64, on the other hand, is not a multilib
-  # compiler, so its libraries are in /usr/lib.
-  ifneq (,$(filter x86_64,$(my_arch)))
-    my_ndk_libdir_name := lib64
-  else
-    my_ndk_libdir_name := lib
-  endif
-
-  my_ndk_platform_dir := \
-      $(my_built_ndk)/platforms/android-$(my_ndk_api)/arch-$(my_arch)
-  my_built_ndk_libs := $(my_ndk_platform_dir)/usr/$(my_ndk_libdir_name)
-  my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/$(my_ndk_libdir_name)
+  my_ndk_sysroot_lib := $(my_built_ndk)/sysroot/usr/lib/$(my_ndk_triple)/$(my_ndk_api)
 
   # The bionic linker now has support for packed relocations and gnu style
   # hashes (which are much faster!), but shipping to older devices requires
@@ -1428,7 +1404,6 @@
 my_ndk_shared_libraries_fullpath := \
     $(foreach _lib,$(my_ndk_shared_libraries),\
         $(if $(filter $(NDK_KNOWN_LIBS),$(_lib)),\
-            $(my_built_ndk_libs)/$(_lib)$(so_suffix),\
             $(my_ndk_sysroot_lib)/$(_lib)$(so_suffix)))
 
 built_shared_libraries += \
diff --git a/core/config.mk b/core/config.mk
index 91c8bd8..26e90ef 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -863,7 +863,6 @@
 
 # A list of SEPolicy versions, besides PLATFORM_SEPOLICY_VERSION, that the framework supports.
 PLATFORM_SEPOLICY_COMPAT_VERSIONS := \
-    28.0 \
     29.0 \
     30.0 \
     31.0 \
diff --git a/core/main.mk b/core/main.mk
index 33bcc20..9ddd990 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -2192,13 +2192,13 @@
 $(PRODUCT_OUT)/sbom.spdx.json: $(PRODUCT_OUT)/sbom.spdx
 $(PRODUCT_OUT)/sbom.spdx: $(PRODUCT_OUT)/sbom-metadata.csv $(GEN_SBOM)
 	rm -rf $@
-	$(GEN_SBOM) --output_file $@ --metadata $(PRODUCT_OUT)/sbom-metadata.csv --product_out_dir=$(PRODUCT_OUT) --build_version $(BUILD_FINGERPRINT_FROM_FILE) --product_mfr=$(PRODUCT_MANUFACTURER) --json
+	$(GEN_SBOM) --output_file $@ --metadata $(PRODUCT_OUT)/sbom-metadata.csv --product_out_dir=$(PRODUCT_OUT) --build_version $(BUILD_FINGERPRINT_FROM_FILE) --product_mfr="$(PRODUCT_MANUFACTURER)" --json
 
 else
 apps_only_sbom_files := $(sort $(patsubst %,%.spdx,$(apps_only_installed_files)))
 $(apps_only_sbom_files): $(PRODUCT_OUT)/sbom-metadata.csv $(GEN_SBOM)
 	rm -rf $@
-	$(GEN_SBOM) --output_file $@ --metadata $(PRODUCT_OUT)/sbom-metadata.csv --product_out_dir=$(PRODUCT_OUT) --build_version $(BUILD_FINGERPRINT_FROM_FILE) --product_mfr=$(PRODUCT_MANUFACTURER) --unbundled
+	$(GEN_SBOM) --output_file $@ --metadata $(PRODUCT_OUT)/sbom-metadata.csv --product_out_dir=$(PRODUCT_OUT) --build_version $(BUILD_FINGERPRINT_FROM_FILE) --product_mfr="$(PRODUCT_MANUFACTURER)" --unbundled
 
 sbom: $(apps_only_sbom_files)
 endif
diff --git a/target/product/security/BUILD.bazel b/target/product/security/BUILD.bazel
index 08c1944..c12be79 100644
--- a/target/product/security/BUILD.bazel
+++ b/target/product/security/BUILD.bazel
@@ -4,4 +4,5 @@
         "*.pk8",
         "*.pem",
     ]),
+    visibility = ["//visibility:public"],
 )
diff --git a/tools/Android.bp b/tools/Android.bp
index f170336..e325f6b 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -92,4 +92,9 @@
     srcs: [
         "list_files.py",
     ],
+    version: {
+      py3: {
+        embedded_launcher: true,
+      }
+    }
 }
diff --git a/tools/compliance/cmd/sbom/sbom.go b/tools/compliance/cmd/sbom/sbom.go
index 1477ca5..3cdfa0a 100644
--- a/tools/compliance/cmd/sbom/sbom.go
+++ b/tools/compliance/cmd/sbom/sbom.go
@@ -16,6 +16,8 @@
 
 import (
 	"bytes"
+	"crypto/sha1"
+	"encoding/hex"
 	"flag"
 	"fmt"
 	"io"
@@ -194,11 +196,12 @@
 	os.Exit(0)
 }
 
-type creationTimeGetter func() time.Time
+type creationTimeGetter func() string
 
 // actualTime returns current time in UTC
-func actualTime() time.Time {
-	return time.Now().UTC()
+func actualTime() string {
+	t := time.Now().UTC()
+	return t.UTC().Format("2006-01-02T15:04:05Z")
 }
 
 // replaceSlashes replaces "/" by "-" for the library path to be used for packages & files SPDXID
@@ -206,6 +209,23 @@
 	return strings.ReplaceAll(x, "/", "-")
 }
 
+// stripDocName removes the outdir prefix and meta_lic suffix from a target Name
+func stripDocName(name string) string {
+	// remove outdir prefix
+	if strings.HasPrefix(name, "out/") {
+		name = name[4:]
+	}
+
+	// remove suffix
+	if strings.HasSuffix(name, ".meta_lic") {
+		name = name[:len(name)-9]
+	} else if strings.HasSuffix(name, "/meta_lic") {
+		name = name[:len(name)-9] + "/"
+	}
+
+	return name
+}
+
 // getPackageName returns a package name of a target Node
 func getPackageName(_ *context, tn *compliance.TargetNode) string {
 	return replaceSlashes(tn.Name())
@@ -223,8 +243,7 @@
 		return replaceSlashes(tn.ModuleName())
 	}
 
-	// TO DO: Replace tn.Name() with pm.Name() + parts of the target name
-	return replaceSlashes(tn.Name())
+	return stripDocName(replaceSlashes(tn.Name()))
 }
 
 // getDownloadUrl returns the download URL if available (GIT, SVN, etc..),
@@ -295,6 +314,19 @@
 	return files
 }
 
+// generateSPDXNamespace generates a unique SPDX Document Namespace using a SHA1 checksum
+// and the CreationInfo.Created field as the date.
+func generateSPDXNamespace(created string) string {
+	// Compute a SHA1 checksum of the CreationInfo.Created field.
+	hash := sha1.Sum([]byte(created))
+	checksum := hex.EncodeToString(hash[:])
+
+	// Combine the checksum and timestamp to generate the SPDX Namespace.
+	namespace := fmt.Sprintf("SPDXRef-DOCUMENT-%s-%s", created, checksum)
+
+	return namespace
+}
+
 // sbomGenerator implements the spdx bom utility
 
 // SBOM is part of the new government regulation issued to improve national cyber security
@@ -325,8 +357,11 @@
 	// creating the license section
 	otherLicenses := []*spdx.OtherLicense{}
 
-        // main package name
-        var mainPkgName string
+	// spdx document name
+	var docName string
+
+	// main package name
+	var mainPkgName string
 
 	// implementing the licenses references for the packages
 	licenses := make(map[string]string)
@@ -365,6 +400,7 @@
 			}
 
 			if isMainPackage {
+				docName = getDocumentName(ctx, tn, pm)
 				mainPkgName = replaceSlashes(getPackageName(ctx, tn))
 				isMainPackage = false
 			}
@@ -478,11 +514,17 @@
 		return nil, nil, fmt.Errorf("Unable to build creation info section for SPDX doc: %v\n", err)
 	}
 
+	ci.Created = ctx.creationTime()
+
 	return &spdx.Document{
-		SPDXIdentifier: "DOCUMENT",
-		CreationInfo:   ci,
-		Packages:       pkgs,
-		Relationships:  relationships,
-		OtherLicenses:  otherLicenses,
+		SPDXVersion:       "SPDX-2.2",
+		DataLicense:       "CC0-1.0",
+		SPDXIdentifier:    "DOCUMENT",
+		DocumentName:      docName,
+		DocumentNamespace: generateSPDXNamespace(ci.Created),
+		CreationInfo:      ci,
+		Packages:          pkgs,
+		Relationships:     relationships,
+		OtherLicenses:     otherLicenses,
 	}, deps, nil
 }
diff --git a/tools/compliance/cmd/sbom/sbom_test.go b/tools/compliance/cmd/sbom/sbom_test.go
index cc8805f..65a2df1 100644
--- a/tools/compliance/cmd/sbom/sbom_test.go
+++ b/tools/compliance/cmd/sbom/sbom_test.go
@@ -55,8 +55,12 @@
 			name:      "apex",
 			roots:     []string{"highest.apex.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-firstparty-highest.apex",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-firstparty-highest.apex.meta_lic",
@@ -179,8 +183,12 @@
 			name:      "application",
 			roots:     []string{"application.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-firstparty-application",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-firstparty-application.meta_lic",
@@ -254,8 +262,12 @@
 			name:      "container",
 			roots:     []string{"container.zip.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-firstparty-container.zip",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-firstparty-container.zip.meta_lic",
@@ -378,8 +390,12 @@
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-firstparty-bin-bin1",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-firstparty-bin-bin1.meta_lic",
@@ -440,8 +456,12 @@
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-firstparty-lib-libd.so",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-firstparty-lib-libd.so.meta_lic",
@@ -476,8 +496,12 @@
 			name:      "apex",
 			roots:     []string{"highest.apex.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-notice-highest.apex",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-notice-highest.apex.meta_lic",
@@ -606,8 +630,12 @@
 			name:      "container",
 			roots:     []string{"container.zip.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-notice-container.zip",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-notice-container.zip.meta_lic",
@@ -736,8 +764,12 @@
 			name:      "application",
 			roots:     []string{"application.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-notice-application",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-notice-application.meta_lic",
@@ -817,8 +849,12 @@
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-notice-bin-bin1",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-notice-bin-bin1.meta_lic",
@@ -885,8 +921,12 @@
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-notice-lib-libd.so",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-notice-lib-libd.so.meta_lic",
@@ -921,8 +961,12 @@
 			name:      "apex",
 			roots:     []string{"highest.apex.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-reciprocal-highest.apex",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-reciprocal-highest.apex.meta_lic",
@@ -1057,8 +1101,12 @@
 			name:      "application",
 			roots:     []string{"application.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-reciprocal-application",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-reciprocal-application.meta_lic",
@@ -1144,8 +1192,12 @@
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-reciprocal-bin-bin1",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-reciprocal-bin-bin1.meta_lic",
@@ -1212,8 +1264,12 @@
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-reciprocal-lib-libd.so",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-reciprocal-lib-libd.so.meta_lic",
@@ -1248,8 +1304,12 @@
 			name:      "apex",
 			roots:     []string{"highest.apex.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-restricted-highest.apex",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-restricted-highest.apex.meta_lic",
@@ -1390,8 +1450,12 @@
 			name:      "container",
 			roots:     []string{"container.zip.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-restricted-container.zip",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-restricted-container.zip.meta_lic",
@@ -1532,8 +1596,12 @@
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-restricted-bin-bin1",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-restricted-bin-bin1.meta_lic",
@@ -1606,8 +1674,12 @@
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-restricted-lib-libd.so",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-restricted-lib-libd.so.meta_lic",
@@ -1642,8 +1714,12 @@
 			name:      "apex",
 			roots:     []string{"highest.apex.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-proprietary-highest.apex",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-proprietary-highest.apex.meta_lic",
@@ -1784,8 +1860,12 @@
 			name:      "container",
 			roots:     []string{"container.zip.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-proprietary-container.zip",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-proprietary-container.zip.meta_lic",
@@ -1926,8 +2006,12 @@
 			name:      "application",
 			roots:     []string{"application.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-proprietary-application",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-proprietary-application.meta_lic",
@@ -2013,8 +2097,12 @@
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-proprietary-bin-bin1",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-proprietary-bin-bin1.meta_lic",
@@ -2081,8 +2169,12 @@
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
 			expectedOut: &spdx.Document{
-				SPDXIdentifier: "DOCUMENT",
-				CreationInfo:   getCreationInfo(t),
+				SPDXVersion:       "SPDX-2.2",
+				DataLicense:       "CC0-1.0",
+				SPDXIdentifier:    "DOCUMENT",
+				DocumentName:      "testdata-proprietary-lib-libd.so",
+				DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
+				CreationInfo:      getCreationInfo(t),
 				Packages: []*spdx.Package{
 					{
 						PackageName:             "testdata-proprietary-lib-libd.so.meta_lic",
@@ -2123,7 +2215,7 @@
 				rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
 			}
 
-			ctx := context{stdout, stderr, compliance.GetFS(tt.outDir), "Android", []string{tt.stripPrefix}, fakeTime}
+			ctx := context{stdout, stderr, compliance.GetFS(tt.outDir), "", []string{tt.stripPrefix}, fakeTime}
 
 			spdxDoc, deps, err := sbomGenerator(&ctx, rootFiles...)
 			if err != nil {
@@ -2181,6 +2273,27 @@
 	if actual == nil || expected == nil {
 		t.Errorf("SBOM: SPDX Doc is nil! Got %v: Expected %v", actual, expected)
 	}
+
+	if actual.DocumentName != expected.DocumentName {
+		t.Errorf("sbom: unexpected SPDX Document Name got %q, want %q", actual.DocumentName, expected.DocumentName)
+	}
+
+	if actual.SPDXVersion != expected.SPDXVersion {
+		t.Errorf("sbom: unexpected SPDX Version got %s, want %s", actual.SPDXVersion, expected.SPDXVersion)
+	}
+
+	if actual.DataLicense != expected.DataLicense {
+		t.Errorf("sbom: unexpected SPDX DataLicense got %s, want %s", actual.DataLicense, expected.DataLicense)
+	}
+
+	if actual.SPDXIdentifier != expected.SPDXIdentifier {
+		t.Errorf("sbom: unexpected SPDX Identified got %s, want %s", actual.SPDXIdentifier, expected.SPDXIdentifier)
+	}
+
+	if actual.DocumentNamespace != expected.DocumentNamespace {
+		t.Errorf("sbom: unexpected SPDX Document Namespace got %s, want %s", actual.DocumentNamespace, expected.DocumentNamespace)
+	}
+
 	// compare creation info
 	compareSpdxCreationInfo(t, actual.CreationInfo, expected.CreationInfo)
 
@@ -2314,6 +2427,7 @@
 	return true
 }
 
-func fakeTime() time.Time {
-	return time.UnixMicro(0).UTC()
+func fakeTime() string {
+	t := time.UnixMicro(0)
+	return t.UTC().Format("2006-01-02T15:04:05Z")
 }
diff --git a/tools/finalization/README.md b/tools/finalization/README.md
new file mode 100644
index 0000000..501f260
--- /dev/null
+++ b/tools/finalization/README.md
@@ -0,0 +1,22 @@
+# Finalization tools
+This folder contains automation and CI scripts for [finalizing](https://go/android-finalization) Android before release.
+
+## Automation:
+1. [Environment setup](./environment.sh). Set values for varios finalization constants.
+2. [Finalize SDK](./finalize-aidl-vndk-sdk-resources.sh). Prepare the branch for SDK release. SDK contains Android Java APIs and other stable APIs. Commonly referred as a 1st step.
+3. [Finalize Android](./finalize-sdk-rel.sh). Mark branch as "REL", i.e. prepares for Android release. Any signed build containing these changes will be considered an official Android Release. Referred as a 2nd finalization step.
+4. [Finalize SDK and submit](./step-1.sh). Do [Finalize SDK](./finalize-aidl-vndk-sdk-resources.sh) step, create CLs, organize them into topic and send to Gerrit.
+  a. [Update SDK and submit](./update-step-1.sh). Same as above, but updates the existings CLs.
+5. [Finalize Android and submit](./step-2.sh). Do [Finalize Android](./finalize-sdk-rel.sh) step, create  CLs, organize them into topic and send to Gerrit.
+  a. [Update Android and submit](./update-step-2.sh). Same as above, but updates the existings CLs.
+
+## CI:
+Performed in build targets in Finalization branches.
+1. [Finalization Step 1 for Main, git_main-fina-1-release](https://android-build.googleplex.com/builds/branches/git_main-fina-1-release/grid). Test [1st step/Finalize SDK](./finalize-aidl-vndk-sdk-resources.sh).
+2. [Finalization Step 1 for UDC, git_udc-fina-1-release](https://android-build.googleplex.com/builds/branches/git_udc-fina-1-release/grid). Same but for udc-dev.
+3. [Finalization Step 2 for Main, git_main-fina-2-release](https://android-build.googleplex.com/builds/branches/git_main-fina-2-release/grid). Test [1st step/Finalize SDK](./finalize-aidl-vndk-sdk-resources.sh) and [2nd step/Finalize Android](./finalize-sdk-rel.sh). Use [local finalization](./localonly-steps.sh) to build and copy presubmits.
+4. [Finalization Step 2 for UDC, git_udc-fina-2-release](https://android-build.googleplex.com/builds/branches/git_udc-fina-2-release/grid). Same but for udc-dev.
+5. [Local finalization steps](./localonly-steps.sh) are done only during local testing or in the CI lab. Normally these steps use artifacts from other builds.
+
+## Utility:
+[Full cleanup](./cleanup.sh). Remove all local changes and switch each project into head-less state. This is the best state to sync/rebase/finalize the branch.
diff --git a/tools/finalization/build-step-1-and-2.sh b/tools/finalization/build-step-1-and-2.sh
index 1b749b1..a5aba08 100755
--- a/tools/finalization/build-step-1-and-2.sh
+++ b/tools/finalization/build-step-1-and-2.sh
@@ -9,8 +9,8 @@
     # SDK codename -> int
     source $top/build/make/tools/finalization/finalize-aidl-vndk-sdk-resources.sh
 
-    # Platform/Mainline SDKs build and move to prebuilts
-    source $top/build/make/tools/finalization/localonly-finalize-mainline-sdk.sh
+    # ADB, Platform/Mainline SDKs build and move to prebuilts
+    source $top/build/make/tools/finalization/localonly-steps.sh
 
     # REL
     source $top/build/make/tools/finalization/finalize-sdk-rel.sh
diff --git a/tools/finalization/finalize-sdk-rel.sh b/tools/finalization/finalize-sdk-rel.sh
index 9b5415b..cbee005 100755
--- a/tools/finalization/finalize-sdk-rel.sh
+++ b/tools/finalization/finalize-sdk-rel.sh
@@ -40,13 +40,15 @@
     cp -r "$top/system/sepolicy/private/" "$top/system/sepolicy/prebuilts/api/${FINAL_PLATFORM_SDK_VERSION}.0/"
 
     # prebuilts/abi-dumps/ndk
-    mv "$top/prebuilts/abi-dumps/ndk/current" "$top/prebuilts/abi-dumps/ndk/$FINAL_PLATFORM_SDK_VERSION"
+    mkdir -p "$top/prebuilts/abi-dumps/ndk/$FINAL_PLATFORM_SDK_VERSION"
+    cp -r "$top/prebuilts/abi-dumps/ndk/current/64/" "$top/prebuilts/abi-dumps/ndk/$FINAL_PLATFORM_SDK_VERSION/"
 
     # prebuilts/abi-dumps/vndk
     mv "$top/prebuilts/abi-dumps/vndk/$CURRENT_PLATFORM_CODENAME" "$top/prebuilts/abi-dumps/vndk/$FINAL_PLATFORM_SDK_VERSION"
 
     # prebuilts/abi-dumps/platform
-    mv "$top/prebuilts/abi-dumps/platform/current" "$top/prebuilts/abi-dumps/platform/$FINAL_PLATFORM_SDK_VERSION"
+    mkdir -p "$top/prebuilts/abi-dumps/platform/$FINAL_PLATFORM_SDK_VERSION"
+    cp -r "$top/prebuilts/abi-dumps/platform/current/64/" "$top/prebuilts/abi-dumps/platform/$FINAL_PLATFORM_SDK_VERSION/"
 }
 
 finalize_sdk_rel
diff --git a/tools/finalization/localonly-finalize-mainline-sdk.sh b/tools/finalization/localonly-steps.sh
similarity index 93%
rename from tools/finalization/localonly-finalize-mainline-sdk.sh
rename to tools/finalization/localonly-steps.sh
index 2b77c5d..6107b3e 100755
--- a/tools/finalization/localonly-finalize-mainline-sdk.sh
+++ b/tools/finalization/localonly-steps.sh
@@ -2,7 +2,7 @@
 
 set -ex
 
-function finalize_locally_mainline_sdk() {
+function finalize_locally() {
     local top="$(dirname "$0")"/../../../..
     source $top/build/make/tools/finalization/environment.sh
 
@@ -23,5 +23,4 @@
     "$top/prebuilts/build-tools/path/linux-x86/python3" -W ignore::DeprecationWarning "$top/prebuilts/sdk/update_prebuilts.py" --local_mode -f ${FINAL_PLATFORM_SDK_VERSION} -e ${FINAL_MAINLINE_EXTENSION} --bug 1 1
 }
 
-finalize_locally_mainline_sdk
-
+finalize_locally
diff --git a/tools/finalization/update-step-1.sh b/tools/finalization/update-step-1.sh
new file mode 100644
index 0000000..fd07b7b
--- /dev/null
+++ b/tools/finalization/update-step-1.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Script to perform a 1st step of Android Finalization: API/SDK finalization, update CLs and upload to Gerrit.
+
+set -ex
+
+function update_step_1_changes() {
+    set +e
+    repo forall -c '\
+        if [[ $(git status --short) ]]; then
+            git stash -u ;
+            repo start "$FINAL_PLATFORM_CODENAME-SDK-Finalization" ;
+            git stash pop ;
+            git add -A . ;
+            git commit --amend --no-edit ;
+            repo upload --cbr --no-verify -o nokeycheck -t -y . ;
+        fi'
+}
+
+function update_step_1_main() {
+    local top="$(dirname "$0")"/../../../..
+    source $top/build/make/tools/finalization/environment.sh
+
+
+    local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+    # vndk etc finalization
+    source $top/build/make/tools/finalization/finalize-aidl-vndk-sdk-resources.sh
+
+    # update existing CLs and upload to gerrit
+    update_step_1_changes
+
+    # build to confirm everything is OK
+    AIDL_FROZEN_REL=true $m
+}
+
+update_step_1_main
diff --git a/tools/finalization/update-step-2.sh b/tools/finalization/update-step-2.sh
new file mode 100755
index 0000000..e65d35a
--- /dev/null
+++ b/tools/finalization/update-step-2.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# Script to perform a 2nd step of Android Finalization: REL finalization, create CLs and upload to Gerrit.
+
+function update_step_2_changes() {
+    set +e
+    repo forall -c '\
+        if [[ $(git status --short) ]]; then
+            git stash -u ;
+            repo start "$FINAL_PLATFORM_CODENAME-SDK-Finalization-Rel" ;
+            git stash pop ;
+            git add -A . ;
+            git commit --amend --no-edit ;
+            repo upload --cbr --no-verify -o nokeycheck -t -y . ;
+        fi'
+}
+
+function update_step_2_main() {
+    local top="$(dirname "$0")"/../../../..
+    source $top/build/make/tools/finalization/environment.sh
+
+    local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+    # prebuilts etc
+    source $top/build/make/tools/finalization/finalize-sdk-rel.sh
+
+    # move all changes to finalization branch/topic and upload to gerrit
+    update_step_2_changes
+
+    # build to confirm everything is OK
+    AIDL_FROZEN_REL=true $m
+}
+
+update_step_2_main