Install data_libs using relative_install_path property

Test: Added to data_libs tests
Test: Manually verified with bionic-unit-tests
Test: Treehugger
Change-Id: I28a8e08e3409f1e7c7bb72f4351310b57f35f513
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 3f812c2..e91b40a 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -149,21 +149,25 @@
 	return []android.AndroidMkEntries{entries}
 }
 
-func AndroidMkDataPaths(data android.Paths) []string {
+func AndroidMkDataPaths(data []android.DataPath) []string {
 	var testFiles []string
 	for _, d := range data {
-		rel := d.Rel()
-		path := d.String()
+		rel := d.SrcPath.Rel()
+		path := d.SrcPath.String()
 		if !strings.HasSuffix(path, rel) {
 			panic(fmt.Errorf("path %q does not end with %q", path, rel))
 		}
 		path = strings.TrimSuffix(path, rel)
-		testFiles = append(testFiles, path+":"+rel)
+		testFileString := path + ":" + rel
+		if len(d.RelativeInstallPath) > 0 {
+			testFileString += ":" + d.RelativeInstallPath
+		}
+		testFiles = append(testFiles, testFileString)
 	}
 	return testFiles
 }
 
-func androidMkWriteTestData(data android.Paths, ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+func androidMkWriteTestData(data []android.DataPath, ctx AndroidMkContext, entries *android.AndroidMkEntries) {
 	testFiles := AndroidMkDataPaths(data)
 	if len(testFiles) > 0 {
 		entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
@@ -357,8 +361,11 @@
 			entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true)
 		}
 	})
-
-	androidMkWriteTestData(benchmark.data, ctx, entries)
+	dataPaths := []android.DataPath{}
+	for _, srcPath := range benchmark.data {
+		dataPaths = append(dataPaths, android.DataPath{SrcPath: srcPath})
+	}
+	androidMkWriteTestData(dataPaths, ctx, entries)
 }
 
 func (test *testBinary) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
diff --git a/cc/cc.go b/cc/cc.go
index 0d5b6bd..fdf2879 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1401,9 +1401,9 @@
 	return ok && test.isAllTestsVariation()
 }
 
-func (c *Module) DataPaths() android.Paths {
+func (c *Module) DataPaths() []android.DataPath {
 	if p, ok := c.installer.(interface {
-		dataPaths() android.Paths
+		dataPaths() []android.DataPath
 	}); ok {
 		return p.dataPaths()
 	}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 8a1c8ed..041c4a3 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -539,7 +539,7 @@
 			data_libs: ["test_lib"],
 			gtest: false,
 		}
-  `
+ `
 
 	config := TestConfig(buildDir, android.Android, nil, bp, nil)
 	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
@@ -564,7 +564,7 @@
 	}
 
 	outputPath := outputFiles[0].String()
-	testBinaryPath := testBinary.dataPaths()[0].String()
+	testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
 
 	if !strings.HasSuffix(outputPath, "/main_test") {
 		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
@@ -576,6 +576,54 @@
 	}
 }
 
+func TestDataLibsRelativeInstallPath(t *testing.T) {
+	bp := `
+		cc_test_library {
+			name: "test_lib",
+			srcs: ["test_lib.cpp"],
+			relative_install_path: "foo/bar/baz",
+			gtest: false,
+		}
+
+		cc_test {
+			name: "main_test",
+			data_libs: ["test_lib"],
+			gtest: false,
+		}
+ `
+
+	config := TestConfig(buildDir, android.Android, nil, bp, nil)
+	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
+
+	ctx := testCcWithConfig(t, config)
+	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
+	testBinary := module.(*Module).linker.(*testBinary)
+	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
+	if err != nil {
+		t.Fatalf("Expected cc_test to produce output files, error: %s", err)
+	}
+	if len(outputFiles) != 1 {
+		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
+	}
+	if len(testBinary.dataPaths()) != 1 {
+		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
+	}
+
+	outputPath := outputFiles[0].String()
+	testBinaryPath := testBinary.dataPaths()[0]
+
+	if !strings.HasSuffix(outputPath, "/main_test") {
+		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
+	}
+	entries := android.AndroidMkEntriesForTest(t, config, "", module)[0]
+	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
+		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
+			" but was '%s'", testBinaryPath)
+	}
+}
+
 func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
 	ctx := testCcNoVndk(t, `
 		cc_library {
diff --git a/cc/test.go b/cc/test.go
index 37afb0c..9b6864a 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -165,7 +165,7 @@
 	return test.baseCompiler.Properties.Srcs
 }
 
-func (test *testBinary) dataPaths() android.Paths {
+func (test *testBinary) dataPaths() []android.DataPath {
 	return test.data
 }
 
@@ -310,7 +310,7 @@
 	*binaryDecorator
 	*baseCompiler
 	Properties TestBinaryProperties
-	data       android.Paths
+	data       []android.DataPath
 	testConfig android.Path
 }
 
@@ -339,7 +339,11 @@
 }
 
 func (test *testBinary) install(ctx ModuleContext, file android.Path) {
-	test.data = android.PathsForModuleSrc(ctx, test.Properties.Data)
+	dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
+
+	for _, dataSrcPath := range dataSrcPaths {
+		test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath})
+	}
 
 	ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) {
 		depName := ctx.OtherModuleName(dep)
@@ -348,10 +352,14 @@
 		if !ok {
 			ctx.ModuleErrorf("data_lib %q is not a linkable cc module", depName)
 		}
+		ccModule, ok := dep.(*Module)
+		if !ok {
+			ctx.ModuleErrorf("data_lib %q is not a cc module", depName)
+		}
 		if ccDep.OutputFile().Valid() {
-			test.data = append(test.data, ccDep.OutputFile().Path())
-		} else {
-			ctx.ModuleErrorf("data_lib %q has no output file", depName)
+			test.data = append(test.data,
+				android.DataPath{SrcPath: ccDep.OutputFile().Path(),
+					RelativeInstallPath: ccModule.installer.relativeInstallPath()})
 		}
 	})