List of installed files for each APEX is dist'ed

For each APEX, <apexname>-installed-files.txt is dist'ed to show the
list of files and their sizes that are included in the APEX.

Bug: 147605944
Test: m dist and examine the txt files

Change-Id: I565479523e51280fc88d5fbf8ea3f48ac0ae9fee
diff --git a/apex/androidmk.go b/apex/androidmk.go
index b2fe8da..ad7d2f1 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -245,6 +245,14 @@
 				if apexType == imageApex {
 					fmt.Fprintln(w, "ALL_MODULES.$(LOCAL_MODULE).BUNDLE :=", a.bundleModuleFile.String())
 				}
+
+				if a.installedFilesFile != nil {
+					goal := "droidcore"
+					distFile := name + "-installed-files.txt"
+					fmt.Fprintln(w, ".PHONY:", goal)
+					fmt.Fprintf(w, "$(call dist-for-goals,%s,%s:%s)\n",
+						goal, a.installedFilesFile.String(), distFile)
+				}
 			}
 		}}
 }
diff --git a/apex/apex.go b/apex/apex.go
index 7d6b7f0..8149102 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -547,6 +547,8 @@
 	// Suffix of module name in Android.mk
 	// ".flattened", ".apex", ".zipapex", or ""
 	suffix string
+
+	installedFilesFile android.WritablePath
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
diff --git a/apex/builder.go b/apex/builder.go
index 237b7a8..08a57b3 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -233,6 +233,19 @@
 	return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.FirstUniquePaths(noticeFiles)).HtmlGzOutput
 }
 
+func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath {
+	output := android.PathForModuleOut(ctx, "installed-files.txt")
+	rule := android.NewRuleBuilder()
+	rule.Command().
+		Implicit(builtApex).
+		Text("(cd " + imageDir.String() + " ; ").
+		Text("find . -type f -printf \"%s %p\\n\") ").
+		Text(" | sort -nr > ").
+		Output(output)
+	rule.Build(pctx, ctx, "installed-files."+a.Name(), "Installed files")
+	return output.OutputPath
+}
+
 func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
 	var abis []string
 	for _, target := range ctx.MultiTargets() {
@@ -307,6 +320,7 @@
 	outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
 	prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
 
+	imageDir := android.PathForModuleOut(ctx, "image"+suffix)
 	if apexType == imageApex {
 		// files and dirs that will be created in APEX
 		var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
@@ -408,7 +422,7 @@
 			Description: "apex (" + apexType.name() + ")",
 			Args: map[string]string{
 				"tool_path":        outHostBinDir + ":" + prebuiltSdkToolsBinDir,
-				"image_dir":        android.PathForModuleOut(ctx, "image"+suffix).String(),
+				"image_dir":        imageDir.String(),
 				"copy_commands":    strings.Join(copyCommands, " && "),
 				"manifest":         a.manifestPbOut.String(),
 				"file_contexts":    a.fileContexts.String(),
@@ -446,7 +460,7 @@
 			Description: "apex (" + apexType.name() + ")",
 			Args: map[string]string{
 				"tool_path":     outHostBinDir + ":" + prebuiltSdkToolsBinDir,
-				"image_dir":     android.PathForModuleOut(ctx, "image"+suffix).String(),
+				"image_dir":     imageDir.String(),
 				"copy_commands": strings.Join(copyCommands, " && "),
 				"manifest":      a.manifestPbOut.String(),
 			},
@@ -474,6 +488,9 @@
 		ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
 	}
 	a.buildFilesInfo(ctx)
+
+	// installed-files.txt is dist'ed
+	a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
 }
 
 func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) {