Merge "[rust] Update clang version used to build bindgen"
diff --git a/android/arch.go b/android/arch.go
index 69d66e9..67158e0 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -864,6 +864,10 @@
 				archVariant := variantReplacer.Replace(archVariant)
 				variants = append(variants, proptools.FieldNameForProperty(archVariant))
 			}
+			for _, cpuVariant := range cpuVariants[arch] {
+				cpuVariant := variantReplacer.Replace(cpuVariant)
+				variants = append(variants, proptools.FieldNameForProperty(cpuVariant))
+			}
 			for _, feature := range archFeatures[arch] {
 				feature := variantReplacer.Replace(feature)
 				variants = append(variants, proptools.FieldNameForProperty(feature))
@@ -1741,6 +1745,18 @@
 		a.CpuVariant = ""
 	}
 
+	if a.ArchVariant != "" {
+		if validArchVariants := archVariants[archType]; !InList(a.ArchVariant, validArchVariants) {
+			return Arch{}, fmt.Errorf("[%q] unknown arch variant %q, support variants: %q", archType, a.ArchVariant, validArchVariants)
+		}
+	}
+
+	if a.CpuVariant != "" {
+		if validCpuVariants := cpuVariants[archType]; !InList(a.CpuVariant, validCpuVariants) {
+			return Arch{}, fmt.Errorf("[%q] unknown cpu variant %q, support variants: %q", archType, a.CpuVariant, validCpuVariants)
+		}
+	}
+
 	// Filter empty ABIs out of the list.
 	for i := 0; i < len(a.Abi); i++ {
 		if a.Abi[i] == "" {
diff --git a/android/arch_list.go b/android/arch_list.go
index d68a0d1..79ad4af 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -22,38 +22,12 @@
 		"armv7-a-neon",
 		"armv8-a",
 		"armv8-2a",
-		"cortex-a7",
-		"cortex-a8",
-		"cortex-a9",
-		"cortex-a15",
-		"cortex-a53",
-		"cortex-a53-a57",
-		"cortex-a55",
-		"cortex-a72",
-		"cortex-a73",
-		"cortex-a75",
-		"cortex-a76",
-		"krait",
-		"kryo",
-		"kryo385",
-		"exynos-m1",
-		"exynos-m2",
 	},
 	Arm64: {
-		"armv8_a",
-		"armv8_a_branchprot",
-		"armv8_2a",
+		"armv8-a",
+		"armv8-a-branchprot",
+		"armv8-2a",
 		"armv8-2a-dotprod",
-		"cortex-a53",
-		"cortex-a55",
-		"cortex-a72",
-		"cortex-a73",
-		"cortex-a75",
-		"cortex-a76",
-		"kryo",
-		"kryo385",
-		"exynos-m1",
-		"exynos-m2",
 	},
 	X86: {
 		"amberlake",
@@ -87,6 +61,41 @@
 	},
 }
 
