Reland: NDK backends supports both apps and platform

Previously, the ndk backend was for apps, and the ndk_platform backend
was for platform. However, this has not only caused confusion to the
users, but also added unnecessary complexity as the ndk backend actually
has "two" variants 'sdk' and 'platform' by the sdkMutator in Soong. The
'platform' variant can replace the ndk_platform backend.

This change is the first step to remove the ndk_platform backend. The
'platform' variant of the ndk backend now has the same dependencies as
the ndk_platform backend. This is achieved by using the target specific
properties which adds and removes dependencies for the non-app variants.

The next step will be actually replacing the references to
*-ndk_platform modules with the corresponding *-ndk modules. After that
is done, the ndk_platform backend will be removed.

Ignore-AOSP-First: needs c/p's

Bug: 161456198
Test: m
Merged-In: Id5f5a4b218b601907c306bc8287c0d511ad84668
Change-Id: Id5f5a4b218b601907c306bc8287c0d511ad84668
(cherry picked from commit cdb32cc359e0f3be9694e83ac11fc8b2b4883dab)
diff --git a/build/aidl_interface.go b/build/aidl_interface.go
index 251d0d6..80ba3d6 100644
--- a/build/aidl_interface.go
+++ b/build/aidl_interface.go
@@ -40,8 +40,10 @@
 	langCpp                   = "cpp"
 	langJava                  = "java"
 	langNdk                   = "ndk"
-	langNdkPlatform           = "ndk_platform"
 	langRust                  = "rust"
+	// TODO(b/161456198) remove the NDK platform backend as the 'platform' variant of the NDK
+	// backend serves the same purpose.
+	langNdkPlatform = "ndk_platform"
 
 	currentVersion = "current"
 )
@@ -380,19 +382,18 @@
 		Cpp struct {
 			CommonNativeBackendProperties
 		}
-		// Backend of the compiler generating code for C++ clients using
-		// libbinder_ndk (stable C interface to system's libbinder)
-		// When enabled, this creates a target called "<name>-ndk"
-		// (for apps) and "<name>-ndk_platform" (for platform usage).
+		// Backend of the compiler generating code for C++ clients using libbinder_ndk
+		// (stable C interface to system's libbinder) When enabled, this creates a target
+		// called "<name>-V<ver>-ndk" (for both apps and platform) and
+		// "<name>-V<ver>-ndk_platform" (for platform only).
+		// TODO(b/161456198): remove the ndk_platform backend as the ndk backend can serve
+		// the same purpose.
 		Ndk struct {
 			CommonNativeBackendProperties
 
-			// Currently, all ndk-supported interfaces generate two variants:
-			// - ndk - for apps to use, against an NDK
-			// - ndk_platform - for the platform to use
-			//
-			// This adds an option to disable the 'ndk' variant in cases where APIs
-			// only available in the platform version work.
+			// If set to false, the ndk backend is exclusive to platform and is not
+			// available to applications. Default is true (i.e. available to both
+			// applications and platform).
 			Apps_enabled *bool
 		}
 		// Backend of the compiler generating code for Rust clients.
@@ -426,25 +427,27 @@
 
 func (i *aidlInterface) shouldGenerateJavaBackend() bool {
 	// explicitly true if not specified to give early warning to devs
-	return i.properties.Backend.Java.Enabled == nil || *i.properties.Backend.Java.Enabled
+	return proptools.BoolDefault(i.properties.Backend.Java.Enabled, true)
 }
 
 func (i *aidlInterface) shouldGenerateCppBackend() bool {
 	// explicitly true if not specified to give early warning to devs
-	return i.properties.Backend.Cpp.Enabled == nil || *i.properties.Backend.Cpp.Enabled
+	return proptools.BoolDefault(i.properties.Backend.Cpp.Enabled, true)
 }
 
 func (i *aidlInterface) shouldGenerateNdkBackend() bool {
 	// explicitly true if not specified to give early warning to devs
+	return proptools.BoolDefault(i.properties.Backend.Ndk.Enabled, true)
 	return i.properties.Backend.Ndk.Enabled == nil || *i.properties.Backend.Ndk.Enabled
 }
 
