Introduce flat deps info list.

Compared to full list, flat list drops dependency edges and simply
lists all transitive dependencies for a top-level apex bundle.

Bug: 149622332
Test: m, manually build flatlist
Change-Id: Ibd521c96b7aeab90b95965c1b524e0a0152aaf5a
Merged-In: Ibd521c96b7aeab90b95965c1b524e0a0152aaf5a
Exempt-From-Owner-Approval: cp from aosp
(cherry picked from commit a8bd113a695dfb77695cdff7f72719a08869fc23)
diff --git a/android/apex.go b/android/apex.go
index 19f58d3..07d59b2 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -411,28 +411,41 @@
 type DepNameToDepInfoMap map[string]ApexModuleDepInfo
 
 type ApexBundleDepsInfo struct {
+	flatListPath OutputPath
 	fullListPath OutputPath
 }
 
 type ApexDepsInfoIntf interface {
+	FlatListPath() Path
 	FullListPath() Path
 }
 
+func (d *ApexBundleDepsInfo) FlatListPath() Path {
+	return d.flatListPath
+}
+
 func (d *ApexBundleDepsInfo) FullListPath() Path {
 	return d.fullListPath
 }
 
 var _ ApexDepsInfoIntf = (*ApexBundleDepsInfo)(nil)
 
+// Generate two module out files:
+// 1. FullList with transitive deps and their parents in the dep graph
+// 2. FlatList with a flat list of transitive deps
 func (d *ApexBundleDepsInfo) BuildDepsInfoLists(ctx ModuleContext, depInfos DepNameToDepInfoMap) {
-	var content strings.Builder
+	var fullContent strings.Builder
+	var flatContent strings.Builder
+
+	fmt.Fprintf(&flatContent, "%s:\\n", ctx.ModuleName())
 	for _, key := range FirstUniqueStrings(SortedStringKeys(depInfos)) {
 		info := depInfos[key]
 		toName := info.To
 		if info.IsExternal {
 			toName = toName + " (external)"
 		}
-		fmt.Fprintf(&content, "%s <- %s\\n", toName, strings.Join(SortedUniqueStrings(info.From), ", "))
+		fmt.Fprintf(&fullContent, "%s <- %s\\n", toName, strings.Join(SortedUniqueStrings(info.From), ", "))
+		fmt.Fprintf(&flatContent, "  %s\\n", toName)
 	}
 
 	d.fullListPath = PathForModuleOut(ctx, "depsinfo", "fulllist.txt").OutputPath
@@ -441,7 +454,17 @@
 		Description: "Full Dependency Info",
 		Output:      d.fullListPath,
 		Args: map[string]string{
-			"content": content.String(),
+			"content": fullContent.String(),
+		},
+	})
+
+	d.flatListPath = PathForModuleOut(ctx, "depsinfo", "flatlist.txt").OutputPath
+	ctx.Build(pctx, BuildParams{
+		Rule:        WriteFile,
+		Description: "Flat Dependency Info",
+		Output:      d.flatListPath,
+		Args: map[string]string{
+			"content": flatContent.String(),
 		},
 	})
 }
diff --git a/apex/apex_test.go b/apex/apex_test.go
index f0e7ff3..c00fd05 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -478,12 +478,19 @@
 	ensureListContains(t, noticeInputs, "custom_notice")
 	ensureListContains(t, noticeInputs, "custom_notice_for_static_lib")
 
-	depsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
-	ensureListContains(t, depsInfo, "myjar <- myapex")
-	ensureListContains(t, depsInfo, "mylib <- myapex")
-	ensureListContains(t, depsInfo, "mylib2 <- mylib")
-	ensureListContains(t, depsInfo, "myotherjar <- myjar")
-	ensureListContains(t, depsInfo, "mysharedjar (external) <- myjar")
+	fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
+	ensureListContains(t, fullDepsInfo, "myjar <- myapex")
+	ensureListContains(t, fullDepsInfo, "mylib <- myapex")
+	ensureListContains(t, fullDepsInfo, "mylib2 <- mylib")
+	ensureListContains(t, fullDepsInfo, "myotherjar <- myjar")
+	ensureListContains(t, fullDepsInfo, "mysharedjar (external) <- myjar")
+
+	flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n")
+	ensureListContains(t, flatDepsInfo, "  myjar")
+	ensureListContains(t, flatDepsInfo, "  mylib")
+	ensureListContains(t, flatDepsInfo, "  mylib2")
+	ensureListContains(t, flatDepsInfo, "  myotherjar")
+	ensureListContains(t, flatDepsInfo, "  mysharedjar (external)")
 }
 
 func TestDefaults(t *testing.T) {
@@ -784,11 +791,15 @@
 	// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
 	ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
 
-	depsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
+	fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
+	ensureListContains(t, fullDepsInfo, "mylib <- myapex2")
+	ensureListContains(t, fullDepsInfo, "libbaz <- mylib")
+	ensureListContains(t, fullDepsInfo, "libfoo (external) <- mylib")
 
-	ensureListContains(t, depsInfo, "mylib <- myapex2")
-	ensureListContains(t, depsInfo, "libbaz <- mylib")
-	ensureListContains(t, depsInfo, "libfoo (external) <- mylib")
+	flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n")
+	ensureListContains(t, flatDepsInfo, "  mylib")
+	ensureListContains(t, flatDepsInfo, "  libbaz")
+	ensureListContains(t, flatDepsInfo, "  libfoo (external)")
 }
 
 func TestApexWithRuntimeLibsDependency(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index a3e6929..2996cc6 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -710,6 +710,9 @@
 	ctx.Build(pctx, android.BuildParams{
 		Rule:   android.Phony,
 		Output: android.PathForPhony(ctx, a.Name()+"-deps-info"),
-		Inputs: []android.Path{a.ApexBundleDepsInfo.FullListPath()},
+		Inputs: []android.Path{
+			a.ApexBundleDepsInfo.FullListPath(),
+			a.ApexBundleDepsInfo.FlatListPath(),
+		},
 	})
 }