summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/app.go147
-rw-r--r--java/app_test.go2
-rw-r--r--java/config/config.go2
-rw-r--r--java/sdk_library.go12
4 files changed, 85 insertions, 78 deletions
diff --git a/java/app.go b/java/app.go
index e12b56c58..344265851 100644
--- a/java/app.go
+++ b/java/app.go
@@ -30,8 +30,7 @@ import (
"android/soong/tradefed"
)
-var supportedDpis = [...]string{"Ldpi", "Mdpi", "Hdpi", "Xhdpi", "Xxhdpi", "Xxxhdpi"}
-var dpiVariantsStruct reflect.Type
+var supportedDpis = []string{"ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"}
func init() {
android.RegisterModuleType("android_app", AndroidAppFactory)
@@ -40,22 +39,6 @@ func init() {
android.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
android.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
android.RegisterModuleType("android_app_import", AndroidAppImportFactory)
-
- // Dynamically construct a struct for the dpi_variants property in android_app_import.
- perDpiStruct := reflect.StructOf([]reflect.StructField{
- {
- Name: "Apk",
- Type: reflect.TypeOf((*string)(nil)),
- },
- })
- dpiVariantsFields := make([]reflect.StructField, len(supportedDpis))
- for i, dpi := range supportedDpis {
- dpiVariantsFields[i] = reflect.StructField{
- Name: string(dpi),
- Type: perDpiStruct,
- }
- }
- dpiVariantsStruct = reflect.StructOf(dpiVariantsFields)
}
// AndroidManifest.xml merging
@@ -744,7 +727,8 @@ type AndroidAppImport struct {
android.DefaultableModuleBase
prebuilt android.Prebuilt
- properties AndroidAppImportProperties
+ properties AndroidAppImportProperties
+ dpiVariants interface{}
outputFile android.Path
certificate *Certificate
@@ -756,27 +740,7 @@ type AndroidAppImport struct {
type AndroidAppImportProperties struct {
// A prebuilt apk to import
- Apk string
-
- // Per-DPI settings. This property makes it possible to specify a different source apk path for
- // each DPI.
- //
- // Example:
- //
- // android_app_import {
- // name: "example_import",
- // apk: "prebuilts/example.apk",
- // dpi_variants: {
- // mdpi: {
- // apk: "prebuilts/example_mdpi.apk",
- // },
- // xhdpi: {
- // apk: "prebuilts/example_xhdpi.apk",
- // },
- // },
- // certificate: "PRESIGNED",
- // }
- Dpi_variants interface{}
+ Apk *string
// The name of a certificate in the default certificate directory, blank to use the default
// product certificate, or an android_app_certificate module name in the form ":module".
@@ -799,39 +763,43 @@ type AndroidAppImportProperties struct {
Overrides []string
}
-func getApkPathForDpi(dpiVariantsValue reflect.Value, dpi string) string {
- dpiField := dpiVariantsValue.FieldByName(proptools.FieldNameForProperty(dpi))
- if !dpiField.IsValid() {
- return ""
- }
- apkValue := dpiField.FieldByName("Apk").Elem()
- if apkValue.IsValid() {
- return apkValue.String()
- }
- return ""
-}
-
-// Chooses a source APK path to use based on the module's per-DPI settings and the product config.
-func (a *AndroidAppImport) getSrcApkPath(ctx android.ModuleContext) string {
+// Chooses a source APK path to use based on the module and product specs.
+func (a *AndroidAppImport) updateSrcApkPath(ctx android.LoadHookContext) {
config := ctx.Config()
- dpiVariantsValue := reflect.ValueOf(a.properties.Dpi_variants).Elem()
- if !dpiVariantsValue.IsValid() {
- return a.properties.Apk
+
+ dpiProps := reflect.ValueOf(a.dpiVariants).Elem().FieldByName("Dpi_variants")
+ // Try DPI variant matches in the reverse-priority order so that the highest priority match
+ // overwrites everything else.
+ // TODO(jungjw): Can we optimize this by making it priority order?
+ for i := len(config.ProductAAPTPrebuiltDPI()) - 1; i >= 0; i-- {
+ dpi := config.ProductAAPTPrebuiltDPI()[i]
+ if inList(dpi, supportedDpis) {
+ MergePropertiesFromVariant(ctx, &a.properties, dpiProps, dpi, "dpi_variants")
+ }
}
- // Match PRODUCT_AAPT_PREF_CONFIG first and then PRODUCT_AAPT_PREBUILT_DPI.
if config.ProductAAPTPreferredConfig() != "" {
- if apk := getApkPathForDpi(dpiVariantsValue, config.ProductAAPTPreferredConfig()); apk != "" {
- return apk
+ dpi := config.ProductAAPTPreferredConfig()
+ if inList(dpi, supportedDpis) {
+ MergePropertiesFromVariant(ctx, &a.properties, dpiProps, dpi, "dpi_variants")
}
}
- for _, dpi := range config.ProductAAPTPrebuiltDPI() {
- if apk := getApkPathForDpi(dpiVariantsValue, dpi); apk != "" {
- return apk
- }
+}
+
+func MergePropertiesFromVariant(ctx android.BaseModuleContext,
+ dst interface{}, variantGroup reflect.Value, variant, variantGroupPath string) {
+ src := variantGroup.FieldByName(proptools.FieldNameForProperty(variant))
+ if !src.IsValid() {
+ ctx.ModuleErrorf("field %q does not exist", variantGroupPath+"."+variant)
}
- // No match. Use the generic one.
- return a.properties.Apk
+ err := proptools.ExtendMatchingProperties([]interface{}{dst}, src.Interface(), nil, proptools.OrderAppend)
+ if err != nil {
+ if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
+ ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
+ } else {
+ panic(err)
+ }
+ }
}
func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -896,8 +864,7 @@ func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext
// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
// TODO: LOCAL_PACKAGE_SPLITS
- var srcApk android.Path
- srcApk = android.PathForModuleSrc(ctx, a.getSrcApkPath(ctx))
+ srcApk := a.prebuilt.SingleSourcePath(ctx)
if a.usesLibrary.enforceUsesLibraries() {
srcApk = a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
@@ -959,16 +926,56 @@ func (a *AndroidAppImport) Name() string {
return a.prebuilt.Name(a.ModuleBase.Name())
}
+// Populates dpi_variants property and its fields at creation time.
+func (a *AndroidAppImport) addDpiVariants() {
+ // TODO(jungjw): Do we want to do some filtering here?
+ props := reflect.ValueOf(&a.properties).Type()
+
+ dpiFields := make([]reflect.StructField, len(supportedDpis))
+ for i, dpi := range supportedDpis {
+ dpiFields[i] = reflect.StructField{
+ Name: proptools.FieldNameForProperty(dpi),
+ Type: props,
+ }
+ }
+ dpiStruct := reflect.StructOf(dpiFields)
+ a.dpiVariants = reflect.New(reflect.StructOf([]reflect.StructField{
+ {
+ Name: "Dpi_variants",
+ Type: dpiStruct,
+ },
+ })).Interface()
+ a.AddProperties(a.dpiVariants)
+}
+
// android_app_import imports a prebuilt apk with additional processing specified in the module.
+// DPI-specific apk source files can be specified using dpi_variants. Example:
+//
+// android_app_import {
+// name: "example_import",
+// apk: "prebuilts/example.apk",
+// dpi_variants: {
+// mdpi: {
+// apk: "prebuilts/example_mdpi.apk",
+// },
+// xhdpi: {
+// apk: "prebuilts/example_xhdpi.apk",
+// },
+// },
+// certificate: "PRESIGNED",
+// }
func AndroidAppImportFactory() android.Module {
module := &AndroidAppImport{}
- module.properties.Dpi_variants = reflect.New(dpiVariantsStruct).Interface()
module.AddProperties(&module.properties)
module.AddProperties(&module.dexpreoptProperties)
module.AddProperties(&module.usesLibrary.usesLibraryProperties)
+ module.addDpiVariants()
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ module.updateSrcApkPath(ctx)
+ })
InitJavaModule(module, android.DeviceSupported)
- android.InitSingleSourcePrebuiltModule(module, &module.properties.Apk)
+ android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
return module
}
diff --git a/java/app_test.go b/java/app_test.go
index 721dd4dc2..f08969d2e 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1138,7 +1138,7 @@ func TestAndroidAppImport_DpiVariants(t *testing.T) {
{
name: "AAPTPreferredConfig matches",
aaptPreferredConfig: proptools.StringPtr("xhdpi"),
- aaptPrebuiltDPI: []string{"xxhdpi", "lhdpi"},
+ aaptPrebuiltDPI: []string{"xxhdpi", "ldpi"},
expected: "prebuilts/apk/app_xhdpi.apk",
},
{
diff --git a/java/config/config.go b/java/config/config.go
index 6ade6493f..d017ae67f 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -52,7 +52,7 @@ func init() {
pctx.StaticVariable("JavacHeapSize", "2048M")
pctx.StaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
- pctx.StaticVariable("DexFlags", "-JXX:+TieredCompilation -JXX:TieredStopAtLevel=1")
+ pctx.StaticVariable("DexFlags", "-JXX:OnError='cat hs_err_pid%p.log' -JXX:CICompilerCount=6 -JXX:+UseDynamicNumberOfGCThreads")
pctx.StaticVariable("CommonJdkFlags", strings.Join([]string{
`-Xmaxerrs 9999999`,
diff --git a/java/sdk_library.go b/java/sdk_library.go
index b4a3f296c..1182b966f 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -63,12 +63,6 @@ var (
javaSdkLibrariesLock sync.Mutex
)
-// java_sdk_library is to make a Java library that implements optional platform APIs to apps.
-// It is actually a wrapper of several modules: 1) stubs library that clients are linked against
-// to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
-// shared library that implements the APIs, and 4) XML file for adding the runtime lib to the
-// classpath at runtime if requested via <uses-library>.
-//
// TODO: these are big features that are currently missing
// 1) disallowing linking to the runtime shared lib
// 2) HTML generation
@@ -746,6 +740,11 @@ func (module *SdkLibrary) InitSdkLibraryProperties() {
module.Library.Module.deviceProperties.IsSDKLibrary = true
}
+// java_sdk_library is a special Java library that provides optional platform APIs to apps.
+// In practice, it can be viewed as a combination of several modules: 1) stubs library that clients
+// are linked against to, 2) droiddoc module that internally generates API stubs source files,
+// 3) the real runtime shared library that implements the APIs, and 4) XML file for adding
+// the runtime lib to the classpath at runtime if requested via <uses-library>.
func SdkLibraryFactory() android.Module {
module := &SdkLibrary{}
module.InitSdkLibraryProperties()
@@ -787,6 +786,7 @@ type sdkLibraryImport struct {
var _ SdkLibraryDependency = (*sdkLibraryImport)(nil)
+// java_sdk_library_import imports a prebuilt java_sdk_library.
func sdkLibraryImportFactory() android.Module {
module := &sdkLibraryImport{}