+// Returns whether the ndk backend supports applications or not. Default is `true`. `false` is
+// returned only when `apps_enabled` is explicitly set to false. Note that the ndk_platform backend
+// (which will be removed in the future) is not affected by this. In other words, it is always
+// exclusive for the platform, as its name clearly shows.
 func (i *aidlInterface) shouldGenerateAppNdkBackend() bool {
-	if !i.shouldGenerateNdkBackend() {
-		return false
-	}
-	// explicitly true if not specified to give early warning to devs
-	return i.properties.Backend.Ndk.Apps_enabled == nil || *i.properties.Backend.Ndk.Apps_enabled
+	return i.shouldGenerateNdkBackend() &&
+		proptools.BoolDefault(i.properties.Backend.Ndk.Apps_enabled, true)
 }
 
 func (i *aidlInterface) shouldGenerateRustBackend() bool {
@@ -685,7 +688,7 @@
 	nextVersion := i.nextVersion()
 	shouldGenerateLangBackendMap := map[string]bool{
 		langCpp:         i.shouldGenerateCppBackend(),
-		langNdk:         i.shouldGenerateAppNdkBackend(),
+		langNdk:         i.shouldGenerateNdkBackend(),
 		langNdkPlatform: i.shouldGenerateNdkBackend(),
 		langJava:        i.shouldGenerateJavaBackend(),
 		langRust:        i.shouldGenerateRustBackend()}
diff --git a/build/aidl_interface_backends.go b/build/aidl_interface_backends.go
index 79b6625..6c778af 100644
--- a/build/aidl_interface_backends.go
+++ b/build/aidl_interface_backends.go
@@ -97,6 +97,19 @@
 	var cpp_std *string
 	var hostSupported *bool
 	var addCflags []string
+	targetProp := ccTargetProperties{
+		// Currently necessary for host builds
+		// TODO(b/31559095): bionic on host should define this
+		// TODO(b/146436251): default isn't applied because the module is created
+		// in PreArchMutators, when import behavior becomes explicit, the logic can
+		// be moved back to LoadHook
+		Host: hostProperties{Cflags: []string{
+			"-D__INTRODUCED_IN(n)=",
+			"-D__assert(a,b,c)=",
+			// We want all the APIs to be available on the host.
+			"-D__ANDROID_API__=10000"}},
+		Darwin: darwinProperties{Enabled: proptools.BoolPtr(false)},
+	}
 
 	if lang == langCpp {
 		importExportDependencies = append(importExportDependencies, "libbinder", "libutils")
@@ -105,23 +118,27 @@
 		}
 		hostSupported = i.properties.Host_supported
 		minSdkVersion = i.properties.Backend.Cpp.Min_sdk_version
-	} else if lang == langNdk {
+	} else if lang == langNdk || lang == langNdkPlatform {
 		importExportDependencies = append(importExportDependencies, "libbinder_ndk")
+		nonAppProps := imageProperties{
+			Cflags: []string{"-DBINDER_STABILITY_SUPPORT"},
+		}
 		if genTrace {
 			sharedLibDependency = append(sharedLibDependency, "libandroid")
+			nonAppProps.Exclude_shared_libs = []string{"libandroid"}
+			nonAppProps.Header_libs = []string{"libandroid_aidltrace"}
+			nonAppProps.Shared_libs = []string{"libcutils"}
 		}
-		sdkVersion = proptools.StringPtr("current")
-		stl = proptools.StringPtr("c++_shared")
+		targetProp.Platform = nonAppProps
+		targetProp.Vendor = nonAppProps
+		targetProp.Product = nonAppProps
 		minSdkVersion = i.properties.Backend.Ndk.Min_sdk_version
-	} else if lang == langNdkPlatform {
-		importExportDependencies = append(importExportDependencies, "libbinder_ndk")
-		if genTrace {
-			headerLibs = append(headerLibs, "libandroid_aidltrace")
-			sharedLibDependency = append(sharedLibDependency, "libcutils")
-		}
 		hostSupported = i.properties.Host_supported
-		addCflags = append(addCflags, "-DBINDER_STABILITY_SUPPORT")
-		minSdkVersion = i.properties.Backend.Ndk.Min_sdk_version
+		if lang == langNdk && i.shouldGenerateAppNdkBackend() {
+			sdkVersion = proptools.StringPtr("current")
+			// Don't worry! This maps to libc++.so for the platform variant.
+			stl = proptools.StringPtr("c++_shared")
+		}
 	} else {
 		panic("Unrecognized language: " + lang)
 	}
