Add ramdisk image.

It is similar to recovery image.
Test: m nothing -j

Change-Id: I11389777c6bfb0c0d73bbb4c70091c1e70f44077
diff --git a/android/arch.go b/android/arch.go
index b5b8a8f..6be5993 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -838,8 +838,8 @@
 		osTargets = targets
 	}
 
-	// only the primary arch in the recovery partition
-	if os == Android && module.InstallInRecovery() {
+	// only the primary arch in the ramdisk / recovery partition
+	if os == Android && (module.InstallInRecovery() || module.InstallInRamdisk()) {
 		osTargets = []Target{osTargets[0]}
 	}
 
diff --git a/android/image.go b/android/image.go
index 5291ce3..061bfa5 100644
--- a/android/image.go
+++ b/android/image.go
@@ -22,6 +22,10 @@
 	// CoreVariantNeeded should return true if the module needs a core variant (installed on the system image).
 	CoreVariantNeeded(ctx BaseModuleContext) bool
 
+	// RamdiskVariantNeeded should return true if the module needs a ramdisk variant (installed on the
+	// ramdisk partition).
+	RamdiskVariantNeeded(ctx BaseModuleContext) bool
+
 	// RecoveryVariantNeeded should return true if the module needs a recovery variant (installed on the
 	// recovery partition).
 	RecoveryVariantNeeded(ctx BaseModuleContext) bool
@@ -46,6 +50,9 @@
 
 	// RecoveryVariation means a module to be installed to recovery image.
 	RecoveryVariation string = "recovery"
+
+	// RamdiskVariation means a module to be installed to ramdisk image.
+	RamdiskVariation string = "ramdisk"
 )
 
 // imageMutator creates variants for modules that implement the ImageInterface that
@@ -63,6 +70,9 @@
 		if m.CoreVariantNeeded(ctx) {
 			variations = append(variations, CoreVariation)
 		}
+		if m.RamdiskVariantNeeded(ctx) {
+			variations = append(variations, RamdiskVariation)
+		}
 		if m.RecoveryVariantNeeded(ctx) {
 			variations = append(variations, RecoveryVariation)
 		}
diff --git a/android/module.go b/android/module.go
index 05115d6..2662e2a 100644
--- a/android/module.go
+++ b/android/module.go
@@ -167,6 +167,7 @@
 	InstallInData() bool
 	InstallInTestcases() bool
 	InstallInSanitizerDir() bool
+	InstallInRamdisk() bool
 	InstallInRecovery() bool
 	InstallInRoot() bool
 	InstallBypassMake() bool
@@ -207,6 +208,7 @@
 	InstallInData() bool
 	InstallInTestcases() bool
 	InstallInSanitizerDir() bool
+	InstallInRamdisk() bool
 	InstallInRecovery() bool
 	InstallInRoot() bool
 	InstallBypassMake() bool
@@ -384,6 +386,9 @@
 	// Whether this module is installed to recovery partition
 	Recovery *bool
 
+	// Whether this module is installed to ramdisk
+	Ramdisk *bool
+
 	// Whether this module is built for non-native architecures (also known as native bridge binary)
 	Native_bridge_supported *bool `android:"arch_variant"`
 
@@ -867,6 +872,10 @@
 	return false
 }
 
+func (m *ModuleBase) InstallInRamdisk() bool {
+	return Bool(m.commonProperties.Ramdisk)
+}
+
 func (m *ModuleBase) InstallInRecovery() bool {
 	return Bool(m.commonProperties.Recovery)
 }
@@ -898,6 +907,10 @@
 	}
 }
 
+func (m *ModuleBase) InRamdisk() bool {
+	return m.base().commonProperties.ImageVariation == RamdiskVariation
+}
+
 func (m *ModuleBase) InRecovery() bool {
 	return m.base().commonProperties.ImageVariation == RecoveryVariation
 }
@@ -1649,6 +1662,10 @@
 	return m.module.InstallInSanitizerDir()
 }
 
+func (m *moduleContext) InstallInRamdisk() bool {
+	return m.module.InstallInRamdisk()
+}
+
 func (m *moduleContext) InstallInRecovery() bool {
 	return m.module.InstallInRecovery()
 }
diff --git a/android/paths.go b/android/paths.go
index 02f56d0..7bfd8e1 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -49,6 +49,7 @@
 	InstallInData() bool
 	InstallInTestcases() bool
 	InstallInSanitizerDir() bool
+	InstallInRamdisk() bool
 	InstallInRecovery() bool
 	InstallInRoot() bool
 	InstallBypassMake() bool
@@ -1254,6 +1255,9 @@
 		partition = "data"
 	} else if ctx.InstallInTestcases() {
 		partition = "testcases"
+	} else if ctx.InstallInRamdisk() {
+		// TODO(elsk): should be conditional on RECOVERY_AS_BOOT
+		partition = "ramdisk"
 	} else if ctx.InstallInRecovery() {
 		if ctx.InstallInRoot() {
 			partition = "recovery/root"
diff --git a/android/paths_test.go b/android/paths_test.go
index 46e3e1f..7a32026 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -202,6 +202,7 @@
 	inData         bool
 	inTestcases    bool
 	inSanitizerDir bool
+	inRamdisk      bool
 	inRecovery     bool
 	inRoot         bool
 }
@@ -224,6 +225,10 @@
 	return m.inSanitizerDir
 }
 
+func (m moduleInstallPathContextImpl) InstallInRamdisk() bool {
+	return m.inRamdisk
+}
+
 func (m moduleInstallPathContextImpl) InstallInRecovery() bool {
 	return m.inRecovery
 }
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index 388d17f..3dea6d8 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -41,6 +41,9 @@
 	// is the same as the file name of the source file.
 	Filename_from_src *bool `android:"arch_variant"`
 
+	// Make this module available when building for ramdisk.
+	Ramdisk_available *bool
+
 	// Make this module available when building for recovery.
 	Recovery_available *bool
 
@@ -69,6 +72,18 @@
 	additionalDependencies *Paths
 }
 
+func (p *PrebuiltEtc) inRamdisk() bool {
+	return p.ModuleBase.InRamdisk() || p.ModuleBase.InstallInRamdisk()
+}
+
+func (p *PrebuiltEtc) onlyInRamdisk() bool {
+	return p.ModuleBase.InstallInRamdisk()
+}
+
+func (p *PrebuiltEtc) InstallInRamdisk() bool {
+	return p.inRamdisk()
+}
+
 func (p *PrebuiltEtc) inRecovery() bool {
 	return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery()
 }
@@ -86,7 +101,11 @@
 func (p *PrebuiltEtc) ImageMutatorBegin(ctx BaseModuleContext) {}
 
 func (p *PrebuiltEtc) CoreVariantNeeded(ctx BaseModuleContext) bool {
-	return !p.ModuleBase.InstallInRecovery()
+	return !p.ModuleBase.InstallInRecovery() && !p.ModuleBase.InstallInRamdisk()
+}
+
+func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx BaseModuleContext) bool {
+	return Bool(p.properties.Ramdisk_available) || p.ModuleBase.InstallInRamdisk()
 }
 
 func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx BaseModuleContext) bool {
@@ -167,6 +186,9 @@
 
 func (p *PrebuiltEtc) AndroidMkEntries() []AndroidMkEntries {
 	nameSuffix := ""
+	if p.inRamdisk() && !p.onlyInRamdisk() {
+		nameSuffix = ".ramdisk"
+	}
 	if p.inRecovery() && !p.onlyInRecovery() {
 		nameSuffix = ".recovery"
 	}