diff options
Diffstat (limited to 'java/app.go')
| -rw-r--r-- | java/app.go | 165 |
1 files changed, 88 insertions, 77 deletions
diff --git a/java/app.go b/java/app.go index e12b56c58..674e5ece0 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 @@ -208,9 +191,12 @@ func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato } } +func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { + a.generateAndroidBuildActions(ctx) +} + func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { - a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) - a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) + a.checkPlatformAPI(ctx) a.generateAndroidBuildActions(ctx) } @@ -439,6 +425,9 @@ func processMainCert(m android.ModuleBase, certPropValue string, certificates [] func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { var apkDeps android.Paths + a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) + a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) + // Check if the install APK name needs to be overridden. a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Name()) @@ -601,8 +590,6 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName) } } - a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) - a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) a.generateAndroidBuildActions(ctx) a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites) @@ -744,7 +731,8 @@ type AndroidAppImport struct { android.DefaultableModuleBase prebuilt android.Prebuilt - properties AndroidAppImportProperties + properties AndroidAppImportProperties + dpiVariants interface{} outputFile android.Path certificate *Certificate @@ -756,27 +744,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 +767,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) { @@ -848,7 +820,7 @@ func (a *AndroidAppImport) uncompressEmbeddedJniLibs( rule := android.NewRuleBuilder() rule.Command(). Textf(`if (zipinfo %s 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath). - Tool(ctx.Config().HostToolPath(ctx, "zip2zip")). + BuiltTool(ctx, "zip2zip"). FlagWithInput("-i ", inputPath). FlagWithOutput("-o ", outputPath). FlagWithArg("-0 ", "'lib/**/*.so'"). @@ -875,7 +847,7 @@ func (a *AndroidAppImport) uncompressDex( rule := android.NewRuleBuilder() rule.Command(). Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath). - Tool(ctx.Config().HostToolPath(ctx, "zip2zip")). + BuiltTool(ctx, "zip2zip"). FlagWithInput("-i ", inputPath). FlagWithOutput("-o ", outputPath). FlagWithArg("-0 ", "'classes*.dex'"). @@ -896,8 +868,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 +930,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 } @@ -1060,7 +1071,7 @@ func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, man outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml") rule := android.NewRuleBuilder() - cmd := rule.Command().Tool(ctx.Config().HostToolPath(ctx, "manifest_check")). + cmd := rule.Command().BuiltTool(ctx, "manifest_check"). Flag("--enforce-uses-libraries"). Input(manifest). FlagWithOutput("-o ", outputFile) |
