Merge "Make manifest and APK agree on uncompressed native libs"
diff --git a/android/paths.go b/android/paths.go
index 4b35fef..0c65b83 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -244,7 +244,7 @@
 		}
 		path := filepath.Clean(p)
 		if !strings.HasPrefix(path, prefix) {
-			reportPathErrorf(ctx, "Path '%s' is not in module source directory '%s'", p, prefix)
+			reportPathErrorf(ctx, "Path %q is not in module source directory %q", p, prefix)
 			continue
 		}
 
@@ -505,7 +505,7 @@
 
 	// absolute path already checked by validateSafePath
 	if strings.HasPrefix(ret.String(), ctx.Config().buildDir) {
-		return ret, fmt.Errorf("source path %s is in output", ret.String())
+		return ret, fmt.Errorf("source path %q is in output", ret.String())
 	}
 
 	return ret, err
@@ -521,7 +521,7 @@
 
 	// absolute path already checked by validatePath
 	if strings.HasPrefix(ret.String(), ctx.Config().buildDir) {
-		return ret, fmt.Errorf("source path %s is in output", ret.String())
+		return ret, fmt.Errorf("source path %q is in output", ret.String())
 	}
 
 	return ret, nil
@@ -575,7 +575,7 @@
 	} else if exists, _, err := ctx.Fs().Exists(path.String()); err != nil {
 		reportPathErrorf(ctx, "%s: %s", path, err.Error())
 	} else if !exists {
-		reportPathErrorf(ctx, "source path %s does not exist", path)
+		reportPathErrorf(ctx, "source path %q does not exist", path)
 	}
 	return path
 }
@@ -740,7 +740,7 @@
 	if exists, _, err := ctx.Fs().Exists(path.String()); err != nil {
 		reportPathErrorf(ctx, "%s: %s", path, err.Error())
 	} else if !exists {
-		reportPathErrorf(ctx, "module source path %s does not exist", path)
+		reportPathErrorf(ctx, "module source path %q does not exist", path)
 	}
 
 	return path
diff --git a/apex/apex.go b/apex/apex.go
index 092868e..95cee0c 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -136,7 +136,8 @@
 	pctx.HostBinToolVariable("zip2zip", "zip2zip")
 	pctx.HostBinToolVariable("zipalign", "zipalign")
 
-	android.RegisterModuleType("apex", ApexBundleFactory)
+	android.RegisterModuleType("apex", apexBundleFactory)
+	android.RegisterModuleType("apex_test", testApexBundleFactory)
 	android.RegisterModuleType("apex_defaults", defaultsFactory)
 
 	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -154,7 +155,7 @@
 			depName := mctx.OtherModuleName(child)
 			// If the parent is apexBundle, this child is directly depended.
 			_, directDep := parent.(*apexBundle)
-			if a.installable() {
+			if a.installable() && !a.testApex {
 				// TODO(b/123892969): Workaround for not having any way to annotate test-apexs
 				// non-installable apex's cannot be installed and so should not prevent libraries from being
 				// installed to the system.
@@ -375,6 +376,8 @@
 	filesInfo []apexFile
 
 	flattened bool
+
+	testApex bool
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -1091,9 +1094,18 @@
 		}}
 }
 
-func ApexBundleFactory() android.Module {
+func testApexBundleFactory() android.Module {
+	return ApexBundleFactory( /*testApex*/ true)
+}
+
+func apexBundleFactory() android.Module {
+	return ApexBundleFactory( /*testApex*/ false)
+}
+
+func ApexBundleFactory(testApex bool) android.Module {
 	module := &apexBundle{
 		outputFiles: map[apexPackaging]android.WritablePath{},
+		testApex:    testApex,
 	}
 	module.AddProperties(&module.properties)
 	module.AddProperties(&module.targetProperties)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 6163d0f..2c7f285 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -31,7 +31,8 @@
 	defer teardown(buildDir)
 
 	ctx := android.NewTestArchContext()
-	ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(ApexBundleFactory))
+	ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(apexBundleFactory))
+	ctx.RegisterModuleType("apex_test", android.ModuleFactoryAdaptor(testApexBundleFactory))
 	ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apexKeyFactory))
 	ctx.RegisterModuleType("apex_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
@@ -904,6 +905,105 @@
 	ensureContains(t, cFlags, "-Imy_include")
 }
 
