Revert "use symlink for bundled APEX"

This reverts commit 58ab941c6cc39285925873ac4cd13ffc9d5a3ba3.

Reason for revert: art-com_android_runtime_host-linux_bionic and art-linux-bionic-zipapex builds failing (https://android-build.googleplex.com/builds/submitted/6131062/art-com_android_runtime_host-linux_bionic/latest/view/logs/build.log)

Bug: 144533348
Change-Id: I040af6887aea205a5d72a416fc8e6533dcfa08dd
diff --git a/apex/androidmk.go b/apex/androidmk.go
index d5ab1f6..9aa0894 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -52,40 +52,13 @@
 		return moduleNames
 	}
 
-	var postInstallCommands []string
-	for _, fi := range a.filesInfo {
-		if a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform() {
-			// TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
-			linkTarget := filepath.Join("/system", fi.Path())
-			linkPath := filepath.Join(a.installDir.ToMakePath().String(), apexName, fi.Path())
-			mkdirCmd := "mkdir -p " + filepath.Dir(linkPath)
-			linkCmd := "ln -s " + linkTarget + " " + linkPath
-			postInstallCommands = append(postInstallCommands, mkdirCmd, linkCmd)
-		}
-	}
-	postInstallCommands = append(postInstallCommands, a.compatSymlinks...)
-
 	for _, fi := range a.filesInfo {
 		if cc, ok := fi.module.(*cc.Module); ok && cc.Properties.HideFromMake {
 			continue
 		}
 
-		linkToSystemLib := a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform()
-
-		var moduleName string
-		if linkToSystemLib {
-			moduleName = fi.moduleName
-		} else {
-			moduleName = fi.moduleName + "." + apexName + a.suffix
-		}
-
-		if !android.InList(moduleName, moduleNames) {
-			moduleNames = append(moduleNames, moduleName)
-		}
-
-		if linkToSystemLib {
-			// No need to copy the file since it's linked to the system file
-			continue
+		if !android.InList(fi.moduleName, moduleNames) {
+			moduleNames = append(moduleNames, fi.moduleName)
 		}
 
 		fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
@@ -94,7 +67,7 @@
 		} else {
 			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
 		}
-		fmt.Fprintln(w, "LOCAL_MODULE :=", moduleName)
+		fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName)
 		// /apex/<apex_name>/{lib|framework|...}
 		pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", apexName, fi.installDir)
 		if apexType == flattenedApex {
@@ -170,8 +143,8 @@
 		} else {
 			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
 			// For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex
-			if a.primaryApexType && apexType == flattenedApex && fi.builtFile == a.manifestPbOut && len(postInstallCommands) > 0 {
-				fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(postInstallCommands, " && "))
+			if a.primaryApexType && fi.builtFile == a.manifestPbOut && len(a.compatSymlinks) > 0 {
+				fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(a.compatSymlinks, " && "))
 			}
 			fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
 		}
diff --git a/apex/apex.go b/apex/apex.go
index 0dbd280..9867a7a 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -488,30 +488,6 @@
 	return af.builtFile != nil && af.builtFile.String() != ""
 }
 
-// Path() returns path of this apex file relative to the APEX root
-func (af *apexFile) Path() string {
-	return filepath.Join(af.installDir, af.builtFile.Base())
-}
-
-// SymlinkPaths() returns paths of the symlinks (if any) relative to the APEX root
-func (af *apexFile) SymlinkPaths() []string {
-	var ret []string
-	for _, symlink := range af.symlinks {
-		ret = append(ret, filepath.Join(af.installDir, symlink))
-	}
-	return ret
-}
-
-func (af *apexFile) AvailableToPlatform() bool {
-	if af.module == nil {
-		return false
-	}
-	if am, ok := af.module.(android.ApexModule); ok {
-		return am.AvailableFor(android.AvailableToPlatform)
-	}
-	return false
-}
-
 type apexBundle struct {
 	android.ModuleBase
 	android.DefaultableModuleBase
@@ -562,10 +538,6 @@
 	// Suffix of module name in Android.mk
 	// ".flattened", ".apex", ".zipapex", or ""
 	suffix string
-
-	// Whether to create symlink to the system file instead of having a file
-	// inside the apex or not
-	linkToSystemLib bool
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -1169,8 +1141,7 @@
 						// of the original test module (`depName`, shared by all `test_per_src`
 						// variations of that module).
 						af.moduleName = filepath.Base(af.builtFile.String())
-						// these are not considered transitive dep
-						af.transitiveDep = false
+						af.transitiveDep = true
 						filesInfo = append(filesInfo, af)
 						return true // track transitive dependencies
 					}
