Implement DPI variants in android_app_import.
Bug: 128610294
Test: app_test.go
Change-Id: Ie3e558bfdb40de6b0b9df95d3b373d08a4084d7b
diff --git a/java/app.go b/java/app.go
index ec021fc..849af5b 100644
--- a/java/app.go
+++ b/java/app.go
@@ -17,17 +17,20 @@
// This file contains the module types for compiling Android apps.
import (
- "path/filepath"
- "strings"
-
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
+ "path/filepath"
+ "reflect"
+ "strings"
"android/soong/android"
"android/soong/cc"
"android/soong/tradefed"
)
+var supportedDpis = [...]string{"Ldpi", "Mdpi", "Hdpi", "Xhdpi", "Xxhdpi", "Xxxhdpi"}
+var dpiVariantsStruct reflect.Type
+
func init() {
android.RegisterModuleType("android_app", AndroidAppFactory)
android.RegisterModuleType("android_test", AndroidTestFactory)
@@ -35,6 +38,22 @@
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
@@ -635,6 +654,26 @@
// 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{}
+
// 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".
Certificate *string
@@ -656,6 +695,41 @@
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 {
+ config := ctx.Config()
+ dpiVariantsValue := reflect.ValueOf(a.properties.Dpi_variants).Elem()
+ if !dpiVariantsValue.IsValid() {
+ return a.properties.Apk
+ }
+ // Match PRODUCT_AAPT_PREF_CONFIG first and then PRODUCT_AAPT_PREBUILT_DPI.
+ if config.ProductAAPTPreferredConfig() != "" {
+ if apk := getApkPathForDpi(dpiVariantsValue, config.ProductAAPTPreferredConfig()); apk != "" {
+ return apk
+ }
+ }
+ for _, dpi := range config.ProductAAPTPrebuiltDPI() {
+ if apk := getApkPathForDpi(dpiVariantsValue, dpi); apk != "" {
+ return apk
+ }
+ }
+
+ // No match. Use the generic one.
+ return a.properties.Apk
+}
+
func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
cert := android.SrcIsModule(String(a.properties.Certificate))
if cert != "" {
@@ -701,10 +775,9 @@
_, certificates := collectAppDeps(ctx)
// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
- // TODO: LOCAL_DPI_VARIANTS
// TODO: LOCAL_PACKAGE_SPLITS
- srcApk := a.prebuilt.SingleSourcePath(ctx)
+ srcApk := android.PathForModuleSrc(ctx, a.getSrcApkPath(ctx))
// TODO: Install or embed JNI libraries
@@ -754,6 +827,7 @@
// android_app_import imports a prebuilt apk with additional processing specified in the module.
func AndroidAppImportFactory() android.Module {
module := &AndroidAppImport{}
+ module.properties.Dpi_variants = reflect.New(dpiVariantsStruct).Interface()
module.AddProperties(&module.properties)
module.AddProperties(&module.dexpreoptProperties)