apex: AndroidMk writes common properties

AndroidMkEntries handles bunch of common properties(e.g. LOCAL_INIT_RC,
LOCAL_VINTF_FRAGMENTS, etc).

However apex defines its own Custom() writer, so those properties should
be handled manually.

For example, when an apex defines "init_rc" properties, the value should
be passed to Make via LOCAL_INIT_RC.

Bug: 159211312
Test: m
Change-Id: I65e7a456486c9f5fe70c91b78ff181425035fcf2
diff --git a/android/androidmk.go b/android/androidmk.go
index d579e30..a42dcd4 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -58,7 +58,7 @@
 
 	Extra []AndroidMkExtraFunc
 
-	preamble bytes.Buffer
+	Entries AndroidMkEntries
 }
 
 type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
@@ -427,7 +427,7 @@
 
 func (data *AndroidMkData) fillInData(config Config, bpPath string, mod blueprint.Module) {
 	// Get the preamble content through AndroidMkEntries logic.
-	entries := AndroidMkEntries{
+	data.Entries = AndroidMkEntries{
 		Class:           data.Class,
 		SubName:         data.SubName,
 		DistFile:        data.DistFile,
@@ -438,16 +438,12 @@
 		Host_required:   data.Host_required,
 		Target_required: data.Target_required,
 	}
-	entries.fillInEntries(config, bpPath, mod)
-
-	// preamble doesn't need the footer content.
-	entries.footer = bytes.Buffer{}
-	entries.write(&data.preamble)
+	data.Entries.fillInEntries(config, bpPath, mod)
 
 	// copy entries back to data since it is used in Custom
-	data.Required = entries.Required
-	data.Host_required = entries.Host_required
-	data.Target_required = entries.Target_required
+	data.Required = data.Entries.Required
+	data.Host_required = data.Entries.Host_required
+	data.Target_required = data.Entries.Target_required
 }
 
 func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
@@ -503,7 +499,9 @@
 		return
 	}
 
-	w.Write(data.preamble.Bytes())
+	// write preamble via Entries
+	data.Entries.footer = bytes.Buffer{}
+	data.Entries.write(w)
 
 	for _, extra := range data.Extra {
 		extra(w, data.OutputFile.Path())
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 4dd14d8..7595238 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -33,14 +33,7 @@
 			Disabled: true,
 		}
 	}
-	writers := []android.AndroidMkData{}
-	writers = append(writers, a.androidMkForType())
-	return android.AndroidMkData{
-		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
-			for _, data := range writers {
-				data.Custom(w, name, prefix, moduleDir, data)
-			}
-		}}
+	return a.androidMkForType()
 }
 
 func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, moduleDir string) []string {
@@ -308,6 +301,20 @@
 				fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.ToMakePath().String())
 				fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", name+apexType.suffix())
 				fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !a.installable())
+
+				// Because apex writes .mk with Custom(), we need to write manually some common properties
+				// which are available via data.Entries
+				commonProperties := []string{
+					"LOCAL_INIT_RC", "LOCAL_VINTF_FRAGMENTS",
+					"LOCAL_PROPRIETARY_MODULE", "LOCAL_VENDOR_MODULE", "LOCAL_ODM_MODULE", "LOCAL_PRODUCT_MODULE", "LOCAL_SYSTEM_EXT_MODULE",
+					"LOCAL_MODULE_OWNER",
+				}
+				for _, name := range commonProperties {
+					if value, ok := data.Entries.EntryMap[name]; ok {
+						fmt.Fprintln(w, name+" := "+strings.Join(value, " "))
+					}
+				}
+
 				if len(a.overridableProperties.Overrides) > 0 {
 					fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(a.overridableProperties.Overrides, " "))
 				}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index f1638c3..3cd7d1b 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2161,6 +2161,35 @@
 	`)
 }
 
+func TestAndroidMkWritesCommonProperties(t *testing.T) {
+	ctx, config := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			vintf_fragments: ["fragment.xml"],
+			init_rc: ["init.rc"],
+		}
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+		cc_binary {
+			name: "mybin",
+		}
+	`)
+
+	apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
+	name := apexBundle.BaseModuleName()
+	prefix := "TARGET_"
+	var builder strings.Builder
+	data.Custom(&builder, name, prefix, "", data)
+	androidMk := builder.String()
+	ensureContains(t, androidMk, "LOCAL_VINTF_FRAGMENTS := fragment.xml\n")
+	ensureContains(t, androidMk, "LOCAL_INIT_RC := init.rc\n")
+}
+
 func TestStaticLinking(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {