Merge "Add no_apex property"
diff --git a/android/apex.go b/android/apex.go
index 17df762..99b13ab 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -19,6 +19,7 @@
 	"sync"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 )
 
 // ApexModule is the interface that a module type is expected to implement if
@@ -74,9 +75,15 @@
 	// Sets the name of the apex variant of this module. Called inside
 	// CreateApexVariations.
 	setApexName(apexName string)
+
+	// Return the no_apex property
+	NoApex() bool
 }
 
 type ApexProperties struct {
+	// Whether this module should not be part of any APEX. Default is false.
+	No_apex *bool
+
 	// Name of the apex variant that this module is mutated into
 	ApexName string `blueprint:"mutated"`
 }
@@ -125,6 +132,10 @@
 	return false
 }
 
+func (m *ApexModuleBase) NoApex() bool {
+	return proptools.Bool(m.ApexProperties.No_apex)
+}
+
 func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []blueprint.Module {
 	if len(m.apexVariations) > 0 {
 		sort.Strings(m.apexVariations)
diff --git a/apex/apex.go b/apex/apex.go
index fdb1cfc..9e7f3a0 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -126,6 +126,16 @@
 	usesTag        = dependencyTag{name: "uses"}
 )
 
+var (
+	whitelistNoApex = map[string][]string{
+		"apex_test_build_features":       []string{"libbinder"},
+		"com.android.neuralnetworks":     []string{"libbinder"},
+		"com.android.media":              []string{"libbinder"},
+		"com.android.media.swcodec":      []string{"libbinder"},
+		"test_com.android.media.swcodec": []string{"libbinder"},
+	}
+)
+
 func init() {
 	pctx.Import("android/soong/android")
 	pctx.Import("android/soong/java")
@@ -1005,6 +1015,16 @@
 		return filesInfo[i].builtFile.String() < filesInfo[j].builtFile.String()
 	})
 
+	// check no_apex modules
+	whitelist := whitelistNoApex[ctx.ModuleName()]
+	for i := range filesInfo {
+		if am, ok := filesInfo[i].module.(android.ApexModule); ok {
+			if am.NoApex() && !android.InList(filesInfo[i].moduleName, whitelist) {
+				ctx.ModuleErrorf("tries to include no_apex module %s", filesInfo[i].moduleName)
+			}
+		}
+	}
+
 	// prepend the name of this APEX to the module names. These names will be the names of
 	// modules that will be defined if the APEX is flattened.
 	for i := range filesInfo {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 82c5909..387533c 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -1820,6 +1820,88 @@
 	`)
 }
 
+func TestApexUsesFailsIfUseNoApex(t *testing.T) {
+	testApexError(t, `tries to include no_apex module mylib2`, `
+		apex {
+			name: "commonapex",
+			key: "myapex.key",
+			native_shared_libs: ["mylib"],
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "mylib",
+			srcs: ["mylib.cpp"],
+			shared_libs: ["mylib2"],
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		cc_library {
+			name: "mylib2",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			no_apex: true,
+		}
+	`)
+
+	ctx, _ := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			native_shared_libs: ["mylib"],
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "mylib",
+			srcs: ["mylib.cpp"],
+			shared_libs: ["mylib2"],
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		cc_library {
+			name: "mylib2",
+			srcs: ["mylib.cpp"],
+			shared_libs: ["mylib3"],
+			system_shared_libs: [],
+			stl: "none",
+			stubs: {
+				versions: ["1", "2", "3"],
+			},
+		}
+
+		cc_library {
+			name: "mylib3",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			no_apex: true,
+		}
+	`)
+
+	module := ctx.ModuleForTests("myapex", "android_common_myapex")
+	apexRule := module.Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+
+	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+	ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+	ensureNotContains(t, copyCmds, "image.apex/lib64/mylib3.so")
+
+}
+
 func TestMain(m *testing.M) {
 	run := func() int {
 		setUp()