+var cpuVariants = map[ArchType][]string{
+	Arm: {
+		"cortex-a7",
+		"cortex-a8",
+		"cortex-a9",
+		"cortex-a15",
+		"cortex-a53",
+		"cortex-a53.a57",
+		"cortex-a55",
+		"cortex-a72",
+		"cortex-a73",
+		"cortex-a75",
+		"cortex-a76",
+		"krait",
+		"kryo",
+		"kryo385",
+		"exynos-m1",
+		"exynos-m2",
+	},
+	Arm64: {
+		"cortex-a53",
+		"cortex-a55",
+		"cortex-a72",
+		"cortex-a73",
+		"cortex-a75",
+		"cortex-a76",
+		"kryo",
+		"kryo385",
+		"exynos-m1",
+		"exynos-m2",
+	},
+	X86:    {},
+	X86_64: {},
+}
+
 var archFeatures = map[ArchType][]string{
 	Arm: {
 		"neon",
diff --git a/build_test.bash b/build_test.bash
index b6d00e2..1dc6660 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -25,7 +25,9 @@
 
 # Products that are broken or otherwise don't work with multiproduct_kati
 SKIPPED_PRODUCTS=(
+    # Both of these products are for soong-only builds, and will fail the kati stage.
     mainline_sdk
+    ndk
 )
 
 # To track how long we took to startup. %N isn't supported on Darwin, but
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index d789cde..0da51cb 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -37,10 +37,10 @@
 		"": []string{
 			"-march=x86-64",
 		},
+
 		"broadwell": []string{
 			"-march=broadwell",
 		},
-
 		"haswell": []string{
 			"-march=core-avx2",
 		},
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 8282426..2ddd70e 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -496,7 +496,7 @@
 						}
 						return paths[0], nil
 					} else {
-						return reportError("unknown location label %q", label)
+						return reportError("unknown location label %q is not in srcs, out, tools or tool_files.", label)
 					}
 				} else if strings.HasPrefix(name, "locations ") {
 					label := strings.TrimSpace(strings.TrimPrefix(name, "locations "))
@@ -507,7 +507,7 @@
 						}
 						return strings.Join(paths, " "), nil
 					} else {
-						return reportError("unknown locations label %q", label)
+						return reportError("unknown locations label %q is not in srcs, out, tools or tool_files.", label)
 					}
 				} else {
 					return reportError("unknown variable '$(%s)'", name)
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index 04c97fd..1b5cef2 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -341,7 +341,7 @@
 				out: ["out"],
 				cmd: "echo foo > $(location missing)",
 			`,
-			err: `unknown location label "missing"`,
+			err: `unknown location label "missing" is not in srcs, out, tools or tool_files.`,
 		},
 		{
 			name: "error locations",
@@ -349,7 +349,7 @@
 					out: ["out"],
 					cmd: "echo foo > $(locations missing)",
 			`,
-			err: `unknown locations label "missing"`,
+			err: `unknown locations label "missing" is not in srcs, out, tools or tool_files`,
 		},
 		{
 			name: "error location no files",
diff --git a/java/base.go b/java/base.go
index 42d7733..6ff2d03 100644
--- a/java/base.go
+++ b/java/base.go
@@ -227,6 +227,12 @@
 		// whether to generate Binder#GetTransaction name method.
 		Generate_get_transaction_name *bool
 
+		// whether all interfaces should be annotated with required permissions.
+		Enforce_permissions *bool
+
+		// allowlist for interfaces that (temporarily) do not require annotation for permissions.
+		Enforce_permissions_exceptions []string `android:"path"`
+
 		// list of flags that will be passed to the AIDL compiler
 		Flags []string
 	}
@@ -418,7 +424,8 @@
 	outputFile       android.Path
 	extraOutputFiles android.Paths
 
-	exportAidlIncludeDirs android.Paths
+	exportAidlIncludeDirs     android.Paths
+	ignoredAidlPermissionList android.Paths
 
 	logtagsSrcs android.Paths
 
@@ -772,6 +779,17 @@
 	return hasSrcExt(j.properties.Srcs, ext)
 }
 
+func (j *Module) individualAidlFlags(ctx android.ModuleContext, aidlFile android.Path) string {
+	var flags string
+
+	if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
+		if !android.InList(aidlFile.String(), j.ignoredAidlPermissionList.Strings()) {
+			flags = "-Wmissing-permission-annotation -Werror"
+		}
+	}
+	return flags
+}
+
 func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
 	aidlIncludeDirs android.Paths) (string, android.Paths) {
 
@@ -814,6 +832,11 @@
 		flags = append(flags, "--transaction_names")
 	}
 
+	if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
+		exceptions := j.deviceProperties.Aidl.Enforce_permissions_exceptions
+		j.ignoredAidlPermissionList = android.PathsForModuleSrcExcludes(ctx, exceptions, nil)
+	}
+
 	aidlMinSdkVersion := j.MinSdkVersion(ctx).ApiLevel.String()
 	flags = append(flags, "--min_sdk_version="+aidlMinSdkVersion)
 
