Support non-installable java libraries

Some java libraries will never be installed, support an
installable: false property and export it back to make as
LOCAL_UNINSTALLABLE_MODULE := true.

Test: m -j checkbuild, manually inspect out/soong/Android*.mk
Change-Id: I825ec897648c82fb7323da7df3539c9aaa6bcfce
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 50ba91b..caf594a 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -37,6 +37,7 @@
 	"LOCAL_SANITIZE":              sanitize(""),
 	"LOCAL_SANITIZE_DIAG":         sanitize("diag."),
 	"LOCAL_CFLAGS":                cflags,
+	"LOCAL_UNINSTALLABLE_MODULE":  invert("installable"),
 
 	// composite functions
 	"LOCAL_MODULE_TAGS": includeVariableIf(bpVariable{"tags", bpparser.ListType}, not(valueDumpEquals("optional"))),
@@ -117,19 +118,18 @@
 	addStandardProperties(bpparser.BoolType,
 		map[string]string{
 			// Bool properties
-			"LOCAL_IS_HOST_MODULE":          "host",
-			"LOCAL_CLANG":                   "clang",
-			"LOCAL_FORCE_STATIC_EXECUTABLE": "static_executable",
-			"LOCAL_NATIVE_COVERAGE":         "native_coverage",
-			"LOCAL_NO_CRT":                  "nocrt",
-			"LOCAL_ALLOW_UNDEFINED_SYMBOLS": "allow_undefined_symbols",
-			"LOCAL_RTTI_FLAG":               "rtti",
-			"LOCAL_NO_STANDARD_LIBRARIES":   "no_standard_libs",
-			"LOCAL_PACK_MODULE_RELOCATIONS": "pack_relocations",
-			"LOCAL_TIDY":                    "tidy",
-			"LOCAL_PROPRIETARY_MODULE":      "proprietary",
-			"LOCAL_VENDOR_MODULE":           "vendor",
-
+			"LOCAL_IS_HOST_MODULE":           "host",
+			"LOCAL_CLANG":                    "clang",
+			"LOCAL_FORCE_STATIC_EXECUTABLE":  "static_executable",
+			"LOCAL_NATIVE_COVERAGE":          "native_coverage",
+			"LOCAL_NO_CRT":                   "nocrt",
+			"LOCAL_ALLOW_UNDEFINED_SYMBOLS":  "allow_undefined_symbols",
+			"LOCAL_RTTI_FLAG":                "rtti",
+			"LOCAL_NO_STANDARD_LIBRARIES":    "no_standard_libs",
+			"LOCAL_PACK_MODULE_RELOCATIONS":  "pack_relocations",
+			"LOCAL_TIDY":                     "tidy",
+			"LOCAL_PROPRIETARY_MODULE":       "proprietary",
+			"LOCAL_VENDOR_MODULE":            "vendor",
 			"LOCAL_EXPORT_PACKAGE_RESOURCES": "export_package_resources",
 		})
 }
@@ -528,6 +528,19 @@
 	return includeVariableNow(bpVariable{"cflags", bpparser.ListType}, ctx)
 }
 
+func invert(name string) func(ctx variableAssignmentContext) error {
+	return func(ctx variableAssignmentContext) error {
+		val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.BoolType)
+		if err != nil {
+			return err
+		}
+
+		val.(*bpparser.Bool).Value = !val.(*bpparser.Bool).Value
+
+		return setVariable(ctx.file, ctx.append, ctx.prefix, name, val, true)
+	}
+}
+
 // given a conditional, returns a function that will insert a variable assignment or not, based on the conditional
 func includeVariableIf(bpVar bpVariable, conditional func(ctx variableAssignmentContext) bool) func(ctx variableAssignmentContext) error {
 	return func(ctx variableAssignmentContext) error {
diff --git a/java/androidmk.go b/java/androidmk.go
index 12643cf..c383a0e 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -29,6 +29,9 @@
 		Extra: []android.AndroidMkExtraFunc{
 			func(w io.Writer, outputFile android.Path) {
 				fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := .jar")
+				if library.properties.Installable != nil && *library.properties.Installable == false {
+					fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+				}
 			},
 		},
 	}
@@ -41,6 +44,7 @@
 		Extra: []android.AndroidMkExtraFunc{
 			func(w io.Writer, outputFile android.Path) {
 				fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := .jar")
+				fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
 			},
 		},
 	}
diff --git a/java/java.go b/java/java.go
index a8093e7..7b213b2 100644
--- a/java/java.go
+++ b/java/java.go
@@ -96,6 +96,9 @@
 
 	// If not blank, set the java version passed to javac as -source and -target
 	Java_version *string
+
+	// If set to false, don't allow this module to be installed.  Defaults to true.
+	Installable *bool
 }
 
 type CompilerDeviceProperties struct {
@@ -473,7 +476,10 @@
 func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	j.compile(ctx)
 
-	j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".jar", j.outputFile)
+	if j.properties.Installable == nil || *j.properties.Installable == true {
+		j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
+			ctx.ModuleName()+".jar", j.outputFile)
+	}
 }
 
 func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -605,9 +611,6 @@
 	}
 
 	j.combinedClasspathFile = TransformClassesToJar(ctx, j.classJarSpecs, android.OptionalPath{}, nil)
-
-	ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
-		ctx.ModuleName()+".jar", j.combinedClasspathFile)
 }
 
 var _ Dependency = (*Import)(nil)