Allow building framework.jar and framework-res.apk
Update app support enough to build framework-res.apk, link
framework.jar against its generated files, and export it to
make.
Bug: 69917341
Test: m checkbuild tests docs
Change-Id: I7db29cd1f5fabb22e844483ecc7c38abfedbbe0a
diff --git a/android/package_ctx.go b/android/package_ctx.go
index b40e0a9..3f6a253 100644
--- a/android/package_ctx.go
+++ b/android/package_ctx.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "runtime"
"strings"
"github.com/google/blueprint"
@@ -141,7 +142,7 @@
})
}
-// HostBinVariable returns a Variable whose value is the path to a host tool
+// HostBinToolVariable returns a Variable whose value is the path to a host tool
// in the bin directory for host targets. It may only be called during a Go
// package's initialization - either from the init() function or as part of a
// package-scoped variable's initialization.
@@ -164,6 +165,33 @@
return pa, nil
}
+// HostJNIToolVariable returns a Variable whose value is the path to a host tool
+// in the lib directory for host targets. It may only be called during a Go
+// package's initialization - either from the init() function or as part of a
+// package-scoped variable's initialization.
+func (p PackageContext) HostJNIToolVariable(name, path string) blueprint.Variable {
+ return p.VariableFunc(name, func(config Config) (string, error) {
+ po, err := p.HostJNIToolPath(config, path)
+ if err != nil {
+ return "", err
+ }
+ return po.String(), nil
+ })
+}
+
+func (p PackageContext) HostJNIToolPath(config Config, path string) (Path, error) {
+ ctx := &configErrorWrapper{p, config, []error{}}
+ ext := ".so"
+ if runtime.GOOS == "darwin" {
+ ext = ".dylib"
+ }
+ pa := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "lib64", path+ext)
+ if len(ctx.errors) > 0 {
+ return nil, ctx.errors[0]
+ }
+ return pa, nil
+}
+
// HostJavaToolVariable returns a Variable whose value is the path to a host
// tool in the frameworks directory for host targets. It may only be called
// during a Go package's initialization - either from the init() function or as
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 73ea4ac..18756a9 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -93,6 +93,7 @@
"LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api",
"LOCAL_NOTICE_FILE": "notice",
"LOCAL_JAVA_LANGUAGE_VERSION": "java_version",
+ "LOCAL_INSTRUMENTATION_FOR": "instrumentation_for",
})
addStandardProperties(bpparser.ListType,
map[string]string{
@@ -662,6 +663,8 @@
false: "target.not_linux_glibc"},
"(,$(TARGET_BUILD_APPS))": {
false: "product_variables.unbundled_build"},
+ "($(TARGET_BUILD_APPS),)": {
+ false: "product_variables.unbundled_build"},
"($(TARGET_BUILD_PDK),true)": {
true: "product_variables.pdk"},
"($(TARGET_BUILD_PDK), true)": {
diff --git a/java/androidmk.go b/java/androidmk.go
index df83faa..86e000d 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -46,6 +46,14 @@
if library.jacocoReportClassesFile != nil {
fmt.Fprintln(w, "LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=", library.jacocoReportClassesFile.String())
}
+
+ // Temporary hack: export sources used to compile framework.jar to Make
+ // to be used for droiddoc
+ // TODO(ccross): remove this once droiddoc is in soong
+ if library.Name() == "framework" {
+ fmt.Fprintln(w, "SOONG_FRAMEWORK_SRCS :=", strings.Join(library.compiledJavaSrcs.Strings(), " "))
+ fmt.Fprintln(w, "SOONG_FRAMEWORK_SRCJARS :=", strings.Join(library.compiledSrcJars.Strings(), " "))
+ }
},
},
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
@@ -111,3 +119,33 @@
},
}
}
+
+func (app *AndroidApp) AndroidMk() android.AndroidMkData {
+ return android.AndroidMkData{
+ Class: "APPS",
+ OutputFile: android.OptionalPathForPath(app.outputFile),
+ Include: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
+ Extra: []android.AndroidMkExtraFunc{
+ func(w io.Writer, outputFile android.Path) {
+ if Bool(app.appProperties.Export_package_resources) {
+ if app.dexJarFile != nil {
+ fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", app.dexJarFile.String())
+ }
+ fmt.Fprintln(w, "LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=", app.exportPackage.String())
+
+ if app.jacocoReportClassesFile != nil {
+ fmt.Fprintln(w, "LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=", app.jacocoReportClassesFile.String())
+ }
+
+ if app.Name() == "framework-res" {
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)")
+ // Make base_rules.mk not put framework-res in a subdirectory called
+ // framework_res.
+ fmt.Fprintln(w, "LOCAL_NO_STANDARD_LIBRARIES := true")
+ }
+ }
+ },
+ },
+ }
+
+}
diff --git a/java/app.go b/java/app.go
index bd9ed2a..b66eb4b 100644
--- a/java/app.go
+++ b/java/app.go
@@ -27,6 +27,7 @@
func init() {
android.RegisterPreSingletonType("overlay", OverlaySingletonFactory)
+ android.RegisterModuleType("android_app", AndroidAppFactory)
}
// AAR prebuilts
@@ -76,7 +77,7 @@
if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) {
switch String(a.deviceProperties.Sdk_version) { // TODO: Res_sdk_version?
- case "current", "system_current", "":
+ case "current", "system_current", "test_current", "":
ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res")
default:
// We'll already have a dependency on an sdk prebuilt android.jar
@@ -116,7 +117,13 @@
// a.properties.Proguard.Enabled = true
//}
- a.Module.compile(ctx)
+ if String(a.appProperties.Instrumentation_for) == "" {
+ a.properties.Instrument = true
+ }
+
+ if ctx.ModuleName() != "framework-res" {
+ a.Module.compile(ctx, a.aaptSrcJar)
+ }
certificate := String(a.appProperties.Certificate)
if certificate == "" {
@@ -138,7 +145,12 @@
a.outputFile = packageFile
- ctx.InstallFile(android.PathForModuleInstall(ctx, "app"), ctx.ModuleName()+".apk", a.outputFile)
+ if ctx.ModuleName() == "framework-res" {
+ // framework-res.apk is installed as system/framework/framework-res.apk
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
+ } else {
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "app"), ctx.ModuleName()+".apk", a.outputFile)
+ }
}
var aaptIgnoreFilenames = []string{
diff --git a/java/app_builder.go b/java/app_builder.go
index 82574ae..676ed58 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -29,8 +29,9 @@
var (
signapk = pctx.AndroidStaticRule("signapk",
blueprint.RuleParams{
- Command: `java -jar $signapkCmd $certificates $in $out`,
- CommandDeps: []string{"$signapkCmd"},
+ Command: `${config.JavaCmd} -Djava.library.path=$$(dirname $signapkJniLibrary) ` +
+ `-jar $signapkCmd $certificates $in $out`,
+ CommandDeps: []string{"$signapkCmd", "$signapkJniLibrary"},
},
"certificates")
@@ -48,6 +49,9 @@
pctx.SourcePathVariable("androidManifestMergerCmd", "prebuilts/devtools/tools/lib/manifest-merger.jar")
pctx.HostBinToolVariable("aaptCmd", "aapt")
pctx.HostJavaToolVariable("signapkCmd", "signapk.jar")
+ // TODO(ccross): this should come from the signapk dependencies, but we don't have any way
+ // to express host JNI dependencies yet.
+ pctx.HostJNIToolVariable("signapkJniLibrary", "libconscrypt_openjdk_jni")
}
var combineApk = pctx.AndroidStaticRule("combineApk",
@@ -79,6 +83,9 @@
certificateArgs = append(certificateArgs, c+".x509.pem", c+".pk8")
}
+ // TODO(ccross): sometimes uncompress dex
+ // TODO(ccross): sometimes strip dex
+
ctx.Build(pctx, android.BuildParams{
Rule: signapk,
Description: "signapk",
diff --git a/java/app_test.go b/java/app_test.go
index 0b1491e..8e50b9f 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -35,17 +35,7 @@
)
func testApp(t *testing.T, bp string) *android.TestContext {
- bp += `
- android_app {
- name: "framework-res",
- no_framework_libs: true,
- }
- `
-
- appFs := map[string][]byte{
- "AndroidManifest.xml": nil,
- "build/target/product/security/testkey": nil,
- }
+ appFs := map[string][]byte{}
for _, file := range resourceFiles {
appFs[file] = nil
diff --git a/java/java.go b/java/java.go
index 82ff827..f875c79 100644
--- a/java/java.go
+++ b/java/java.go
@@ -41,7 +41,6 @@
android.RegisterModuleType("java_binary_host", BinaryHostFactory)
android.RegisterModuleType("java_import", ImportFactory)
android.RegisterModuleType("java_import_host", ImportFactoryHost)
- android.RegisterModuleType("android_app", AndroidAppFactory)
android.RegisterSingletonType("logtags", LogtagsSingleton)
}
@@ -206,6 +205,10 @@
// installed file for binary dependency
installFile android.Path
+
+ // list of .java files and srcjars that was passed to javac
+ compiledJavaSrcs android.Paths
+ compiledSrcJars android.Paths
}
type Dependency interface {
@@ -349,6 +352,9 @@
} else if *j.deviceProperties.System_modules != "none" && ctx.Config().TargetOpenJDK9() {
ctx.AddDependency(ctx.Module(), systemModulesTag, *j.deviceProperties.System_modules)
}
+ if ctx.ModuleName() == "framework" {
+ ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res")
+ }
}
ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
@@ -612,6 +618,10 @@
}
}
+ // Store the list of .java files that was passed to javac
+ j.compiledJavaSrcs = uniqueSrcFiles
+ j.compiledSrcJars = srcJars
+
enable_sharding := false
if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") {
if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
diff --git a/java/java_test.go b/java/java_test.go
index cf5047b..0a9eba9 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -97,6 +97,13 @@
`, extra)
}
+ bp += `
+ android_app {
+ name: "framework-res",
+ no_framework_libs: true,
+ }
+ `
+
if config.TargetOpenJDK9() {
systemModules := []string{
"core-system-modules",
@@ -134,6 +141,10 @@
"prebuilts/sdk/system_current/framework.aidl": nil,
"prebuilts/sdk/test_current/android.jar": nil,
"prebuilts/sdk/test_current/framework.aidl": nil,
+
+ // For framework-res, which is an implicit dependency for framework
+ "AndroidManifest.xml": nil,
+ "build/target/product/security/testkey": nil,
}
for k, v := range fs {