Merge "Reland: Add jni_libs property to java tests"
diff --git a/java/java.go b/java/java.go
index ee4f2eb..adb0c56 100644
--- a/java/java.go
+++ b/java/java.go
@@ -27,6 +27,7 @@
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
+	"android/soong/cc"
 	"android/soong/dexpreopt"
 	"android/soong/java/config"
 	"android/soong/tradefed"
@@ -708,6 +709,9 @@
 
 	// Test options.
 	Test_options TestOptions
+
+	// Names of modules containing JNI libraries that should be installed alongside the test.
+	Jni_libs []string
 }
 
 type hostTestProperties struct {
@@ -769,6 +773,13 @@
 		}
 	}
 
+	if len(j.testProperties.Jni_libs) > 0 {
+		for _, target := range ctx.MultiTargets() {
+			sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
+			ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...)
+		}
+	}
+
 	j.deps(ctx)
 }
 
@@ -793,6 +804,29 @@
 		j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
 	})
 
+	ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) {
+		sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo)
+		if sharedLibInfo.SharedLibrary != nil {
+			// Copy to an intermediate output directory to append "lib[64]" to the path,
+			// so that it's compatible with the default rpath values.
+			var relPath string
+			if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" {
+				relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base())
+			} else {
+				relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base())
+			}
+			relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath)
+			ctx.Build(pctx, android.BuildParams{
+				Rule:   android.Cp,
+				Input:  sharedLibInfo.SharedLibrary,
+				Output: relocatedLib,
+			})
+			j.data = append(j.data, relocatedLib)
+		} else {
+			ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
+		}
+	})
+
 	j.Library.GenerateAndroidBuildActions(ctx)
 }
 
diff --git a/java/java_test.go b/java/java_test.go
index 0523458..e7ea4ef 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -20,6 +20,7 @@
 	"path/filepath"
 	"reflect"
 	"regexp"
+	"runtime"
 	"strconv"
 	"strings"
 	"testing"
@@ -462,6 +463,38 @@
 	}
 }
 
+func TestTest(t *testing.T) {
+	ctx, _ := testJava(t, `
+		java_test_host {
+			name: "foo",
+			srcs: ["a.java"],
+			jni_libs: ["libjni"],
+		}
+
+		cc_library_shared {
+			name: "libjni",
+			host_supported: true,
+			device_supported: false,
+			stl: "none",
+		}
+	`)
+
+	buildOS := android.BuildOs.String()
+
+	foo := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+
+	expected := "lib64/libjni.so"
+	if runtime.GOOS == "darwin" {
+		expected = "lib64/libjni.dylib"
+	}
+
+	fooTestData := foo.data
+	if len(fooTestData) != 1 || fooTestData[0].Rel() != expected {
+		t.Errorf(`expected foo test data relative path [%q], got %q`,
+			expected, fooTestData.Strings())
+	}
+}
+
 func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) {
 	bp := `
 		java_library {