+func TestNonTestApex(t *testing.T) {
+	ctx := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			native_shared_libs: ["mylib_common"],
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "mylib_common",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`)
+
+	module := ctx.ModuleForTests("myapex", "android_common_myapex")
+	apexRule := module.Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+
+	if apex, ok := module.Module().(*apexBundle); !ok || apex.testApex {
+		t.Log("Apex was a test apex!")
+		t.Fail()
+	}
+	// Ensure that main rule creates an output
+	ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
+
+	// Ensure that apex variant is created for the direct dep
+	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_core_shared_myapex")
+
+	// Ensure that both direct and indirect deps are copied into apex
+	ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so")
+
+	// Ensure that the platform variant ends with _core_shared
+	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_core_shared")
+
+	if !android.InAnyApex("mylib_common") {
+		t.Log("Found mylib_common not in any apex!")
+		t.Fail()
+	}
+}
+
+func TestTestApex(t *testing.T) {
+	if android.InAnyApex("mylib_common_test") {
+		t.Fatal("mylib_common_test must not be used in any other tests since this checks that global state is not updated in an illegal way!")
+	}
+	ctx := testApex(t, `
+		apex_test {
+			name: "myapex",
+			key: "myapex.key",
+			native_shared_libs: ["mylib_common_test"],
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "mylib_common_test",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`)
+
+	module := ctx.ModuleForTests("myapex", "android_common_myapex")
+	apexRule := module.Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+
+	if apex, ok := module.Module().(*apexBundle); !ok || !apex.testApex {
+		t.Log("Apex was not a test apex!")
+		t.Fail()
+	}
+	// Ensure that main rule creates an output
+	ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
+
+	// Ensure that apex variant is created for the direct dep
+	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_core_shared_myapex")
+
+	// Ensure that both direct and indirect deps are copied into apex
+	ensureContains(t, copyCmds, "image.apex/lib64/mylib_common_test.so")
+
+	// Ensure that the platform variant ends with _core_shared
+	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_core_shared")
+
+	if android.InAnyApex("mylib_common_test") {
+		t.Log("Found mylib_common_test in some apex!")
+		t.Fail()
+	}
+}
+
 func TestApexWithTarget(t *testing.T) {
 	ctx := testApex(t, `
 		apex {
diff --git a/cc/gen_stub_libs.py b/cc/gen_stub_libs.py
index 4906ea2..81bc398 100755
--- a/cc/gen_stub_libs.py
+++ b/cc/gen_stub_libs.py
@@ -119,9 +119,12 @@
         return True
     if 'platform-only' in version.tags:
         return True
-    if 'vndk' in version.tags and not vndk:
-        return True
-    if 'apex' in version.tags and not apex:
+
+    no_vndk_no_apex = 'vndk' not in version.tags and 'apex' not in version.tags
+    keep = no_vndk_no_apex or \
+           ('vndk' in version.tags and vndk) or \
+           ('apex' in version.tags and apex)
+    if not keep:
         return True
     if not symbol_in_arch(version.tags, arch):
         return True
@@ -132,9 +135,11 @@
 
 def should_omit_symbol(symbol, arch, api, vndk, apex):
     """Returns True if the symbol should be omitted."""
-    if not vndk and 'vndk' in symbol.tags:
-        return True
-    if not apex and 'apex' in symbol.tags:
+    no_vndk_no_apex = 'vndk' not in symbol.tags and 'apex' not in symbol.tags
+    keep = no_vndk_no_apex or \
+           ('vndk' in symbol.tags and vndk) or \
+           ('apex' in symbol.tags and apex)
+    if not keep:
         return True
     if not symbol_in_arch(symbol.tags, arch):
         return True
diff --git a/cc/test_gen_stub_libs.py b/cc/test_gen_stub_libs.py
index 594c1bc..2ee9886 100755
--- a/cc/test_gen_stub_libs.py
+++ b/cc/test_gen_stub_libs.py
@@ -751,6 +751,8 @@
                 wibble;
                 wizzes; # vndk
                 waggle; # apex
+                bubble; # apex vndk
+                duddle; # vndk apex
             } VERSION_2;
 
             VERSION_5 { # versioned=14
@@ -771,6 +773,8 @@
             void qux() {}
             void wibble() {}
             void waggle() {}
+            void bubble() {}
+            void duddle() {}
             void wobble() {}
         """)
         self.assertEqual(expected_src, src_file.getvalue())
@@ -788,6 +792,8 @@
                 global:
                     wibble;
                     waggle;
+                    bubble;
+                    duddle;
             } VERSION_2;
         """)
         self.assertEqual(expected_version, version_file.getvalue())
diff --git a/java/androidmk.go b/java/androidmk.go
index 089ed4f..d86e71f 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -203,6 +203,11 @@
 		Include:    "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
 		Extra: []android.AndroidMkExtraFunc{
 			func(w io.Writer, outputFile android.Path) {
+				// TODO(jungjw): This, outputting two LOCAL_MODULE lines, works, but is not ideal. Find a better solution.
+				if app.Name() != app.installApkName {
+					fmt.Fprintln(w, "# Overridden by PRODUCT_PACKAGE_NAME_OVERRIDES")
+					fmt.Fprintln(w, "LOCAL_MODULE :=", app.installApkName)
+				}
 				fmt.Fprintln(w, "LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=", app.exportPackage.String())
 				if app.dexJarFile != nil {
 					fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", app.dexJarFile.String())
@@ -247,8 +252,8 @@
 				}
 
 				fmt.Fprintln(w, "LOCAL_CERTIFICATE :=", app.certificate.Pem.String())
-				if len(app.appProperties.Overrides) > 0 {
-					fmt.Fprintln(w, "LOCAL_OVERRIDES_PACKAGES := "+strings.Join(app.appProperties.Overrides, " "))
+				if overriddenPkgs := app.getOverriddenPackages(); len(overriddenPkgs) > 0 {
+					fmt.Fprintln(w, "LOCAL_OVERRIDES_PACKAGES :=", strings.Join(overriddenPkgs, " "))
 				}
 
 				for _, jniLib := range app.installJniLibs {
@@ -262,6 +267,17 @@
 	}
 }
 
+func (a *AndroidApp) getOverriddenPackages() []string {
+	var overridden []string
+	if len(a.appProperties.Overrides) > 0 {
+		overridden = append(overridden, a.appProperties.Overrides...)
+	}
+	if a.Name() != a.installApkName {
+		overridden = append(overridden, a.Name())
+	}
+	return overridden
+}
+
 func (a *AndroidTest) AndroidMk() android.AndroidMkData {
 	data := a.AndroidApp.AndroidMk()
 	data.Extra = append(data.Extra, func(w io.Writer, outputFile android.Path) {