@@ -145,19 +162,6 @@
 		productAvailable = nil
 	}
 
-	if lang == langNdk {
-		// TODO(b/121157555): when the NDK variant is its own variant, these wouldn't interact,
-		// but we can't create a vendor or product version of an NDK variant
-		//
-		// nil (unspecified) is used instead of false so that this can't conflict with
-		// 'vendor: true', for instance.
-		vendorAvailable = nil
-		odmAvailable = nil
-		productAvailable = nil
-		overrideVndkProperties.Vndk.Enabled = proptools.BoolPtr(false)
-		overrideVndkProperties.Vndk.Support_system_process = proptools.BoolPtr(false)
-	}
-
 	mctx.CreateModule(aidlImplementationGeneratorFactory, &nameProperties{
 		Name: proptools.StringPtr(cppModuleGen + "-generator"),
 	}, &aidlImplementationGeneratorProperties{
@@ -186,19 +190,8 @@
 				Apex_available:            commonProperties.Apex_available,
 				Min_sdk_version:           minSdkVersion,
 				UseApexNameMacro:          true,
-				Target: ccTargetProperties{
-					// Currently necessary for host builds
-					// TODO(b/31559095): bionic on host should define this
-					// TODO(b/146436251): default isn't applied because the module is created
-					// in PreArchMutators, when import behavior becomes explicit, the logic can
-					// be moved back to LoadHook
-					Host: hostProperties{Cflags: []string{
-						"-D__INTRODUCED_IN(n)=",
-						"-D__assert(a,b,c)=",
-						// We want all the APIs to be available on the host.
-						"-D__ANDROID_API__=10000"}},
-					Darwin: perTargetProperties{Enabled: proptools.BoolPtr(false)}},
-				Tidy: proptools.BoolPtr(true),
+				Target:                    targetProp,
+				Tidy:                      proptools.BoolPtr(true),
 				// Do the tidy check only for the generated headers
 				Tidy_flags:            []string{"--header-filter=" + android.PathForOutput(mctx).String() + ".*"},
 				Tidy_checks_as_errors: []string{"*"},
@@ -303,7 +296,7 @@
 		Defaults:       []string{"aidl-rust-module-defaults"},
 		Host_supported: i.properties.Host_supported,
 		Apex_available: i.properties.Backend.Rust.Apex_available,
-		Target:         rustTargetProperties{Darwin: perTargetProperties{Enabled: proptools.BoolPtr(false)}},
+		Target:         rustTargetProperties{Darwin: darwinProperties{Enabled: proptools.BoolPtr(false)}},
 	}, &rust.SourceProviderProperties{
 		Source_stem: proptools.StringPtr(versionedRustName),
 	}, &aidlRustSourceProviderProperties{
diff --git a/build/properties.go b/build/properties.go
index 69914ed..1b302a9 100644
--- a/build/properties.go
+++ b/build/properties.go
@@ -21,17 +21,28 @@
 type hostProperties struct {
 	Cflags []string
 }
-type perTargetProperties struct {
+
+type darwinProperties struct {
 	Enabled *bool
 }
 
+type imageProperties struct {
+	Shared_libs         []string
+	Header_libs         []string
+	Exclude_shared_libs []string
+	Cflags              []string
+}
+
 type ccTargetProperties struct {
-	Host   hostProperties
-	Darwin perTargetProperties
+	Host     hostProperties
+	Darwin   darwinProperties
+	Platform imageProperties
+	Vendor   imageProperties
+	Product  imageProperties
 }
 
 type rustTargetProperties struct {
-	Darwin perTargetProperties
+	Darwin darwinProperties
 }
 
 type ccProperties struct {