diff --git a/java/droiddoc.go b/java/droiddoc.go
index c84a15c..023d619 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -330,7 +330,7 @@
 
 	// Process all aidl files together to support sharding them into one or more rules that produce srcjars.
 	if len(aidlSrcs) > 0 {
-		srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
+		srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, nil, flags.aidlDeps)
 		outSrcFiles = append(outSrcFiles, srcJarFiles...)
 	}
 
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 7ad316f..5dc7bc9 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -472,7 +472,8 @@
 		Flag("--quiet").
 		Flag("--format=v2").
 		FlagWithArg("--repeat-errors-max ", "10").
-		FlagWithArg("--hide ", "UnresolvedImport")
+		FlagWithArg("--hide ", "UnresolvedImport").
+		FlagWithArg("--hide ", "InvalidNullability")
 
 	return cmd
 }
diff --git a/java/gen.go b/java/gen.go
index 445a2d8..1572bf0 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -44,7 +44,7 @@
 		})
 )
 
-func genAidl(ctx android.ModuleContext, aidlFiles android.Paths, aidlFlags string, deps android.Paths) android.Paths {
+func genAidl(ctx android.ModuleContext, aidlFiles android.Paths, aidlGlobalFlags string, aidlIndividualFlags map[string]string, deps android.Paths) android.Paths {
 	// Shard aidl files into groups of 50 to avoid having to recompile all of them if one changes and to avoid
 	// hitting command line length limits.
 	shards := android.ShardPaths(aidlFiles, 50)
@@ -61,15 +61,17 @@
 
 		rule.Command().Text("rm -rf").Flag(outDir.String())
 		rule.Command().Text("mkdir -p").Flag(outDir.String())
-		rule.Command().Text("FLAGS=' " + aidlFlags + "'")
+		rule.Command().Text("FLAGS=' " + aidlGlobalFlags + "'")
 
 		for _, aidlFile := range shard {
+			localFlag := aidlIndividualFlags[aidlFile.String()]
 			depFile := srcJarFile.InSameDir(ctx, aidlFile.String()+".d")
 			javaFile := outDir.Join(ctx, pathtools.ReplaceExtension(aidlFile.String(), "java"))
 			rule.Command().
 				Tool(ctx.Config().HostToolPath(ctx, "aidl")).
 				FlagWithDepFile("-d", depFile).
 				Flag("$FLAGS").
+				Flag(localFlag).
 				Input(aidlFile).
 				Output(javaFile).
 				Implicits(deps)
@@ -159,7 +161,14 @@
 
 	// Process all aidl files together to support sharding them into one or more rules that produce srcjars.
 	if len(aidlSrcs) > 0 {
-		srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
+		individualFlags := make(map[string]string)
+		for _, aidlSrc := range aidlSrcs {
+			flags := j.individualAidlFlags(ctx, aidlSrc)
+			if flags != "" {
+				individualFlags[aidlSrc.String()] = flags
+			}
+		}
+		srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, individualFlags, flags.aidlDeps)
 		outSrcFiles = append(outSrcFiles, srcJarFiles...)
 	}
 
diff --git a/java/java_test.go b/java/java_test.go
index 21c76b6..f095c5e 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1333,6 +1333,42 @@
 	}
 }
 