@@ -1206,22 +1177,15 @@
 
 	// remove duplicates in filesInfo
 	removeDup := func(filesInfo []apexFile) []apexFile {
-		encountered := make(map[string]apexFile)
+		encountered := make(map[string]bool)
+		result := []apexFile{}
 		for _, f := range filesInfo {
 			dest := filepath.Join(f.installDir, f.builtFile.Base())
-			if e, ok := encountered[dest]; !ok {
-				encountered[dest] = f
-			} else {
-				// If a module is directly included and also transitively depended on
-				// consider it as directly included.
-				e.transitiveDep = e.transitiveDep && f.transitiveDep
-				encountered[dest] = e
+			if !encountered[dest] {
+				encountered[dest] = true
+				result = append(result, f)
 			}
 		}
-		var result []apexFile
-		for _, v := range encountered {
-			result = append(result, v)
-		}
 		return result
 	}
 	filesInfo = removeDup(filesInfo)
@@ -1243,6 +1207,12 @@
 		}
 	}
 
+	// 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 {
+		filesInfo[i].moduleName = filesInfo[i].moduleName + "." + a.Name() + a.suffix
+	}
+
 	a.installDir = android.PathForModuleInstall(ctx, "apex")
 	a.filesInfo = filesInfo
 
@@ -1262,14 +1232,6 @@
 			return
 		}
 	}
-	// Optimization. If we are building bundled APEX, for the files that are gathered due to the
-	// transitive dependencies, don't place them inside the APEX, but place a symlink pointing
-	// the same library in the system partition, thus effectively sharing the same libraries
-	// across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
-	// in the APEX.
-	a.linkToSystemLib = !ctx.Config().UnbundledBuild() &&
-		a.installable() &&
-		!proptools.Bool(a.properties.Use_vendor)
 
 	// prepare apex_manifest.json
 	a.buildManifest(ctx, provideNativeLibs, requireNativeLibs)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 01549bb..cc346e9 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -91,10 +91,6 @@
 	config.TestProductVariables.Binder32bit = proptools.BoolPtr(true)
 }
 
-func withUnbundledBuild(fs map[string][]byte, config android.Config) {
-	config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
-}
-
 func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
 	android.ClearApexDependency()
 
@@ -1535,68 +1531,46 @@
 	ensureContains(t, cFlags, "-Imy_include")
 }
 
-type fileInApex struct {
-	path   string // path in apex
-	isLink bool
-}
-
-func getFiles(t *testing.T, ctx *android.TestContext, moduleName string) []fileInApex {
+func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName string, files []string) {
 	t.Helper()
 	apexRule := ctx.ModuleForTests(moduleName, "android_common_"+moduleName+"_image").Rule("apexRule")
 	copyCmds := apexRule.Args["copy_commands"]
 	imageApexDir := "/image.apex/"
-	var ret []fileInApex
+	var failed bool
+	var surplus []string
+	filesMatched := make(map[string]bool)
+	addContent := func(content string) {
+		for _, expected := range files {
+			if matched, _ := path.Match(expected, content); matched {
+				filesMatched[expected] = true
+				return
+			}
+		}
+		surplus = append(surplus, content)
+	}
 	for _, cmd := range strings.Split(copyCmds, "&&") {
 		cmd = strings.TrimSpace(cmd)
 		if cmd == "" {
 			continue
 		}
 		terms := strings.Split(cmd, " ")
-		var dst string
-		var isLink bool
 		switch terms[0] {
 		case "mkdir":
 		case "cp":
 			if len(terms) != 3 {
 				t.Fatal("copyCmds contains invalid cp command", cmd)
 			}
-			dst = terms[2]
-			isLink = false
-		case "ln":
-			if len(terms) != 3 && len(terms) != 4 {
-				// ln LINK TARGET or ln -s LINK TARGET
-				t.Fatal("copyCmds contains invalid ln command", cmd)
-			}
-			dst = terms[len(terms)-1]
-			isLink = true
-		default:
-			t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd)
-		}
-		if dst != "" {
+			dst := terms[2]
 			index := strings.Index(dst, imageApexDir)
 			if index == -1 {
 				t.Fatal("copyCmds should copy a file to image.apex/", cmd)
 			}
 			dstFile := dst[index+len(imageApexDir):]
-			ret = append(ret, fileInApex{path: dstFile, isLink: isLink})
+			addContent(dstFile)
+		default:
+			t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd)
 		}
 	}
