blob: 72170fc6d315fb9ced4047dc0a91c286522ac8cf [file] [log] [blame]
// Copyright 2020 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package java
// This file contains the module implementations for runtime_resource_overlay and
// override_runtime_resource_overlay.
import "android/soong/android"
func init() {
RegisterRuntimeResourceOverlayBuildComponents(android.InitRegistrationContext)
}
func RegisterRuntimeResourceOverlayBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory)
ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory)
}
type RuntimeResourceOverlay struct {
android.ModuleBase
android.DefaultableModuleBase
android.OverridableModuleBase
aapt
properties RuntimeResourceOverlayProperties
overridableProperties OverridableRuntimeResourceOverlayProperties
certificate Certificate
outputFile android.Path
installDir android.InstallPath
}
type RuntimeResourceOverlayProperties struct {
// the name of a certificate in the default certificate directory or an android_app_certificate
// module name in the form ":module".
Certificate *string
// Name of the signing certificate lineage file.
Lineage *string
// For overriding the --rotation-min-sdk-version property of apksig
RotationMinSdkVersion *string
// optional theme name. If specified, the overlay package will be applied
// only when the ro.boot.vendor.overlay.theme system property is set to the same value.
Theme *string
// If not blank, set to the version of the sdk to compile against. This
// can be either an API version (e.g. "29" for API level 29 AKA Android 10)
// or special subsets of the current platform, for example "none", "current",
// "core", "system", "test". See build/soong/java/sdk.go for the full and
// up-to-date list of possible values.
// Defaults to compiling against the current platform.
Sdk_version *string
// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
// Defaults to sdk_version if not set.
Min_sdk_version *string
// list of android_library modules whose resources are extracted and linked against statically
Static_libs []string
// list of android_app modules whose resources are extracted and linked against
Resource_libs []string
// Names of modules to be overridden. Listed modules can only be other overlays
// (in Make or Soong).
// This does not completely prevent installation of the overridden overlays, but if both
// overlays would be installed by default (in PRODUCT_PACKAGES) the other overlay will be removed
// from PRODUCT_PACKAGES.
Overrides []string
}
// RuntimeResourceOverlayModule interface is used by the apex package to gather information from
// a RuntimeResourceOverlay module.
type RuntimeResourceOverlayModule interface {
android.Module
OutputFile() android.Path
Certificate() Certificate
Theme() string
}
// RRO's partition logic is different from the partition logic of other modules defined in soong/android/paths.go
// The default partition for RRO is "/product" and not "/system"
func rroPartition(ctx android.ModuleContext) string {
var partition string
if ctx.DeviceSpecific() {
partition = ctx.DeviceConfig().OdmPath()
} else if ctx.SocSpecific() {
partition = ctx.DeviceConfig().VendorPath()
} else if ctx.SystemExtSpecific() {
partition = ctx.DeviceConfig().SystemExtPath()
} else {
partition = ctx.DeviceConfig().ProductPath()
}
return partition
}
func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
sdkDep := decodeSdkDep(ctx, android.SdkContext(r))
if sdkDep.hasFrameworkLibs() {
r.aapt.deps(ctx, sdkDep)
}
cert := android.SrcIsModule(String(r.properties.Certificate))
if cert != "" {
ctx.AddDependency(ctx.Module(), certificateTag, cert)
}
ctx.AddVariationDependencies(nil, staticLibTag, r.properties.Static_libs...)
ctx.AddVariationDependencies(nil, libTag, r.properties.Resource_libs...)
for _, aconfig_declaration := range r.aaptProperties.Flags_packages {
ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
}
}
func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Compile and link resources
r.aapt.hasNoCode = true
// Do not remove resources without default values nor dedupe resource configurations with the same value
aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"}
// Allow the override of "package name" and "overlay target package name"
manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
if overridden || r.overridableProperties.Package_name != nil {
// The product override variable has a priority over the package_name property.
if !overridden {
manifestPackageName = *r.overridableProperties.Package_name
}
aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, false)...)
}
if r.overridableProperties.Target_package_name != nil {
aaptLinkFlags = append(aaptLinkFlags,
"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
}
if r.overridableProperties.Category != nil {
aaptLinkFlags = append(aaptLinkFlags,
"--rename-overlay-category "+*r.overridableProperties.Category)
}
r.aapt.buildActions(ctx,
aaptBuildActionOptions{
sdkContext: r,
enforceDefaultTargetSdkVersion: false,
extraLinkFlags: aaptLinkFlags,
aconfigTextFiles: getAconfigFilePaths(ctx),
},
)
// Sign the built package
_, _, certificates := collectAppDeps(ctx, r, false, false)
r.certificate, certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
var lineageFile android.Path
if lineage := String(r.properties.Lineage); lineage != "" {
lineageFile = android.PathForModuleSrc(ctx, lineage)
}
rotationMinSdkVersion := String(r.properties.RotationMinSdkVersion)
SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, lineageFile, rotationMinSdkVersion)
r.outputFile = signed
partition := rroPartition(ctx)
r.installDir = android.PathForModuleInPartitionInstall(ctx, partition, "overlay", String(r.properties.Theme))
ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
}
func (r *RuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
return android.SdkSpecFrom(ctx, String(r.properties.Sdk_version))
}
func (r *RuntimeResourceOverlay) SystemModules() string {
return ""
}
func (r *RuntimeResourceOverlay) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
if r.properties.Min_sdk_version != nil {
return android.ApiLevelFrom(ctx, *r.properties.Min_sdk_version)
}
return r.SdkVersion(ctx).ApiLevel
}
func (r *RuntimeResourceOverlay) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
return android.SdkSpecPrivate.ApiLevel
}
func (r *RuntimeResourceOverlay) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
return r.SdkVersion(ctx).ApiLevel
}
func (r *RuntimeResourceOverlay) Certificate() Certificate {
return r.certificate
}
func (r *RuntimeResourceOverlay) OutputFile() android.Path {
return r.outputFile
}
func (r *RuntimeResourceOverlay) Theme() string {
return String(r.properties.Theme)
}
// runtime_resource_overlay generates a resource-only apk file that can overlay application and
// system resources at run time.
func RuntimeResourceOverlayFactory() android.Module {
module := &RuntimeResourceOverlay{}
module.AddProperties(
&module.properties,
&module.aaptProperties,
&module.overridableProperties)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitOverridableModule(module, &module.properties.Overrides)
return module
}
// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay
type OverridableRuntimeResourceOverlayProperties struct {
// the package name of this app. The package name in the manifest file is used if one was not given.
Package_name *string
// the target package name of this overlay app. The target package name in the manifest file is used if one was not given.
Target_package_name *string
// the rro category of this overlay. The category in the manifest file is used if one was not given.
Category *string
}
type OverrideRuntimeResourceOverlay struct {
android.ModuleBase
android.OverrideModuleBase
}
func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(_ android.ModuleContext) {
// All the overrides happen in the base module.
// TODO(jungjw): Check the base module type.
}
// override_runtime_resource_overlay is used to create a module based on another
// runtime_resource_overlay module by overriding some of its properties.
func OverrideRuntimeResourceOverlayModuleFactory() android.Module {
m := &OverrideRuntimeResourceOverlay{}
m.AddProperties(&OverridableRuntimeResourceOverlayProperties{})
android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
android.InitOverrideModule(m)
return m
}