Add InstallInRoot to allow modules to install into root partition

If InstallInRoot() returns true the module will be installed to
$OUT/root or $OUT/recovery/root.

Bug: 141877526
Test: m checkbuild
Test: no change to build.ninja or Android-${TARGET_PRODUCT}.mk
Test: TestPathForModuleInstall
Change-Id: Id6e435c6019f11eeb5806528fd464dbf220b88d9
diff --git a/android/paths_test.go b/android/paths_test.go
index b66eb1e..2e67272 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -204,6 +204,7 @@
 	inTestcases    bool
 	inSanitizerDir bool
 	inRecovery     bool
+	inRoot         bool
 }
 
 func (moduleInstallPathContextImpl) Fs() pathtools.FileSystem {
@@ -232,6 +233,10 @@
 	return m.inRecovery
 }
 
+func (m moduleInstallPathContextImpl) InstallInRoot() bool {
+	return m.inRoot
+}
+
 func (m moduleInstallPathContextImpl) InstallBypassMake() bool {
 	return false
 }
@@ -313,6 +318,40 @@
 			in:  []string{"bin", "my_test"},
 			out: "target/product/test_device/system_ext/bin/my_test",
 		},
+		{
+			name: "root binary",
+			ctx: &moduleInstallPathContextImpl{
+				baseModuleContext: baseModuleContext{
+					target: deviceTarget,
+				},
+				inRoot: true,
+			},
+			in:  []string{"my_test"},
+			out: "target/product/test_device/root/my_test",
+		},
+		{
+			name: "recovery binary",
+			ctx: &moduleInstallPathContextImpl{
+				baseModuleContext: baseModuleContext{
+					target: deviceTarget,
+				},
+				inRecovery: true,
+			},
+			in:  []string{"bin/my_test"},
+			out: "target/product/test_device/recovery/root/system/bin/my_test",
+		},
+		{
+			name: "recovery root binary",
+			ctx: &moduleInstallPathContextImpl{
+				baseModuleContext: baseModuleContext{
+					target: deviceTarget,
+				},
+				inRecovery: true,
+				inRoot:     true,
+			},
+			in:  []string{"my_test"},
+			out: "target/product/test_device/recovery/root/my_test",
+		},
 
 		{
 			name: "system native test binary",