-	return ret
-}
-
-func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName string, files []string) {
-	var failed bool
-	var surplus []string
-	filesMatched := make(map[string]bool)
-	for _, file := range getFiles(t, ctx, moduleName) {
-		for _, expected := range files {
-			if matched, _ := path.Match(expected, file.path); matched {
-				filesMatched[expected] = true
-				return
-			}
-		}
-		surplus = append(surplus, file.path)
-	}
 
 	if len(surplus) > 0 {
 		sort.Strings(surplus)
@@ -3391,90 +3365,6 @@
 	ensureContains(t, androidMk, "LOCAL_TARGET_REQUIRED_MODULES += e f\n")
 }
 
-func TestSymlinksFromApexToSystem(t *testing.T) {
-	bp := `
-		apex {
-			name: "myapex",
-			key: "myapex.key",
-			native_shared_libs: ["mylib"],
-			java_libs: ["myjar"],
-		}
-
-		apex_key {
-			name: "myapex.key",
-			public_key: "testkey.avbpubkey",
-			private_key: "testkey.pem",
-		}
-
-		cc_library {
-			name: "mylib",
-			srcs: ["mylib.cpp"],
-			shared_libs: ["myotherlib"],
-			system_shared_libs: [],
-			stl: "none",
-		}
-
-		cc_library {
-			name: "myotherlib",
-			srcs: ["mylib.cpp"],
-			system_shared_libs: [],
-			stl: "none",
-		}
-
-		java_library {
-			name: "myjar",
-			srcs: ["foo/bar/MyClass.java"],
-			sdk_version: "none",
-			system_modules: "none",
-			libs: ["myotherjar"],
-			compile_dex: true,
-		}
-
-		java_library {
-			name: "myotherjar",
-			srcs: ["foo/bar/MyClass.java"],
-			sdk_version: "none",
-			system_modules: "none",
-		}
-	`
-
-	ensureRealfileExists := func(t *testing.T, files []fileInApex, file string) {
-		for _, f := range files {
-			if f.path == file {
-				if f.isLink {
-					t.Errorf("%q is not a real file", file)
-				}
-				return
-			}
-		}
-		t.Errorf("%q is not found", file)
-	}
-
-	ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string) {
-		for _, f := range files {
-			if f.path == file {
-				if !f.isLink {
-					t.Errorf("%q is not a symlink", file)
-				}
-				return
-			}
-		}
-		t.Errorf("%q is not found", file)
-	}
-
-	ctx, _ := testApex(t, bp, withUnbundledBuild)
-	files := getFiles(t, ctx, "myapex")
-	ensureRealfileExists(t, files, "javalib/myjar.jar")
-	ensureRealfileExists(t, files, "lib64/mylib.so")
-	ensureRealfileExists(t, files, "lib64/myotherlib.so")
-
-	ctx, _ = testApex(t, bp)
-	files = getFiles(t, ctx, "myapex")
-	ensureRealfileExists(t, files, "javalib/myjar.jar")
-	ensureRealfileExists(t, files, "lib64/mylib.so")
-	ensureSymlinkExists(t, files, "lib64/myotherlib.so") // this is symlink
-}
-
 func TestMain(m *testing.M) {
 	run := func() int {
 		setUp()
diff --git a/apex/builder.go b/apex/builder.go
index e16df02..4a760b9 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -245,41 +245,36 @@
 
 	apexType := a.properties.ApexType
 	suffix := apexType.suffix()
-	var implicitInputs []android.Path
 	unsignedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix+".unsigned")
 
-	// TODO(jiyong): construct the copy rules using RuleBuilder
-	var copyCommands []string
-	for _, fi := range a.filesInfo {
-		destPath := android.PathForModuleOut(ctx, "image"+suffix, fi.Path()).String()
-		copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(destPath))
-		if a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform() {
-			// TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
-			pathOnDevice := filepath.Join("/system", fi.Path())
-			copyCommands = append(copyCommands, "ln -s "+pathOnDevice+" "+destPath)
-		} else {
-			copyCommands = append(copyCommands, "cp "+fi.builtFile.String()+" "+destPath)
-			implicitInputs = append(implicitInputs, fi.builtFile)
-		}
-		// create additional symlinks pointing the file inside the APEX
-		for _, symlinkPath := range fi.SymlinkPaths() {
-			symlinkDest := android.PathForModuleOut(ctx, "image"+suffix, symlinkPath).String()
-			copyCommands = append(copyCommands, "ln -s "+filepath.Base(destPath)+" "+symlinkDest)
-		}
+	filesToCopy := []android.Path{}
+	for _, f := range a.filesInfo {
+		filesToCopy = append(filesToCopy, f.builtFile)
 	}
 
-	// TODO(jiyong): use RuleBuilder
-	var emitCommands []string
-	imageContentFile := android.PathForModuleOut(ctx, "content.txt")
+	copyCommands := []string{}
+	emitCommands := []string{}
+	imageContentFile := android.PathForModuleOut(ctx, a.Name()+"-content.txt")
 	emitCommands = append(emitCommands, "echo ./apex_manifest.pb >> "+imageContentFile.String())
 	if proptools.Bool(a.properties.Legacy_android10_support) {
 		emitCommands = append(emitCommands, "echo ./apex_manifest.json >> "+imageContentFile.String())
 	}
-	for _, fi := range a.filesInfo {
-		emitCommands = append(emitCommands, "echo './"+fi.Path()+"' >> "+imageContentFile.String())
+	for i, src := range filesToCopy {
+		dest := filepath.Join(a.filesInfo[i].installDir, src.Base())
+		emitCommands = append(emitCommands, "echo './"+dest+"' >> "+imageContentFile.String())
+		dest_path := filepath.Join(android.PathForModuleOut(ctx, "image"+suffix).String(), dest)
+		copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(dest_path))
+		copyCommands = append(copyCommands, "cp "+src.String()+" "+dest_path)
+		for _, sym := range a.filesInfo[i].symlinks {
+			symlinkDest := filepath.Join(filepath.Dir(dest_path), sym)
+			copyCommands = append(copyCommands, "ln -s "+filepath.Base(dest)+" "+symlinkDest)
+		}
 	}
 	emitCommands = append(emitCommands, "sort -o "+imageContentFile.String()+" "+imageContentFile.String())
 
+	implicitInputs := append(android.Paths(nil), filesToCopy...)
+	implicitInputs = append(implicitInputs, a.manifestPbOut)
+
 	if a.properties.Whitelisted_files != nil {
 		ctx.Build(pctx, android.BuildParams{
 			Rule:        emitApexContentRule,
@@ -401,7 +396,6 @@
 			optFlags = append(optFlags, "--do_not_check_keyname")
 		}
 
-		implicitInputs = append(implicitInputs, a.manifestPbOut)
 		if proptools.Bool(a.properties.Legacy_android10_support) {
 			implicitInputs = append(implicitInputs, a.manifestJsonOut)
 			optFlags = append(optFlags, "--manifest_json "+a.manifestJsonOut.String())
@@ -519,7 +513,7 @@
 	if a.installable() {
 		// For flattened APEX, do nothing but make sure that APEX manifest and apex_pubkey are also copied along
 		// with other ordinary files.
-		a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
+		a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb."+a.Name()+a.suffix, ".", etc, nil))
 
 		// rename to apex_pubkey
 		copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
@@ -528,7 +522,7 @@
 			Input:  a.public_key_file,
 			Output: copiedPubkey,
 		})
-		a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
+		a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey."+a.Name()+a.suffix, ".", etc, nil))
 
 		if a.properties.ApexType == flattenedApex {
 			apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())