+func TestAidlEnforcePermissions(t *testing.T) {
+	ctx, _ := testJava(t, `
+		java_library {
+			name: "foo",
+			srcs: ["aidl/foo/IFoo.aidl"],
+			aidl: { enforce_permissions: true },
+		}
+	`)
+
+	aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+	expectedAidlFlag := "-Wmissing-permission-annotation -Werror"
+	if !strings.Contains(aidlCommand, expectedAidlFlag) {
+		t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
+	}
+}
+
+func TestAidlEnforcePermissionsException(t *testing.T) {
+	ctx, _ := testJava(t, `
+		java_library {
+			name: "foo",
+			srcs: ["aidl/foo/IFoo.aidl", "aidl/foo/IFoo2.aidl"],
+			aidl: { enforce_permissions: true, enforce_permissions_exceptions: ["aidl/foo/IFoo2.aidl"] },
+		}
+	`)
+
+	aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+	expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl"
+	if !strings.Contains(aidlCommand, expectedAidlFlag) {
+		t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
+	}
+	expectedAidlFlag = "$$FLAGS  aidl/foo/IFoo2.aidl"
+	if !strings.Contains(aidlCommand, expectedAidlFlag) {
+		t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
+	}
+}
+
 func TestDataNativeBinaries(t *testing.T) {
 	ctx, _ := testJava(t, `
 		java_test_host {
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index 1574587..b57963b 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -19,56 +19,9 @@
     exit 1
 fi
 
-TOP=$(pwd)
-
-source build/envsetup.sh
-PLATFORM_SDK_VERSION=$(get_build_var PLATFORM_SDK_VERSION)
-PLATFORM_BASE_SDK_EXTENSION_VERSION=$(get_build_var PLATFORM_BASE_SDK_EXTENSION_VERSION)
-PLATFORM_VERSION_ALL_CODENAMES=$(get_build_var PLATFORM_VERSION_ALL_CODENAMES)
-
-# PLATFORM_VERSION_ALL_CODENAMES is a comma separated list like O,P. We need to
-# turn this into ["O","P"].
-PLATFORM_VERSION_ALL_CODENAMES=${PLATFORM_VERSION_ALL_CODENAMES/,/'","'}
-PLATFORM_VERSION_ALL_CODENAMES="[\"${PLATFORM_VERSION_ALL_CODENAMES}\"]"
-
-# Get the list of missing <uses-library> modules and convert it to a JSON array
-# (quote module names, add comma separator and wrap in brackets).
-MISSING_USES_LIBRARIES="$(get_build_var INTERNAL_PLATFORM_MISSING_USES_LIBRARIES)"
-MISSING_USES_LIBRARIES="[$(echo $MISSING_USES_LIBRARIES | sed -e 's/\([^ ]\+\)/\"\1\"/g' -e 's/[ ]\+/, /g')]"
-
-SOONG_OUT=${OUT_DIR}/soong
-SOONG_NDK_OUT=${OUT_DIR}/soong/ndk
-rm -rf ${SOONG_OUT}
-mkdir -p ${SOONG_OUT}
-
-# We only really need to set some of these variables, but soong won't merge this
-# with the defaults, so we need to write out all the defaults with our values
-# added.
-cat > ${SOONG_OUT}/soong.variables << EOF
-{
-    "Platform_sdk_version": ${PLATFORM_SDK_VERSION},
-    "Platform_base_sdk_extension_version": ${PLATFORM_BASE_SDK_EXTENSION_VERSION},
-    "Platform_version_active_codenames": ${PLATFORM_VERSION_ALL_CODENAMES},
-
-    "DeviceName": "generic_arm64",
-    "HostArch": "x86_64",
-    "Malloc_not_svelte": false,
-    "Safestack": false,
-
-    "Ndk_abis": true,
-
-    "VendorVars": {
-        "art_module": {
-            "source_build": "true"
-        }
-    },
-
-    "MissingUsesLibraries": ${MISSING_USES_LIBRARIES}
-}
-EOF
-m --soong-only --skip-config ${SOONG_OUT}/ndk.timestamp
+TARGET_PRODUCT=ndk build/soong/soong_ui.bash --make-mode --soong-only ${OUT_DIR}/soong/ndk.timestamp
 
 if [ -n "${DIST_DIR}" ]; then
     mkdir -p ${DIST_DIR} || true
-    tar cjf ${DIST_DIR}/ndk_platform.tar.bz2 -C ${SOONG_OUT} ndk
+    tar cjf ${DIST_DIR}/ndk_platform.tar.bz2 -C ${OUT_DIR}/soong ndk
 fi